Home > electronics, programming > Fixed Time Loop in Microcontrollers

Fixed Time Loop in Microcontrollers

Hey.

Most of the times I am developing a piece of code for my PICs, there is a main loop in the flow. The code repeats it self indefinitely doing its thing and it is only interrupted temporarily by the hardware interrupts of the PIC. Now most of the times a simple while(1) { // code here } will do just fine. However, sometimes your need that loop to start at specific time interval for example every half second. This is pretty useful when somewhere in your maths you need a specific dt.

The way we will do this is by using a timer to count the time pass and let us know when its time to restart the loop. To do that we will use the overflow interrupt of timer0. Let’s do an example. We want our loop to run every 10msec. Let’s assume that the PIC is running on a 10MHz oscillator. That means the clock time is 1/10MHz=0.1usec . The instruction clock is four times that i.e. 0.4usec. Therefore, using no prescaler or postscaler, timer0 counts up every 0.4usec. We set our timer0 to 16-bit mode i.e. to count up to 0xFFFF.

Now to do some calculations. So we need to set the timer to a value (let’s call this A) so that after 10msec it will reach 0xFFFF and cause the overflow which will notify us. Now if the clock increments every 0.4usec, it takes 10msec/0.4usec=25000 counts (or 0x61A8 in hex). Therefore A+0x61A8=0xFFFF which makes A=0x9E57.

Load the A value to timer0 when the program starts running. Then when the timer overflows and interrupts the flow, raise a flag to show that the time is up and load the A value again. Finally put the stuff that you want to have a fixed time loop into an if statement branch which will check whether the flag is raised. Within that loop reset the flag.

EDIT: Adding the code and a screenshot – 22/04/2011

Below I am showing the code I described above. This is code for the CCS compiler but you can easily change it to suit your needs. I think it is pretty clear.

#include <main.h>
#int_TIMER0
short flag=0;
 
void  TIMER0_isr(void)
{
   set_timer0(0x9e57);
   output_toggle(PIN_A0); // Use an LED in A0 pin to see the loop
   flag=1;
   clear_interrupt(INT_TIMER0);
   enable_interrupts(INT_TIMER0);
}
 
void main()
{
   // Here you setup your timer
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);      //26.2 ms overflow
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
 
   // Setup the interrupts
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
 
   // This value will create overflow in 10ms
   set_timer0(0x9e57);
 
   while(1) //main loop
   {
      if (flag==1)
      {
         // Put here the stuff that you want to run
         // on a fixed loop
 
         flag=0;
      }
 
      // Here you can put stuff to run while you are
      // waiting for the new fixed loop to start
   }
}

So I programmed a PIC with the above code and hooked it up to the oscilloscope. In the screenshot below you can see the output from the A0 pin. Notice the correct timings on the bottom of the screen.

Oscilloscope Screenshot

Thats it. Any questions, improvements or comments are always welcome.

Until next time, bye.


Related Posts:



Categories: electronics, programming Tags:
  1. No comments yet.
  1. No trackbacks yet.