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

 | Site Tutorial Index |
|  | 16F PIC Examples |
|  | 18F PIC Examples |
| |  | 7 Segment Displays |
| |  | 7 Segment Displays |
| |  | RS232 and UART |
| |  | Code Snippets |
| | |  | Internal Timers |
| | |  | Interrupts |
|  | Handy Tips |