The Timer is used to measure the time or generate an accurate time delay. It is an important application in an embedded system. It maintains the timing of operation in sync with a system clock or an external clock. The timer is used to count cycles and perform a particular action at a specified moment or optionally start an interrupt cycle. The digital cycles counted by the timer can be supplied internally through the peripheral clock or externally through a crystal, in this article we will look into the details of pic16f877a timer with examples.
The timer is nothing but a simple binary counter that can be configured to count clock pulses(Internal/External). Once it reaches the max value, it will roll back to zero setting up an Overflow flag and generates the interrupt if enabled.
Prescaler: Prescaler is a block that presents inside the timer module and it is used to divide the clock frequency by a constant. It allows the timer to be clocked at the rate a user desires.
The PIC16F877A basically has three timer modules. These timer module terminals are also multiplexed with other functions for handling alternate functions. These three-timer modules as named as TIMER 0, TIMER 1 and TIMER 2. These modules help to perform various timer, Counter or PWM Generation.
Now, we have to learn deeper about these three Timer Modules.
The main features of Timer 0 is given below:
Timer 0 has a register called TMR0 Register, which is 8 bits of size. The below table shows the registers associated with PIC16f877A Timer 0 module.
[fusion_table fusion_table_type=”1″ fusion_table_rows=”” fusion_table_columns=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” class=”” id=”” animation_type=”” animation_direction=”left” animation_speed=”0.3″ animation_offset=””]
Register | Description |
---|---|
OPTION_REG | This registers is used to configure the TIMER0 Prescalar, Clock Source etc |
TMR0 | This register will hold the count value.When this register overflows (FF to 00) then an interrupt will be generated. |
INTCON | This register contains the Timer0 overflow flag(TMR0IF) and corresponding Interrupt Enable flag(TMR0IE). |
[/fusion_table]
RBPU: Not Applicable for Timers
INTEDG: Not Applicable for Timers
T0CS (TMR0 Clock Source Select bit)
1-Transition on T0CKI pin
0-Internal instruction cycle clock (CLKO)
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
PSA (Prescaler Assignment bit)
1-Prescaler is assigned to the WDT
0-Prescaler is assigned to the Timer 0
PS2:PS0 (Prescaler Rate Select bits)
Prescaler is not accessible but can be configured using PS2:PS0 bits of OPTION_REG.
GIE (Global Interrupt Enable bit)
1-Enables all unmasked interrupts
0-Disables all interrupts
PIE (Peripheral Interrupt Enable bit)
1-Enables all unmasked peripheral interrupts
0-Disables all peripheral interrupts
TMR0IE (TMR0 Overflow Interrupt Enable bit)
1-Enables the TMR0 interrupt
0-Disables the TMR0 interrupt
INTE (RB0/INT External Interrupt Enable Bit)
1-Enables the RB0/INT external interrupt
0-Disables the RB0/INT external interrupt
RBIE(RB Port Change Interrupt Enable Bit)
1-Enables the RB port change interrupt
0-Disables the RB port change interrupt
TMR0IF (TMR0 Overflow Interrupt Flag bit)
1-TMR0 register has overflowed (must be cleared in software)
0-TMR0 register did not overflow
INTF (RB0/INT External Interrupt Flag Bit)
1-RB0/INT External interrupt occurred(must be cleared in software))
0-RB0/INT External interrupt did not occur
RBIF (RB Port Change Interrupt Flag Bit)
1-At least one of the RB7 – RB4 pins changed state; a mismatch condition will continue to set line bit. Reading PORT B will end the mismatch condition and allow the bit to be cleared(must be cleared in software)
0-None of the RB7 – RB4 pins have changed state.
Working process to implement Timer 0
It is important to learn how time delay is calculated by the timer since the exact delay generation is the most common application of timer.
Example: Given that a time delay of 1 ms is to be generated and a 20MHz crystal oscillator is connected with PIC.
The timer is related to the internal frequency which is always Fosc/4.
Clock source frequency (Crystal)
Fosc = 20 MHz = 20000000 Hz
Therefore, Timer frequency :
Ftimer = Fosc / 4 = 20000000 / 4 = 5000000 Hz = 5 MHz
If Prescaler =1:32, then
Ftimer= 5000000 / 256 = 19531.25 Hz
So, the TMRO register value
= 256-((Delay * Fosc)/(Prescalar4))
= 256-((1ms * 20Mhz)/(32*4))
= 256-156=100
The values are reloaded again to start timer for same delay. Before filling this value timer registers should be configured as we shall see.
A simple program with 1 ms delay using Timer 0.
#include<pic.h> int Count=0; void main(void) { TMR0=0; //TMR0 Initiation T0CS=0; //Choosing to work with internal clk T0SE=0; //Reacting on Low2High edge PSA=0; //Choosing to work with a Prescaler PS0=1; PS1=1; //Prescaler value divides 256 PS2=1; while(1) { while(!T0IF); //Stays here 256 times and then T0IF=1 T0IF=0; //Resetting the overflow flag Count++; //Increasing by 1 if(Count==15) { Count=0; //when count reaches 15 - Resetting to 0 } } }
The main features of Timer 1 is given below:
Timer 1 has a register called TMR1 register, which is 16 bits of size. The below table shows the registers associated with PIC16f877A Timer 1 module.
Bit 7 and Bit 6 (unimplemented) : Read as ‘0’
T1CKPS1:T1CKPS0 (Timer1 Input Clock Prescale Select bits)
11 = 1:8 prescale value
10 = 1:4 prescale value
01 = 1:2 prescale value
00 = 1:1 prescale value
T1OSCEN (Timer 1 Oscillator Enable Control bit)
1-Oscillator is enabled
0-Oscillator is shut-off
T1SYNC (Timer 1 External Clock Input Synchronization Control bit)
1-Do not synchronize external clock input
0-Synchronize external clock input
TMR1CS (Timer 1 Clock Source Select bit)
1-External clock from pin RC0/T1OSO/T1CKI (on the rising edge)
0-Internal clock (FOSC/4)
TMR1ON (Timer 1 On bit)
1-Enables Timer 1
0-Stops Timer 1
Time delay is calculated by the timer 1 .
Example: Given that a time delay of 100 ms is to be generated and a 20MHz crystal oscillator is connected with PIC.
The timer is related to the internal frequency which is always Fosc/4.
Clock source frequency (Crystal)
Fosc = 20 MHz = 20000000 Hz
Therefore, Timer frequency :
Ftimer = Fosc / 4 = 20000000 / 4 = 5000000 Hz = 5 MHz
If Prescaler =1:8, then
Ftimer= 5000000 / 256 = 19531.25 Hz
So, the TMRO register value
= 65536-((Delay * Fosc)/(Prescalar4))
= 65536-((100ms * 20Mhz)/(8*4))
= 3036
Delay of 1 sec using Timer 1.
#include<pic.h> int Count = 0; void main (void) { T1CON = 0b00000001; while (1) { while (! TMR1IF); TMR1IF = 0; Count ++; if (Count == 15) { Count = 0; } } }
The main features of Timer 0 is given below:
PIC16F877A Timer 2 module registers are shown below:
TOUTPS3:TOUTPS0 (Timer 2 Output Postscale Select bits)
0000 = 1:1 postscale
0001 = 1:2 postscale
0010 = 1:3 postscale
•
•
1111 = 1:16 postscale
TMR2ON (Timer 2 On bit)
1-Timer 2 is on
0-Timer 2 is off
T2CKPS1:T2CKPS0 (Timer 2 Clock Prescale Select bits)
00 = Prescaler is 1
01 = Prescaler is 4
1x = Prescaler is 16
Generating 1 sec delay using Timer 2
Example: As the timer 2 is 8-bit and supports 1:16 prescaler, it is not possible to directly generate the delay of 1 sec. The max delay with 1:16 Prescaler will be:
Delay = 256 * (Prescaler*4)/Fosc
= 256 * 16*4/20Mhz
=819us
Now 500us can be generated using timers which will be used to increment a counter 2000 times to get 1 sec delay.
Delay Calculations for 500usec @20Mhz with Prescaler as 16:
Reg Value = 256-(Delay * Fosc)/(Prescalar*4))
= 256-((500us* 20Mhz)/(16*4))
= 256-156=100
#include<pic.h> int Count=0; void main(void) { T2CON=0b01111100; //T2CON Initiation TMR2=0; //Start value=0 PR2=0XFF; //Stop value=255 while(1) { while(!TMR2IF); //Program stay here till TMR2IF goes to "1" TMR2IF=0; //after TMR2IF goes to "1" - reset it Count++; //increase count by 1 if(Count==224) { Count=0; //if count reaches 244 - reset it } } }