You are on page 1of 36

PIC16 C Hardware Timers

Microcontrollers

1
PIC16 C Hardware Timers

The microcontroller PIC16F877 has 3 different timers:

• PIC Timer0
• PIC Timer1
• PIC Timer2
Microcontrollers

2
PIC Timer0
The Timer0 module timer/counter has the following
features:
• 8-bit timer/counter
• Readable and writable
• 8-bit software programmable prescaler
Microcontrollers

• Internal (FOSC/4) or external clock select


• Interrupt on overflow from FFh to 00h
• Edge select (rising or falling) for external clock

3
BLOCK DIAGRAM OF THE TIMER0/WDT PRESCALER

T0SE: TMR0 Source Edge Select bit


1 = Increment on high-to-low transition on T0CKI pin
Microcontrollers

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

4
Calculating Count, Fout, and TMR0 values

• If using INTERNAL clock, the division is performed as


follow:
Microcontrollers

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.

5
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
Microcontrollers

Prescaler will be 1:256 and fclk=4MHz. Second, let’s set


TMR0=0. Thus:

6
An example of EXTERNAL clock source

What is the output frequency - Fout, when the external


oscillator is 100kHz and Count=8?

Calculation:
Microcontrollers

First, let’s assume that the frequency division by the


Prescaler will be 1:256. Second, let’s set TMR0=0. Thus:

7
Microcontrollers
Test circuit

8
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
Microcontrollers

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
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);
Microcontrollers

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
Microcontrollers

11
Timer0-Counter
#include<16f877a.h>
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

void main() {
unsigned int8 count;;
Microcontrollers

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
Microcontrollers

13
TIMER1 MODULE
• The Timer1 module, timer/counter, has the following
features:

• 16-bit timer/counter consisting of two 8-bit registers


(TMR1H and TMR1L)
Microcontrollers

• 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
TIMER1 BLOCK
DIAGRAM
Microcontrollers

2000JUN02_CT_AN5
: Timer1
15
Microcontrollers

16
Microcontrollers

17
Microcontrollers

18
• The maximum clock frequency at the T0CKI input is limited by the synchronization requirement
with the internal clock. Each machine cycle (or instruction cycle) for a PIC microcontroller consists
of four clock cycles, which are named as Q1, Q2, Q3, and Q4. The synchronization of T0CKI with
the internal clock is accomplished by sampling the prescaler output on the Q2 and Q4 cycles of
each machine cycle. Therefore, the external clock signal at T0CKI should remain high or low for at
least half of the duration of the machine cycle (which is 2Tosc, Tosc is the period for the main
oscillator), plus an additional resistor-capacitor delay of 20 ns. This determines the minimum value
of the pulse width that enters through the T0CKI pin. The minimum time period of the input clock
pulse is, therefore, 4Tosc + 40 ns, and the maximum frequency will be the reciprocal of this.
Microcontrollers

• For example, if the main oscillator frequency is 4 MHz (Tosc 0.25 ?s), the machine cycle will be 4
x Tosc = 1 ?s long. An external clock signal going directly into the counter (without the prescaler)
should be high for at least 2Tosc+20 ns = 520 ns and low for at least the same time, giving the
total time period of 520 x 2 = 1040 ns. Therefore, the limit for maximum input frequeny would be
1/1040 ns = 961.5 KHz. If the prescaler is used, the electrical specification of PIC16F688 says
that the external clock input must be high and low for at least 10 ns, which gives the maximum
countable frequency through T0CKI pin equal to 50 MHz. Read Microchip’s tutorials on
Timers: Part 1 and Part 2 for further details.
• - See more at: http://embedded-lab.com/blog/?p=1042#sthash.nol4LF0H.dpuf

19
Timer1 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 10
unsigned int8 seconds, high_count;
Microcontrollers

#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
}
20
Timer1 and interrupts
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);
Microcontrollers

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);
}

21
Microcontrollers

22
Timer1-Counter
#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);
Microcontrollers

delay_ms(500);
count=get_timer1();
do {
if (count !=get_timer1()){
count=get_timer1();
printf("%LU times.\n\r", count);
}
} while (TRUE);
}
23
Timer1-Counter
Microcontrollers

24
Microcontrollers

Sleep mode

25
Microcontrollers Sleep mode

26
Microcontrollers

Sleep mode

27
Timer2
The Timer2 module, timer/counter, has the following
features:

• Two 8-bit registers (TMR2 and PR2)


• Readable and writable
Microcontrollers

• A prescaler and a postscaler


• Connected only to an internal clock
• Interrupt on overflow

28
TIMER2 BLOCK
DIAGRAM
Microcontrollers

29
TIMER2 BLOCK
DIAGRAM
• 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
Microcontrollers

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.

30
TIMER2 BLOCK
DIAGRAM
• 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
Microcontrollers

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. 31
Calculate the required
values of the TIMER2:

• Fout – The output frequency after the division.


• Tout – The Cycle Time after the division.
Microcontrollers

• 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.

32
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:
Microcontrollers

33
Timer2 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 125


unsigned int8 seconds, high_count;
Microcontrollers

#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
}

34
Timer2 and interrupts
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);
Microcontrollers

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);
}

35
Microcontrollers

36

You might also like