View previous topic :: View next topic |
Author |
Message |
montypaul
Joined: 08 May 2008 Posts: 3
|
pic18f2620 and timer interrupt help!! |
Posted: Thu May 08, 2008 5:50 pm |
|
|
What's wrong in this code?
I am migrating from 16f876 to 18f2620 and the program that makes a led blinking just doesn't work.
Code: |
#include <18f2620.h>
#fuses XT, NOPROTECT, PUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, MCLR
#use delay(clock=4000000)
static long cADCflag,cInterruptCount; /* global variable */
void main()
{
/* SET THE COUNTER TO ROLL EVERY 11.10ms*/
setup_timer_0 ( RTCC_INTERNAL | RTCC_8_BIT | RTCC_DIV_256 ); /* timer increments every 11.10 ms */
enable_interrupts ( INT_RTCC ); /* enable timer interrupt */
enable_interrupts ( GLOBAL ); /* enable global interrupts */
set_timer0 ( 39 ); /* start counter at 256-39 = 217 counts until wrap */
#INT_RTCC
void TIMER_INTERRUPT ( void )
{
if ( cInterruptCount++ == 90 ) // if one second yet
{
cAdcFlag = 1; /* set flag to alert main program to read ADC */
cInterruptCount = 0;
OUTPUT_HIGH ( PIN_C3 );
delay_ms(200);
OUTPUT_LOW ( PIN_C3 );
}
set_timer0 ( 39 ); // restart at adjusted value for 1-second accuracy
} |
_________________ Paul |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 08, 2008 6:27 pm |
|
|
You need to show the rest of the main() function. (Make it short).
For example, if you just have a closing brace, and that's all, then the
code will execute a hidden sleep instruction and go to sleep. You won't
see anything.
Putting a 200 ms delay inside an isr that interrupts every 11 ms
isn't a good idea. If you just want to signal that the isr is being
entered (for debugging purposes), then you could put a single
putc() statement in there. Example:
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu May 08, 2008 6:28 pm |
|
|
Your program is not complete, so I can't say for sure where the problem is. One missing item is that you are not initialising the variable cInterruptCount. With a random value the first time it could take up to about 65000 interrupts before the first blink starts.
Why have you made this variable a 'long' type? An 8 bit integer would suffice and makes your interrupt handler faster.
A second problem is your timing being off by a factor 5.
4 MHz / (4 * 256 *217) = 55,5ms and not 11,1ms....
So instead of counting 90 interrupts you only have to count 90/5=18 interrupts.
Code: | set_timer0 ( 39 ); // restart at adjusted value for 1-second accuracy | You can never be sure of the time it takes to enter the interrupt handler, for example another interrupt might be active at the same time. If you want to have a more accurate 1 second timer you should move this line to the start of the interrupt handler and change to Code: | set_timer0 ( get_timer_0() + 39 ); // restart at adjusted value for 1-second accuracy
|
|
|
|
montypaul
Joined: 08 May 2008 Posts: 3
|
|
Posted: Fri May 09, 2008 9:33 am |
|
|
Problem fixed, Thank you very much! _________________ Paul |
|
|
|