Search code examples
timerpicinterrupt-handling

Wondering how to strangely preset the value of Timer0?


May I ask when setting the value for Timer0 why in some cases people have to use subtraction to represent the preset Timer0 instead of using its result directly (in this case, 175 )? And in this case what is the purpose of the UL suffix?

Examble:

X=255Ul-80;
void interrupt ISR(void)
{
     if (T0IF)
    {
         T0IF=0;
         TMR0=X;
         abc();
    }
}
...


Solution

  • The Microchip documentation describes how the TIMER0 module works.

    It does not describe methods of how to use this counter/timer module very well.

    The fundamental architecture of the TIMER0 module is very primitive when compared to any modern embedded controller today. It is unclear why Microchip persists with including this counter/timer module in new 8-bit PIC controllers. Understand that 35 years ago it was a challenge to maximize functionality with the minimum number of transistors so that each controller chip would be as small as possible and yield the most chips per wafer.

    The way TIMER0 works is as an up counter. When first implemented the controller did not support interrupts at all. See baseline controllers like the PIC12F508. The mid-range controllers like the PIC16F877 added support for interrupts and TIMER0 acquired the functionality to request an interrupt when the 8-bit count register rolled over from 0xFF to 0x00. It takes 256 counts for TIMER0 to assert an interrupt request when the TIMER0 count register starts at 0x00. When the interrupt needs to be asserted after a specific number of counts set the count register to the value of 256-(Specific_Number_Of_Counts) then clear the TIMER0 interrupt request.

    This feature is used by developer to have the TIMER0 interrupt request assert after a specific number of counts.

    There is an "off-by-one" error in the example in you question:

    X=255Ul-80;

    As the TIMER0 count register will have the value of 0xFF after 80 counts and the TIMER0 interrupt request will be set after 81 counts.

    The example code in your question "suggests" that you want the "abc()" function invoked after TIMER0 have been clocked 80 times. The function will actually be invoked after TIMER0 have been clocked 81 times.

    Also note that the simulation model for TIMER0 does not have a cycle accurate implementation so does not simulate the actual accurately. This simulation flaw exists in all releases of MPLABX for 8-bit PIC controllers. Be warned that the simulator will not provide cycle counts that match the real world hardware.