Microcontrollers PIC16 C Hardware Timers 1
Mic
roco
ntr
olle
rs PIC16 C Hardware Timers
1
Mic
roco
ntr
olle
rs
2
The microcontroller PIC16F877 has 3 different timers:
• PIC Timer0
• PIC Timer1
• PIC Timer2
PIC16 C Hardware Timers
Mic
roco
ntr
olle
rs
PIC Timer0
The Timer0 module timer/counter has the following
features:
• 8-bit timer/counter
• Readable and writable
• 8-bit software programmable prescaler
• Internal (FOSC/4) or external clock select
• Interrupt on overflow from FFh to 00h
• Edge select (rising or falling) for external clock
3
Mic
roco
ntr
olle
rs
BLOCK DIAGRAM OF THE TIMER0/WDT PRESCALER
4
T0SE: TMR0 Source Edge Select bit
1 = Increment on high-to-low transition on T0CKI pin
0 = Increment on low-to-high transition on T0CKI pin
T0CS: TMR0 Clock Source Select bit
1 = Transition on T0CKI pin
0 = Internal instruction cycle clock (CLKO)
PSA: Prescaler Assignment bit
1 = Prescaler is assigned to the WDT
0 = Prescaler is assigned to the Timer0 module
Mic
roco
ntr
olle
rs
Calculating Count, Fout, and TMR0 values
• If using INTERNAL clock, the division is performed as
follow:
5
Fout The output frequency after the division.
Tout The Cycle Time after the division.
4 The division of the original clock by 4
Count A numeric value to be placed to obtain the desired output frequency - Fout.
(256 - TMR0) The number of times in the timer will count based on the register TMR0.
Mic
roco
ntr
olle
rs
An example of INTERNAL clock
• Suppose we want to create a delay of 0.5 second in the
our program using Timer0. What is the value of Count?
Calculation:
• First, let’s assume that the frequency division by the
Prescaler will be 1:256 and fclk=4MHz. Second, let’s set
TMR0=0. Thus:
6
Mic
roco
ntr
olle
rs
An example of EXTERNAL clock source
7
What is the output frequency - Fout, when the external
oscillator is 100kHz and Count=8?
Calculation:
First, let’s assume that the frequency division by the
Prescaler will be 1:256. Second, let’s set TMR0=0. Thus:
Mic
roco
ntr
olle
rs
8
Test circuit
Mic
roco
ntr
olle
rs
RTCC (timer0) and interrupts
#include<16f877a.h>
#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
#define high start 76
unsigned int8 seconds, high count;
#INT_RTCC //Interrupt procedure
clock_isr() { //called every time RTCC
high_count -= 1; //flips from 255 to 0
if(high_count==0) {
++seconds;
high_count=high_start; //Inc SECONDS counter every
} //76 times to keep time
}
9
Mic
roco
ntr
olle
rs
RTCC (timer0) and interrupts
void main() { //a simple stopwatch program
unsigned int8 start, time;
high_count = high_start;
setup_timer_0( RTCC_INTERNAL | RTCC_DIV_256 );
set_timer0(0);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
do {
printf("Press any key to begin.\n\r"); getc(); start = seconds;
printf("Press any key to stop.\r\n"); getc(); time = seconds -
start;
printf("%U seconds.\n\r", time);
} while (TRUE);
} 10
Mic
roco
ntr
olle
rs
11
Mic
roco
ntr
olle
rs
Timer0-Counter
#include<16f877a.h>
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
void main() {
unsigned int8 count;;
setup_counters (RTCC_EXT_L_TO_H,RTCC_DIV_1);
set_timer0(0);
do {
if (count !=get_timer0()){
count=get_timer0();
printf("%U times.\n\r", count);
}
} while (TRUE);
}
12
Mic
roco
ntr
olle
rs
13
Mic
roco
ntr
olle
rs
TIMER1 MODULE
• The Timer1 module, timer/counter, has the following
features:
• 16-bit timer/counter consisting of two 8-bit registers
(TMR1H and TMR1L)
• Readable and writable
• Interrupt on overflow from FFFFh to 0000h
Timer1 can operate in one of two modes:
• As a Timer
• As a Counter 14
Mic
roco
ntr
olle
rs TIMER1 BLOCK
DIAGRAM
15
TMR1CS: Timer1 Clock Source Select bit
1 = External clock from pin RC0/T1OSO/T1CKI (on the rising edge)
0 = Internal clock (FOSC/4)
Mic
roco
ntr
olle
rs
#include<16f877a.h>
#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
#define high_start 10
unsigned int8 seconds, high_count;
#INT_TIMER1 //Interrupt procedure
clock_isr() { //called every time Timer1
high_count -= 1; //flips from 255 to 0
if(high_count==0) {
++seconds;
high_count=high_start; //Inc SECONDS counter every
} //10 times to keep time
}
16
Timer1 and interrupts
Mic
roco
ntr
olle
rs
void main() { //a simple stopwatch program
unsigned int8 start, time;
high_count = high_start;
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );
set_timer1(3036);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
do {
printf("Press any key to begin.\n\r"); getc(); start = seconds;
printf("Press any key to stop.\r\n"); getc(); time = seconds - start;
printf("%U seconds.\n\r", time);
} while (TRUE);
}
17
Timer1 and interrupts
Mic
roco
ntr
olle
rs
18
Mic
roco
ntr
olle
rs
#include<16f877a.h>
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
void main() {
unsigned int16 count;
set_timer1(3600);
setup_timer_1(t1_external | T1_DIV_BY_1);
delay_ms(500);
count=get_timer1();
do {
if (count !=get_timer1()){
count=get_timer1();
printf("%LU times.\n\r", count);
}
} while (TRUE);
}
19
Timer1-Counter
Mic
roco
ntr
olle
rs
Timer1-Counter
20
Mic
roco
ntr
olle
rs
Timer2
The Timer2 module, timer/counter, has the following
features:
• Two 8-bit registers (TMR2 and PR2)
• Readable and writable
• A prescaler and a postscaler
• Connected only to an internal clock
• Interrupt on overflow
21
Mic
roco
ntr
olle
rs TIMER2 BLOCK
DIAGRAM
22
Mic
roco
ntr
olle
rs
• Timer2 has 2 count registers 8-bits: TMR2 and PR2.
PR2 is a readable and writable register and initialized to
FFh upon Reset.
• Register TMR2 is used to store the "initial" count value
(the value from which it begins to count). Register PR2 is
used to store the "ending" count value (the maximum
value we need/want to reach). ie: using Timer2 we can
determine the started count value, the final count value,
and the count will be between these two values. The
Timer2 increments from 00h until it matches PR2 and
then resets to 00h on the next increment cycle.
23
TIMER2 BLOCK
DIAGRAM
Mic
roco
ntr
olle
rs
• Prescaler and Postscaler - Timer2 is an 8-bit timer with a
prescaler and a postscaler. Each allows to make
additional division of the frequency clock source.
• Prescaler divides the frequency clock source BEFORE
the counting take place at the register TMR2, thus the
counting inside the TMR2 register is performed based on
the divided frequency clock source by the Prescaler
• The match output of TMR2 goes through a 4-bit
postscaler (which gives a 1:1 to 1:16 scaling inclusive) to
generate a TMR2 interrupt (latched in flag bit, TMR2IF
(PIR1<1>)).
• Postscaler divides the frequency that comes out of the
Comparator again for the last time. 24
TIMER2 BLOCK
DIAGRAM
Mic
roco
ntr
olle
rs
Calculate the required
values of the TIMER2:
• Fout – The output frequency after the division.
• Tout – The Cycle Time after the division.
• 4 - The division of the original clock (4 MHz) by 4, when using
internal crystal as clock (and not external oscillator).
• Count - A numeric value to be placed to obtain the desired output
frequency - fout.
• (PR2 – TMR2) - The number of times the counter will count.
25
Mic
roco
ntr
olle
rs
Example and calculation
of how to use TIMER2 • Suppose we want to create a delay of 1 second in the our program
using Timer2. What is the value of Count?
• Calculation:
• First, let's assume that the frequency division by the Prescaler will
be 1:1 and Postscaler will be 1:16. Second, let's set TMR1=0 and
PR2=255. Thus:
26
Mic
roco
ntr
olle
rs
#include<16f877a.h>
#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
#define high_start 125
unsigned int8 seconds, high_count;
#INT_TIMER2 //Interrupt procedure
clock_isr() { //called every time Timer2
high_count -= 1; //flips from 156 to 0
if(high_count==0) {
++seconds;
high_count=high_start; //Inc SECONDS counter every
} //125 times to keep time
}
27
Timer2 and interrupts
Mic
roco
ntr
olle
rs
void main() { //a simple stopwatch program
unsigned int8 start, time;
high_count = high_start;
setup_timer_2(T2_DIV_BY_16,0x9c,16); //PR2=0x9C=156, Postscaler=16
set_timer2(0);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
do {
printf("Press any key to begin.\n\r"); getc(); start = seconds;
printf("Press any key to stop.\r\n"); getc(); time = seconds - start;
printf("%U seconds.\n\r", time);
} while (TRUE);
}
28
Timer2 and interrupts
Mic
roco
ntr
olle
rs
29