4
\$\begingroup\$

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?

asked Sep 3, 2012 at 13:44
\$\endgroup\$
2
  • \$\begingroup\$ 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 :-) \$\endgroup\$ Commented Sep 3, 2012 at 14:30
  • \$\begingroup\$ I added some detail to my answer, how you get your actual 8 seconds delay. Hope it helps. \$\endgroup\$ Commented Sep 3, 2012 at 14:58

1 Answer 1

5
\$\begingroup\$

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.

answered Sep 3, 2012 at 14:30
\$\endgroup\$
5
  • \$\begingroup\$ This is by far the best post I have read that's short and laconic. Thank you this definitely helped \$\endgroup\$ Commented Sep 3, 2012 at 15:08
  • \$\begingroup\$ By the way you stated "So for a 1Mhz clock frequency your interrupt is triggered every 265ms" I assume ms here is milliseconds right ? \$\endgroup\$ Commented Sep 3, 2012 at 15:10
  • \$\begingroup\$ @MistyD - Yes ms is milliseconds. I'm glad I could help. \$\endgroup\$ Commented Sep 3, 2012 at 15:13
  • \$\begingroup\$ 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 ? \$\endgroup\$ Commented Sep 3, 2012 at 15:20
  • \$\begingroup\$ @MistyD - Whoops, your right. I corrected it in the answer. \$\endgroup\$ Commented Sep 3, 2012 at 15:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.