Microprocessors and Microcontrollers
Timers & Counters
Timers.1
Timers and Counters
• PIC Microcontroller has three Timers/
Counters:
– Timer 0: 8-bit register TMR0
• Described in section 11 of RM
– Timer 1: 16-bit register TMR1H | TMR1L
• Described in section 12 of RM
– Timer 2: 8-bit register TMR2
• Described in section 13 of RM
Timers.2
Timer 0
• Timer mode:
– a register (TMR0) will be incremented every
instruction cycle (without prescaler)
• Counter mode:
– a register (TMR0) will be incremented every time
either a rising or falling edge occurs at pin T0CKI
• Register TMR0 (0x01 in banks 0 & 2):
– can be read by the user at any time in the program
Timers.3
Timer 0
Architecture
(at address 0x01 in Bank 1 & 3)
Timers.4
Timer 0
Writing to TMR0 ( 0x01 banks 0 & 2)
A write to TMR0 will cause
a 2 instruction cycle (2TCY) inhibit !!!!!
Timers.5
Timer 0
Interrupt
A TIMER 0 interrupt is generated when the TIMER 0 overflows from
0xFF to 0x00
In INTCON bit 5 (NOTE: Timer 0 is turned off during SLEEP) Timers.6
Timer 0
Interrupt
( at location 0x0B in all banks )
bit 5 bit 2
bit 7
See Reference Manual pp.171
Timers.7
Timer 0
fosc = 4MHz
Interrupt - Example
Blink InfraRed (IR) LED at a rate of 5kHz
5kHz => T = 0.2msec => ON for 0.1 ms
OFF for 0.1 ms
If run at maximum speed and selecting
the microcontroller’s oscillator as the timer’s input,
RB0 the counter/timer gets incremented every 1µsec.
IR
PIC16F877
T = 0.1msec = 100 x 1µsec
VSS Timers.8
Timer 0
Interrupt - Example
T = 0.1msec = 100 x 1µsec
So make sure that it takes Timer 0
100 counts before it overflows:
Pick the initial value of Timer 0 as 256 – 100 = 156 = 0x9C
( add 2 to this to account for two-cycle delay) 156+2 = 158 = 0x9E
Timers.9
Timer 0
Example - Setup
OPTION_REG: B’XX0X1XXX’ : B’1101 1111’
Timers.10
Timer 0
Interrupt – Example – Step 1 & 3
org 0x000
goto INIT
org 0x004
goto T0_ISR
INIT: clrf STATUS ; access
bsf STATUS,5 ; bank 1 (for OPTION and TRIS)
clrf TRISB, F ; pin 0 (and others) of PORTB: output
movlw B’ 11011111’ ; setup the OPTION register
movwf OPTION_REG
bcf STATUS,5 ; access bank 0
movlw b’00100000’ ; enable the Timer 0 interrupt
movwf INTCON ; clears T0IF also
movlw D’158’ ; initialize the Timer 0 counter
movwf TMR0
bsf INTCON,7 ; enable global interrupts
…
Timers.11
Timer 0
Interrupt – Example – Step 2
MAIN: …
…
goto MAIN
T0_ISR: comf PORTB,F ; Toggles LED on RB0
movlw D’158’ ; make sure to put the original
movwf TMR0 ; value back in the TMR0 register
bcf INTCON,2 ; clear the Timer 0 interrupt flag
retfie ; return to whatever you were doing
Timers.12
Timer 0
Prescaler
A Prescaler divides the input clock
(Fosc/4 or the clock on the pin) by
another factor:
Timers.13
Timer 0
Prescaler - Example
Suppose we want to change our earlier example’s interrupt rate
from 10kHz (= 0.1msec) to 2.5kHz (0.4msec).
This could be accomplished by dividing the input clock by four or
selecting bit value 001 for PS2, PS1, and PS0. Make sure to also
select the pre-scalar by clearing bit 3 of OPTION_REG (PSA).
org 0x0000
goto INIT
org 0x0004
goto T0_ISR
INIT: clrf STATUS ; access
bsf STATUS,5 ; bank 1
clrf TRISB, F ; pin 0 (an others) of PORTB: output
movlw B’00000001’ ; setup the OPTION register
movwf OPTION_REG
bcf STATUS,5 ; access bank 0
… Timers.14
Timer 0
Prescaler
• The Prescaler is shared with the
WatchDog timer … but more about
that one later.
Timers.15
Timer 0
Counter Mode of Operation
Timers.16
Timer 0
Counter Mode: Synchronization
Timers.17
Timer 0
Counter Mode of Operation
OPTION_REG
OSC1
CPU
Clock
T0SE = 0:
or PIC16F877
T0SE = 1:
T0CKI
External
Clock
Timers.18
Timer 0
Counter Mode Example
Count the number of times someone pushes a button given the
following hardware setup.
VDD
If button is pushed the
voltage on the T0CKI pin
goes from VDD to VSS.
T0CKI
In other words we want
PIC16F877 to detect a falling edge:
Vss T0SE = 1
Timers.19
Timer 0
Counter Mode Example
OPTION_REG: B’XX111XXX’ : B’11111111’
Timers.20
Timer 0
Counter Mode Example
org 0x000
INIT: clrf TMR0,F ; clear the counter (2TCY inhibit)
clrf STATUS ; access
bsf STATUS,RP0 ; bank 1
movlw B’ 11111111’ ; setup the OPTION register
movwf OPTION_REG
bcf STATUS,RP0 ; access bank 0
MAIN: …
…
…
movf TMR0,W ; read the number of button pushes
…
…
…
Timers.21
Timer 0
During microcontroller SLEEP
Timer 0 is shutdown
Timers.22
Timer 1
• Timer mode:
– a register (TMR1H | TMR1L) will be incremented
every instruction cycle (without prescaler)
• Counter mode:
– a register (TMR1H | TMR1L) will be incremented
every time a rising edge occurs at pin T1CKI
• Registers TMR1H & TMR1L:
– can be read by the user at any time in the program
Timers.23
Timer 1
Architecture
Timers.24
Timer 1
Architecture
Timer Counter
Synchronous Asynchronous
The external clock input is No synchronization takes
synchronized with the place, just increment
rising edge of the CPU counter at any rising edge
clock just like with Timer0 of external clock input
Timers.25
Timer 1
What about reading out the Timer’s 2 Bytes
Oops Oops
So, what is the solution?
Timers.26
Timer 1
What about reading out the Timer’s 2 Bytes
; All interrupts are disabled
movf TMR1H, W ; Read high byte
movwf TMPH ;
movf TMR1L, W ; Read low byte
movwf TMPL ;
movf TMR1H, W ; Read high byte
subwf TMPH, W ; Sub 1st read with 2nd read
btfsc STATUS,Z ; Is result = 0
goto CONTINUE ; Good 16-bit read
;
; TMR1L may have rolled over between the read of the high and low bytes.
; Reading the high and low bytes now will read a good value.
;
movf TMR1H, W ; Read high byte
movwf TMPH ;
movf TMR1L, W ; Read low byte
movwf TMPL ;
; Re-enable the Interrupt (if required)
CONTINUE … ; Continue with your code Timers.27
Timer 1
What about writing out the Timer’s 2 Bytes
; All interrupts are disabled
clrf TMR1L ; Clear Low byte, Ensures no
; rollover into TMR1H
movlw HI_BYTE ; Value to load into TMR1H
movwf TMR1H, F ; Write High byte
movlw LO_BYTE ; Value to load into TMR1L
movwf TMR1L, F ; Write Low byte
; Re-enable the Interrupt (if required)
CONTINUE … ; Continue with your code
Timers.28
Timer 1
Associated Registers
To turn the Timer 1 On
Timers.29
Timer 1
Associated Registers (Interrupts)
Peripheral Interrupt Enable Flag & Enable bits
Timers.30
For PIC16F877
(See section 12 of DS)
Timers.31
Timer 1
Example with Interrupt
We want to blink the light at a frequency of 1 Hz
without using a Timing Loop (Delay)
1 Hz => T = 1.0 seconds => ON for 0.5 seconds
RB0 OFF for 0.5 seconds
@ fosc = 4MHz => fcy = 1MHz => Tcy = 1µsec
0.5 seconds = 500,000 instruction cycles
PIC16F877
Timer 1 can count from 0 to 65,536 (=64k)
How do we increase this?
VSS Use the pre-scaler !!
Timers.32
Timer 1
Example with Interrupt
65,536 * 1 = 65,536 (1us)
65,536 * 2 = 131,072 (2us)
65,536 * 4 = 262,144 (4us) 500,000/8 = 62,500
65,536 * 8 = 524,288 (8us)
(62,500 * 8us = 0.5s)
So, if we can cause Timer 1 to overflow after 62,500 increments
we will cause an Interrupt every ~0.5 seconds
Thus, start Timer 1 at 65,536 – 62,500 = 3036 = 0x0BDC
Initialize TMR1H with 0x0B and TMR1L with 0xDC Timers.33
Timer 1
Setup
T1CON:
T1CON: B’ 0 0 1 1 0 1 0 0’
Timers.34
Timer 1
Interrupt – Example – Step 1
org 0x000
goto INIT
org 0x004
goto T1_ISR
INIT: clrf STATUS ; access
bsf STATUS,RP0 ; bank 1
bcf TRISB, 0 ; make pin 0 of PORTB: output
bcf STATUS,RP0 ; access bank 0
; Initialize Timer 1
movlw B’00110100’ ; setup the T1CON register
movwf T1CON ; leave Timer 1 off for now
movlw 0x0B ; Value to load into TMR1H
movwf TMR1H, F ; Write High byte
movlw 0xDC ; Value to load into TMR1L
movwf TMR1L, F
…
Timers.35
Timer 1
Interrupt – Example – Step 1 (Continued)
; Initialize the interrupts:
bsf STATUS, RP0 ; select bank 1
bsf PIE1, TMR1IE ; enable Timer 1 interrupt
bcf STATUS, RP0 ; select bank 0 again
bcf PIR1, TMR1IF ; clear the interrupt flag
movlw B’11000000’ ; Turn on GIE and PEIE
movwf INTCON ;
bsf T1CON, TMR1ON ; TURN on Timer 1
Main: goto Main
end
Timers.36
Timer 1
Interrupt – Example – Step 2
MAIN: goto MAIN
T1_ISR: comf PORTB,F ; Toggles LED on RB0
clrf TMR1L ; Clear Low byte, Ensures no
; rollover into TMR1H
movlw 0x0B ; Value to load into TMR1H
movwf TMR1H, F ; Write High byte
movlw 0xDC ; Value to load into TMR1L
movwf TMR1L, F
bcf PIR1, TMR1IF ; clear the interrupt flag
retfie ; return to whatever you were doing
Timers.37
Timer 1
During microcontroller SLEEP
Timer 1 is ON (in asynchronous mode)
and can wake up the microcontroller
Timers.38
Timer 2
• Timer: 8-bit
• With prescaler and postscaler
• Shutdown during SLEEP
• Timer 2 increments until it matches
register PR2 at which time it resets to
0x00, and increments the postscalar.
Timers.39
Timer 2
Architecture
Timers.40
Timer 2
In PIC16F877
Prescaler and Postscaler Counters clear when:
- any write occurs to TMR2 register.
- any write occurs to T2CON register. (TMR2 does not clear).
Timers.41