3.4 Timer TMR0
The timer TMR0 has a wide range of application in practice. Very few programs don’t use it in some way. It is very convenient and easy to use for writing programs or subroutines for generating pulses of arbitrary duration, time measurement or counting external pulses (events) with almost no limitations.
The timer TMR0 module is an 8-bit timer/counter with the following features:
- 8-bit timer/counter;
- 8-bit prescaler (shared with Watchdog timer);
- Programmable internal or external clock source;
- Interrupt on overflow; and
- Programmable external clock edge selection.
Figure below illustrates the timer TMR0 schematic with all bits which determine its operation. These bits are stored in the OPTION_REG register.
OPTION_REG Register
- RBPU - PORTB Pull-up enable bit
- 0 - PORTB pull-up resistors are disabled.
- 1 - PORTB pins can be connected to pull-up resistors.
- INTEDG - Interrupt Edge Select bit
- 0 - Interrupt on rising edge of the INT pin (0-1).
- 1 - Interrupt on falling edge of the INT pin (1-0).
- T0CS - TMR0 Clock Select bit
- 0 - Pulses are brought to TMR0 timer/counter input through the RA4 pin.
- 1 - Timer uses internal cycle clock (Fosc/4).
- T0SE - TMR0 Source Edge Select bit
- 0 - Increment on high-to-low transition on the TMR0 pin.
- 1 - Increment on low-to-high transition on the TMR0 pin.
- PSA - Prescaler Assignment bit
- 0 - Prescaler is assigned to the WDT.
- 1 - Prescaler is assigned to the TMR0 timer/counter.
- PS2, PS1, PS0 - Prescaler Rate Select bit
- Prescaler rate is adjusted by combining these bits. As seen in the table, the same combination of bits gives different prescaler rate for the timer/counter and watch-dog timer, respectively.
PS2 |
PS1 |
PS0 |
TMR0 |
WDT |
0 |
0 |
0 |
1:2 |
1:1 |
0 |
0 |
1 |
1:4 |
1:2 |
0 |
1 |
0 |
1:8 |
1:4 |
0 |
1 |
1 |
1:16 |
1:8 |
1 |
0 |
0 |
1:32 |
1:16 |
1 |
0 |
1 |
1:64 |
1:32 |
1 |
1 |
0 |
1:128 |
1:64 |
1 |
1 |
1 |
1:256 |
1:128 |
When PSA bit is cleared, prescaler is asigned to TMR0 timer/counter as ilustrated on the figure below:
Let's do it in mikroC...
// In this example, TMR0 is configured as a timer and prescaler is assigned to it.
unsigned cnt; // Define variable cnt
void interrupt() { // Interrupt routine
cnt++; // Interrupt causes cnt to be incremented by 1
TMR0 = 155; // Timer (or counter) TMR0 returns its initial value
INTCON = 0x20; // Bit T0IE is set, bit T0IF is cleared
}
void main() {
OPTION_REG = 0x04; // Prescaler (1:32) is assigned to the timer TMR0
TMR0 = 155; // Timer T0 counts from 155 to 255
INTCON = 0xA0; // Enable interrupt TMR0
...
...
// In the following example,TMR0 is configured as counter and prescaler is assigned to it
OPTION_REG = 0x20; // Prescaler (1:2) is assigned to the counter TMR0
TMR0 = 155; // Counter T0 counts from 155 to 255
INTCON = 0xA0; // Enable interrupt TMR0
...
...
When PSA bit is set, prescaler is asigned to watch-dog timer as ilustrated on the next figure:
Let's do it in mikroC...
// In this example, prescaler (1:64) is assigned to Watch-dog timer.
void main() {
OPTION_REG = 0x0E; // Prescaler is assigned to WDT (1:64)
asm CLRWDT; // Assembly command to reset WDT
...
...
asm CLRWDT; // Assembly command to reset WDT
...
Additionally it is also worth mentioning:
- When the prescaler is assigned to the timer/counter, any write to the TMR0 register will clear the prescaler.
- When the prescaler is assigned to the watch-dog timer, the CLRWDT instruction will clear both the prescaler and WDT.
- Write to the TMR0 register, used as timer, will not cause the pulse counting to start immediately, but with two instruction cycles delay. Accordingly, it is necessary to adjust the value written to the TMR0 register.
- When the microcontroller is set in sleep mode, the clock oscillator is turned off. Overflow cannot occur since there are no pulses to count. This is why the TMR0 overflow interrupt cannot wake up the processor from Sleep mode.
- When used as an external clock counter, without prescaler, a minimal pulse length or a delay between two pulses must be 2 Tosc + 20 nS (Tosc is the oscillator clock signal period).
- When used as an external clock counter with prescaler, a minimal pulse length or interval between two pulses is only 10nS.
- The 8-bit prescaler register is not available to the user, which means that it cannot be directly read or written to.
- When changing the prescaler assignment from TMR0 to the watch-dog timer, the following instruction sequence written in assembly language must be executed in order to prevent the microcontroller from reset:
BANKSEL TMR0
CLRWDT ;CLEAR WDT
CLRF TMR0 ;CLEAR TMR0 AND PRESCALER
BANKSEL OPTION_REG
BSF OPTION_REG,PSA ;PRESCALER IS ASSIGNED TO WDT
CLRWDT ;CLEAR WDT
MOVLW b'11111000' ;SELECT BITS PS2,PS1,PS0 AND CLEAR
ANDWF OPTION_REG,W ;THEM BY 'LOGIC AND' INSTRUCTION
IORLW b'00000101' ;BITS PS2, PS1, AND PS0 SET
MOVWF OPTION_REG ;PRESCALER RATE TO 1:32
- Likewise, when changing the prescaler assignment from the WDT to TMR0, the following instruction sequence, also written in assembly language, must be executed:
BANKSEL TMR0
CLRWDT ;CLEAR WDT AND PRESCALER
BANKSEL OPTION_REG
MOVLW b'11110000' ;SELECT ONLY BITS PSA,PS2,PS1,PS0
ANDWF OPTION_REG,W ;CLEAR THEM BY 'LOGIC AND' INSTRUCTION
IORLW b'00000011' ;PRESCALER RATE IS 1:16
MOVWF OPTION_REG
In Short
In order to use TMR0 properly, it is necessary:
Step 1: To select mode:
- Timer mode is selected by the T0CS bit of the OPTION_REG register, (T0CS: 0=timer, 1=counter).
- When used, the prescaler should be assigned to the timer/counter by clearing the PSA bit of the OPTION_REG register. The prescaler rate is set by using the PS2-PS0 bits of the same register.
- When using interrupt, the GIE and TMR0IE bits of the INTCON register should be set.
Step 2: Measuring and Counting
To measure time:
- Reset the TMR0 register or write some known value to it.
- Elapsed time (in microseconds when using 4MHz quartz) is measured by reading the TMR0 register.
- The flag bit TMR0IF of the INTCON register is automatically set every time the TMR0 register overflows. If enabled, an interrupt occurs.
To count pulses:
- The polarity of pulses are to be counted on the RA4 pin is selected by the TOSE bit of the OPTION_REG register (T0SE: 0=positive, 1=negative pulses).
- Number of pulses may be read from the TMR0 register. The prescaler and interrupt are used in the same manner as in timer mode.