Take the 2-minute tour ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

I am currently trying the following example

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


#INT_TIMER1
void TimerOverflow() 
{
    printf("Timer Overflowed\r\n");
}

void main() 
{
   long time;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_TIMER1);

   set_timer1(8000); //count till 8000 then overflow
   time = get_timer1();
     while(1)
     {
     }

}

However the interrupt function is supposed to be called after ever (almost) 8 seconds but its being called as if the delay was 0 seconds. What am i doing wrong here?

share|improve this question
    
Try to force the interrupt flag to be cleared. After banging my head several times on the wall I have learned that I cannot trust 100% on compilers :-) –  Bruno Ferreira Sep 3 '12 at 14:30
    
I added some detail to my answer, how you get your actual 8 seconds delay. Hope it helps. –  PetPaulsen Sep 3 '12 at 14:58
add comment

1 Answer

up vote 4 down vote accepted

I think you missunderstood the timer-funtions. According to your comment you are assuming, that set_timer1 will set the value the timer counts to. But what realy happens is, that you set timer1 to the value 8000. The timer interrupt is triggered everytime the timer overflows. Because timer1 is a 16 bit timer this happens when the counter reaches 65535. So the first time the timer counts from 8000 to 65535, triggers the interrupt, resets the counter to 0 and counts again to 65535, triggers the interupt, and so on.

Let \$f\$ be the clock frequency, then is the time interval \$T\$ your interrupt is triggered: $$ T = \frac{4\cdot2^{16}}{f} $$ So for a 1Mhz clock frequency your interrupt is triggered every 262ms, for a 20Mhz it is triggered every 13ms.

What you need to do to get a bigger delay is to increase a software-counter in your interrupt routine. But with your 20Mhz clock you are getting these odd 13ms. What you need to get a nice number like 10ms is to count to 50000 (rearrange the formula from above). So what you can do is initialize the timer not to 0 but to \$2^{16} - 50000 = 15536\$ (this time with the set_timer1-function). The last thing is to increase the mentioned software-counter everytime your interrupt triggers. When your variable hold a value of 8000 you know, that 8s elapsed.

You should read the datasheet for the pic, especially chapter 6 'Timer1 Module', to get a better understanding what is happening and how to use your pic microcontroller.

share|improve this answer
    
This is by far the best post I have read that's short and laconic. Thank you this definitely helped –  MistyD Sep 3 '12 at 15:08
    
By the way you stated "So for a 1Mhz clock frequency your interrupt is triggered every 265ms" I assume ms here is milliseconds right ? –  MistyD Sep 3 '12 at 15:10
    
@MistyD - Yes ms is milliseconds. I'm glad I could help. –  PetPaulsen Sep 3 '12 at 15:13
    
You stated "So for a 1Mhz clock frequency your interrupt is triggered every 265ms" I guess you meant 262.144 Milliseconds right ? Since $${\frac{4\times 2^{16}}{1}=262,144}~Microseconds $$ so $$\frac{262144}{1000}=262.144~Milliseconds$$ Am I correct ? –  MistyD Sep 3 '12 at 15:20
    
@MistyD - Whoops, your right. I corrected it in the answer. –  PetPaulsen Sep 3 '12 at 15:26
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.