3.4 Timer0
The PIC16F887 microcontroller features three completely independent timers/counters marked as TMR0, TMR1 and TMR2. Read carefully the following chapter to learn more about them.
Timer0 has a wide range of application in practice. There is almost no program without it as it allows you to easily write a code that is to generate pulses of arbitrary duration, time measurement or counting of external pulses (events) with almost no limitations. Timer0 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 Timer0 schematic with all bits controlling 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 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 the Timer0/counter input through the RA4 pin.
- 1 - Timer0 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 Timer0/counter.
- 1 - Prescaler is assigned to the WDT.
- PS2, PS1, PS0 - Prescaler Rate Select bit
- Prescaler rate is set by combining these bits. As seen in the table, the same combination of bits gives different prescaler rate for the Timer0/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 the PSA bit is cleared, the prescaler is asigned to the Timer0/counter as shown in figure below:
Let's do it in mikroBasic...
' In this example, Timer0 is configured as a timer and prescaler is assigned to it.
unsigned cnt ' Define variable cnt
sub procedure interrupt ' Interrupt routine
cnt = cnt + 1 ' Interrupt causes cnt to be incremented by 1
TMR0 = 155 ' Timer0 (or counter) returns its initial value
INTCON = 0x20 ' Bit T0IE is set, bit T0IF is cleared
end sub
main:
OPTION_REG = 0x04 ' Prescaler (1:32) is assigned to Timer0
TMR0 = 155 ' Timer0 counts from 155 to 255
INTCON = 0xA0 ' Enable interrupt on TMR0 overflow
...
...
' In the following example, Timer0 is configured as counter and prescaler is assigned to it
OPTION_REG = 0x20 ' Prescaler (1:2) is assigned to the Timer0
TMR0 = 155 ' Timer0 counts from 155 to 255
INTCON = 0xA0 ' Enable interrupt on TMR0 overflow
...
When the PSA bit is set, the prescaler is asigned to the watch-dog timer as shown in figure below:
Let's do it in mikroBasic...
' In this example, prescaler (1:64) is assigned to watch-dog timer.
main:
OPTION_REG = 0x0E ' Prescaler is assigned to WDT (1:64)
asm
CLRWDT ' Assembly command to reset WDT
end asm
...
...
asm
CLRWDT ' Assembly command to reset WDT
end asm
...
This 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.
- Write to the TMR0 register, used as a timer, will not cause the pulse counting to start immediately, but with two instruction cycles delay. Accordingly, it is ne cessary to adjust the value written to the TMR0 register.
- When the microcontroller is set to sleep mode, the clock oscillator is turned off. No overflow can occur since there are no pulses to count and therefore the TMR0 overflow interrupt cannot wake up the microcontroller from Sleep mode.
- When used as an external clock counter, without prescaler, a minimum pulse length or a delay between two pulses must be 2 Tosc + 20 nS (Tosc stands for the period of a clock signal generated by the oscillator).
- When used as an external clock counter with prescaler, a minimum pulse length or interval between two pulses is 10nS only.
- The 8-bit prescaler register is not available to the user, which means that it can not be directly read or written to.
- When switching the prescaler assignment from Timer0 to watch-dog timer, the following instruction sequence written in assembly language must be executed in order to prevent the microcontroller from resetting:
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 USING ‘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 Timer0, 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 USNG ‘LOGIC AND’ INSTRUCTION
IORLW b’00000011’ ;PRESCALER RATE IS 1:16
MOVWF OPTION_REG
In Short
In order to use Timer0 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 an interrupt is used, the GIE and TMR0IE bits of the INTCON register should be set.
Step 2: To measure and count Time measurement:
- Reset the TMR0 register or write some known value to it.
- Elapsed time (in microseconds if 4MHz quartz crystal is used) 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.
Counting:
- The polarity of pulses 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 the timer mode.