18F Code Snippet - TMR0

    TMR0 is an 8 byte timer/counter that can be pre-scaled to change vary its incrementing cycle. It is quite different in regards to setting up compared to the 16F's, but here's an example.

    Pre-scaling is important as we may want the Timer Register to increment faster/slower in different applications. The speed in which it does cycle is dependent on both the external crystal speed and the pre-scaling options, or the Prescaler and external clock if an external source is used.

    Now to make a timer that can be used to count mS very accurately. An easy way to find out how much time each clock cycle will take is to use a cycle calculator such as this. Make sure that the Internal Check Box is selected, now be sure that 20Mhz is the clock speed, and the pre-scaler is set to 1:32, you will see that the TMR0 period is now 1.638mS, so every time the TMR0 clock reaches 255, and rolls over to 0, 1.638mS has elapsed. To make things easier, I will work with a scale of 1000 for my mS counter. Now when mS = 10000, 10mS has elapsed, so there is no need to use Floats.

    The sub routine "TMR0_Initialize" goes through the required steps to set up TMR0, follow the code at your own pace;

Device = 18F452
Clock = 20
      
Dim
    mS As Word,
    TMR0ON As T0CON.7,
    T08BIT As T0CON.6,
    T0CS As T0CON.5,
    T0SE As T0CON.4,
    PSA As T0CON.3,
    TMR0IF As INTCON.2,
    TMR0 As TMR0L,
    TMR0IE As INTCON.5,
    TMR0_Event As Boolean

Interrupt TMR0_Interrupt()
    Save(0)                  // Backup system variables
    If TMR0IF = 1 Then       // Check if a TMR0 Interrupt occurred
        TMR0IF = 0           // Clear the interrupt
        Inc(mS, 1638)        // Increment the mS counter (scale of 1000)
        If mS >= 10000 Then  // Working with a scale of 1000, so this 
            mS = mS - 10000  //  checks if 10mS has elapsed
            TMR0_Event = True
        EndIf
    EndIf                   
    Restore                  // Backup system variables
End Interrupt

Sub TMR0_Initialize() 
TMR0ON = 0               // Disable TMR0
T08BIT = 1               // Ensure TMR0 is working in 8 Bit mode
T0CS = 0                 // Ensure TMR increments from internal clock
T0SE = 0                 // Only used if external source is selected
PSA = 0                  // Ensure the Clock source uses the Prescaler
T0CON.0 = 0              // Set the Prescaler bits
T0CON.1 = 0              //
T0CON.2 = 1              //
TMR0 = 0                 // Clear the TMR0 register
TMR0IE = 1               // Enable TMR0 Interrupts
Enable(TMR0_Interrupt)   // Enable the TMR0 Interrupt Handler
TMR0ON = 1               // Enable TMR0 to increment
End Sub

// Start Of Main Program... 
mS = 0                       // Reset the mS counter
TMR0_Event = False           // Clear the TMR0 Event Flag
TMR0_Initialize              // Setup and enable TMR0
Low(PORTB.0)                 // Make PORTB.0 and output and set it low

While True
    While TMR0_Event = False // Wait for 10mS to elapse
    Wend                     // 
    TMR0_Event = False       // Reset the Event Flag
    Toggle(PORTB.0)          // Toggle PORTB.0
Wend                         // Loop forever

 

The result, a very accurate interrupt;

 

Note the PIC's power supply/oscillator are not shown

 Skip Navigation Links.

Collapse Site Tutorial IndexSite Tutorial Index
Expand 16F PIC Examples16F PIC Examples
Collapse 18F PIC Examples18F PIC Examples
LED's
Switches
Expand 7 Segment Displays7 Segment Displays
LCD's
Expand 7 Segment Displays7 Segment Displays
ADC
ADC (Another Example)
EEPROM's
DS1307
Expand RS232 and UARTRS232 and UART
DS18B20
External ADC
Hall Effect Sensor
Pulse Width Modulation (PWM)
Infrared UART
Swordfish Modules
Collapse Code SnippetsCode Snippets
SF Libraries
18F Transition Guide
Internal Oscillator
PLL
Structures
Multi Tasking
Collapse Internal TimersInternal Timers
TMR0
TMR1
TMR2
Expand InterruptsInterrupts
Expand Handy TipsHandy Tips