PIC 18f and timer0 problems - Page 1
Forum section: electronics / general

author: VogonJelc
author_rank: Newbie
timestamp: November 15, 2018, 10:45:03 pm
content: Hello friends,Few years ago when I thought I had time for MCU I bought PIC18f1320 and kind off forgot about it. Now after stumbling on to EEVBlog chanel I decided to give it a try.After poking around with setting port pins I came to idea to control RGB led brightness and color using PWM. SInce 18f1320 has only one PWM output and I need 3 of them I decided to use a interrupt on timer0 to try to control diodes.SInce I never used timer0 interrupts I decided to make a simple test which is going to turn off and on diode on PORTA RA0 (pin1, 18 pin PDIP package) on my MCU.Its a simple setup just a diode from pin 1 to R and then to GND. Internal oscillator set to 8MHzSo I made a code (MPLAB IDE, XC8) that goes something like thisCode:/** File: TImer0.c* Author: Asus** Created on 13.11.2018., 00.09*/// PIC18F1320 Configuration Bit Settings// 'C' source line config statements// CONFIG1H#pragma config OSC = INTIO2 // Oscillator Selection bits (Internal RC oscillator, port function on RA6 and port function on RA7)#pragma config FSCM = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)#pragma config IESO = ON // Internal External Switchover bit (Internal External Switchover mode enabled)// CONFIG2L#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)#pragma config BOR = ON // Brown-out Reset Enable bit (Brown-out Reset enabled)// BORV = No Setting// CONFIG2H#pragma config WDT = ON // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)// CONFIG3H#pragma config MCLRE = OFF // MCLR Pin Enable bit (RA5 input pin enabled, MCLR disabled)// CONFIG4L#pragma config STVR = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)#pragma config LVP = ON // Low-Voltage ICSP Enable bit (Low-Voltage ICSP enabled)// CONFIG5L#pragma config CP0 = OFF // Code Protection bit (Block 0 (00200-000FFFh) not code-protected)#pragma config CP1 = OFF // Code Protection bit (Block 1 (001000-001FFFh) not code-protected)// CONFIG5H#pragma config CPB = OFF // Boot Block Code Protection bit (Boot Block (000000-0001FFh) not code-protected)#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)// CONFIG6L#pragma config WRT0 = OFF // Write Protection bit (Block 0 (00200-000FFFh) not write-protected)#pragma config WRT1 = OFF // Write Protection bit (Block 1 (001000-001FFFh) not write-protected)// CONFIG6H#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0001FFh) not write-protected)#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)// CONFIG7L#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (00200-000FFFh) not protected from table reads executed in other blocks)#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (001000-001FFFh) not protected from table reads executed in other blocks)// CONFIG7H#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0001FFh) not protected from table reads executed in other blocks)// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#define _XTAL_FREQ 8000000#include <xc.h>//#include <timers.h>void init_timer0(void);void main(void) {OSCCONbits.IRCF = 0b111; //Set int clock to 8MHz)ADCON1bits.PCFG = 0b1111111; //SET PORTA to digital i/o//Set PORTA to outputTRISA=0;PORTA=0;//LATA=0;LATAbits.LA0=1; //turn the diode oninit_timer0(); //init timer0 for 1s delaywhile (1){//Do nothing//for a long time};return;}void init_timer0(){//Setting up the timer to 1s according to http://www.enmcu.com/software/timer0calculatorandcodegenerationT0CONbits.T08BIT = 0; //16bitT0CONbits.T0CS = 0; //internal clockT0CONbits.PSA = 0; //Prescaler onT0CONbits.T0PS2 = 1; //1:32T0CONbits.T0PS1 = 0;T0CONbits.T0PS0 =0 ;TMR0H = 0x0B; //set timer initial value to 3036 loading Low and High register with hex valuesTMR0L = 0xDC;//enabling the INteruptIPEN=0;INTCONbits.PEIE=1; //Peripheral int onINTCONbits.TMR0IF=0; //timer0 flag clearT0CONbits.TMR0ON = 1; //turn on the timerINTCONbits.TMR0IE=1; //enable Timer0 InteruptsINTCONbits.GIE=1; //enable global interupts}void __interrupt() timer0(void){//Toggle diode on RA0if (INTCONbits.TMR0IF && INTCONbits.TMR0IE) //check if it timer0 overflow not needed but ...{TMR0H = 0x0B; //reload timer0 value to 3036 loading Low and High register with hex valuesTMR0L = 0xDC;if (LATAbits.LA0==1)LATAbits.LA0=0;else LATAbits.LA0=1; //Toggle the diodeINTCONbits.TMR0IF=0; //clear Timer0 interupt Flag} ;}Debugger is working fine. But breadboard is whole different story.The led is on always. It's not as bright as when connected straight to 5v and multimeter shows 1.3 volts. But It should go on and off every 1 second. So can any one check where I made mistake? I can't find it.

author: cv007
author_rank: Frequent Contributor
timestamp: November 15, 2018, 11:31:43 pm
content: #pragma config WDT = ON // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))looks like that line was manually changed- formatting does not line up and comment doesn't match the setting (the comment is for the OFF setting)if the watchdog is set to ON in the config bits, you then have to take care of the watchdog or else it will reset when it times out, which is most likely what you are seeing (it runs long enough to get the led on, then resets because of the watchdog timeout- a crude form of pwm to be sure)

author: VogonJelc
author_rank: Newbie
timestamp: November 15, 2018, 11:43:26 pm
content: Hm yes I did change it. From OFF to ON thinking that will solve the problem. It didn't.It didn't. I'm thinking I'll have to change breadboard and hook this thing onto oscilloscope. Think one of my friends has working digital one. If that fails I'll have to use TLC5947 little bit of overkill for my needs.

author: Wilksey
author_rank: Super Contributor
timestamp: November 16, 2018, 12:48:47 am
content: You could set up a simple test with a scope or logic analyser and toggle a pin when the timer overflows to check it is actually doing something.Change interrupt to do:Code:LATAbits.LA0 = !LATAbits.LA0;Few obs:change #pragma config WDT = ON to #pragma config WDT = OFFremove "return" from main, never reached.Possibly change #pragma config STVR = ON to #pragma config STVR = OFF, not clearing STKPTR flags or checking them.Change the code to:Code:void int_timer0(){RCONbits.IPEN = 0;T0CON = 0x84;TMR0H = 0x0B;TMR0L = 0xDC;INTCON = 0E0;}void __interrupt() interrupt(void){if(INTCONbits.TMR0IF){INTCONbits.TMR0IF = 0;TMR0H = 0x0B;TMR0L = 0xDC;if(LATAbits.LA0 == 1){LATAbits.LA0 = 0;}else{LATAbits.LA0 = 1;}}}I'd also add this to main function for clarityCode:ADCON0 = 0;ADCON1 = 0x01;Can't see anything else obvious.

author: VogonJelc
author_rank: Newbie
timestamp: November 16, 2018, 01:11:50 am
content: return was added by MPLAB IDE. T0CON = 0x84; comes to 10000100 which is set bit TMR0ON and prescaler to 32. I will try it. I avoid writing hex stuff and prefer either setting bits or using binary numbers, helps avoid "why did I do it moments". I'll edit interrupt routine maybe it's not passing check on hardware.Already changed Watchdog timer. Either way it works when debugging code. Pin 1 or RA0 changes state just fine. It's the hardware that makes the problem.Gonna change breadboard tomorrow after work. Maybe breadboard is making problems.

author: VogonJelc
author_rank: Newbie
timestamp: November 16, 2018, 12:24:12 pm
content: ChangedLATAbits.LA0=1; //turn the diode ontoLATAbits.LA0=0;And diode stays off. So interrupt is not working. 1.3 v readings must be from bad breadboard.Tried on 2nd pic 18f1320 and same result. Didn't try to change code as suggested as it was 4am and it was time to sleep.Don't think writing hex values is gonna change much but will give it a try. If it still fails on new breadboard with code changes, my pic flash 2 is making problems (not likely), my code is bad (not likely since I seen it get used a lot in examples and it works when debugging in IDE) or timer0 is behaving badly.Maybe try with IPEN=1;setting timer0 int priority to high then making HIGH_priority ISR.If that fails maybe making while(1) loop which is going to either check manually timer0 interrupt flag (with gei and timer0 interupt enabled set to 0) or checking whether TMR0 is lower than 65535. I read that XC8 treats TMR0 as 16 bit variable.

author: MarkF
author_rank: Super Contributor
timestamp: November 16, 2018, 04:18:33 pm
content: It looks like you're trying to generate a 4 Hz interrupt? That may be a little fast to verify that the LED is turning on and off. It would just look dim (as you mentioned). Try something slower.I put together some code with a 2 Hz interrupt. You might want to change the prescaler to 1:256 at first.Corrected:Corrected timer prescaler. The timer is clocked by the instruction cycle clock [i.e. System clock divided by 4 (Fosc/4) in this case]Code:// PIC18F1320 Configuration Bit Settings// 'C' source line config statements// CONFIG1H#pragma config OSC = INTIO1 // Oscillator Selection bits (Internal RC oscillator, CLKO function on RA6 and port function on RA7)#pragma config FSCM = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)#pragma config IESO = ON // Internal External Switchover bit (Internal External Switchover mode enabled)// CONFIG2L#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)#pragma config BOR = OFF // Brown-out Reset Enable bit (Brown-out Reset disabled)// BORV = No Setting// CONFIG2H#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)// CONFIG3H#pragma config MCLRE = OFF // MCLR Pin Enable bit (RA5 input pin enabled, MCLR disabled)// CONFIG4L#pragma config STVR = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)#pragma config LVP = OFF // Low-Voltage ICSP Enable bit (Low-Voltage ICSP disabled)// CONFIG5L#pragma config CP0 = OFF // Code Protection bit (Block 0 (00200-000FFFh) not code-protected)#pragma config CP1 = OFF // Code Protection bit (Block 1 (001000-001FFFh) not code-protected)// CONFIG5H#pragma config CPB = OFF // Boot Block Code Protection bit (Boot Block (000000-0001FFh) not code-protected)#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)// CONFIG6L#pragma config WRT0 = OFF // Write Protection bit (Block 0 (00200-000FFFh) not write-protected)#pragma config WRT1 = OFF // Write Protection bit (Block 1 (001000-001FFFh) not write-protected)// CONFIG6H#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0001FFh) not write-protected)#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)// CONFIG7L#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (00200-000FFFh) not protected from table reads executed in other blocks)#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (001000-001FFFh) not protected from table reads executed in other blocks)// CONFIG7H#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0001FFh) not protected from table reads executed in other blocks)// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#include <xc.h>#include <stdint.h>// Hardware pin assignments#define LEDpin LATAbits.LA0// Globalsuint8_t LEDstate=0;void main(void){OSCCON=0x72; // Select internal oscillator:// IDLEN = Run Mode// IRCF = 8 MHz// SCS = Internal oscillator blockADCON0=0; // A/D converter offADCON1=0x7f; // All digital inputsTRISA=0b11111110; // Set Port A direction bitsLATA=0xff;// Timer 0 SetupT0CONbits.T08BIT=0; // 16-bitT0CONbits.T0CS=0; // Fosc/4T0CONbits.PSA=0; // Prescaler OnT0CONbits.T0PS=4; // 1:32TMR0H=0x0b; // 1 Hz interrupt (62500 count)TMR0L=0xdc;// Enable Timer0 and interruptsT0CONbits.TMR0ON=1;RCONbits.IPEN=0;INTCONbits.TMR0IF=0;INTCONbits.TMR0IE=1;INTCONbits.GIE=1;// Main Loopwhile (1) {}}void __interrupt() isr(void){if (INTCONbits.TMR0IE && INTCONbits.TMR0IF) {INTCONbits.TMR0IF = 0; // Reset Timer0 Interrupt FlagTMR0H=0x0b; // Reload Timer0TMR0L=0xdc;LEDpin = LEDstate; // Set LED pinif (LEDstate++ > 1) LEDstate = 0; // Toggle LED state}}

author: VogonJelc
author_rank: Newbie
timestamp: November 16, 2018, 06:32:38 pm
content: I think its 1 sec on/off verified results using mikroelektronika timer calculator andhttp://www.enmcu.com/software/timer0calculatorandcodegenerationcalculator.The problem is not the code. Code is fine. ANd it's not breadboard either. So after a lot of changing code and flashing mcu braking one in process (he will be fine he doesn't need those pins to work) i took my trusted multimeter to check whether my power supply is ok or not. I use one of those boards that has dc in and 5v and 3.3v regulators and pins that fit straight into breadboard power rails. I first started to measure power supply. Not wanting to touch pin 5 on MCU with my multimeter i connected it to ground where my diode current limiting resistor was connected to ground and it started blinking one second period. Which was strange since I took everything trying my 2 different breadboards. And it gets even crazier. I turned it off and on. Tried same stuff but no luck. Then I went to check voltages on power board and as soon as I measured 3.3 v rail (which is not in use) well led started to blink. Turn everything off changed prescaler so if it starts blinking faster so I can verify that its realy PIC doing its thing. And bam same stuff led blinking a lot faster. PIc is working but no all the time.I'm pretty certain power board is ok. All voltages are there. And my other things work fine on it, RGB diode works fine when control thru loop. I tested some mosfets I got from old and dead Computer MBO (excellent source of logic level mosfet with very very low RdsOn). So I'm going to try adding reset circuit. And if it still doing crazy stuff I think Im not going to try timer interrupts on these 18f I have.Complete mystery.I'm going to try timer1 if it's going to make same crazy stuff.Thanks for checking my code.I did try adding hex values as suggested. Just to confirm Using hex or binary or setting bit by bit has same symptoms on my pic doesn't work until I randomly poke with my voltmeter pins on breadboard and/or power board.

author: NorthGuy
author_rank: Super Contributor
timestamp: November 16, 2018, 06:48:10 pm
content: Quote from: VogonJelc on November 16, 2018, 06:32:38 pmCheck that you have pull-up on pin 4 (MCLR) and pull-down on pin 11 (PGM). Or disable them with MCLRE and LVP configs respectively. You also may have bad ground connection.

author: VogonJelc
author_rank: Newbie
timestamp: November 16, 2018, 07:02:06 pm
content: Quote from: NorthGuy on November 16, 2018, 06:48:10 pmYou sir are a champ. LVP off and it works. But why does it not make other stuff I did go crazy. I had it on for my simple fet testing circuit. I used same RA0 to drive logic level mosfet on and off.Thank you!And thank every one who decided to take a look and try to help!

author: NorthGuy
author_rank: Super Contributor
timestamp: November 18, 2018, 12:12:02 am
content: Quote from: VogonJelc on November 16, 2018, 07:02:06 pmIf you leave an input which resets the PIC floating, anything can happen.