In this tutorial we are going to discuss the Timer module of Pic16f877a.
First we will see what are timers, their working and later we will configure the PIC16f877a timers to generate delay of 100ms and 500ms respectively. At the end we will see how to use the ExploreEmdedded Timer library.
Contents
Timer Basics
As the name suggests these are used to measure the time or generate the accurate time delay. The microcontroller can also generate/measure the required time delays by running loops, but the timer/counter relieves the CPU from that redundant and repetitive task, allowing it to allocate maximum processing time for other tasks.
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.
PIC Timer Module
Pic16f877a has three indepenndent timer which can be used as timer,Counters or for PWM generation.
Below table provides the details of the three Timers.
Timer | Size | Control Register | Count Register | Min Delay | Max Delay |
---|---|---|---|---|---|
TIMER0 | 8-bit | OPTION_REG | TMR0 | 0 | 0 |
TIMER1 | 16-bit | T1CON | TMR1H,TMR1L | 0 | 0 |
TIMER2 | 8-bit | T2CON | TMR2 | 0 | 0 |
Timer Calculation
PIC Oscillator frequency is divided by 4 and then fed to the controller, Now this this freq can be further divided by presacalar to generate the range of delays.
Time to increment the Timer count by one(timer tick) can be determined as below.
tick = (Prescalar/(Fosc/4)
tick = (Prescalar/(20Mhz/4))
$$tick = (Prescalar * 4)/Fosc$$
Now the Timer value for the required delay can be calculated as below.
Delay = TimerCount * tick
Count = (Delay/tick)
RegValue = TimerMax- Count
RegValue = TimerMax-(Delay/tick) = TimerMax - (Delay/((Prescalar *4)/Fosc))
$$RegValue = TimerMax-((Delay * Fosc)/(Prescalar*4))$$
Below table provides the formula for all the three Timers.
Timer | Size | Formula for delay calculation |
---|---|---|
TIMER0 | 8-bit | $$RegValue = 256-((Delay * Fosc)/(Prescalar*4))$$ |
TIMER1 | 16-bit | $$RegValue = 65536-((Delay * Fosc)/(Prescalar*4))$$ |
TIMER2 | 8-bit | $$RegValue = 256-((Delay * Fosc)/(Prescalar*4))$$ |
Timer 0
The timer TMR0 module is an 8-bit timer/counter with the following features:
- 8-bit timer/counter
- Readable and writable
- 8-bit software programmable prescaler
- Internal or external clock select
- Interrupt on overflow from FFh to 00h
- Edge select for external clock
Timer0 Registers
The below table shows the registers associated with PIC16f877A Timer0 module.
Register | Description |
---|---|
OPTION_REG | This registers is used to configure the TIMER0 Prescalar, Clock Source etc |
TMR0 | This register holds the timer count value which will be incremented depending on prescalar configuration |
INTCON | This register contains the Timer0 overflow flag(TMR0IF) and corresponding Inetrrupt Enable flag(TMR0IE). |
OPTION_REG | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
RBPU | INTEDG | T0CS | T0SE | PSA | PS2 | PS1 | PS0 |
RBPU: NA for Timers
INTEDG: NA 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 Timer0
PS2:PS0: Prescaler Rate Select bits
- Note:There is only one prescaler available which is mutually exclusively shared between the Timer0 module and the Watchdog Timer. A prescaler assignment for the Timer0 module means that there is no prescaler for the Watchdog Timer and vice versa. This prescaler is not accessible but can be configured using PS2:PS0 bits of OPTION_REG.
INTCON | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
GIE | PIE | TMR0IE | INTE | RBIE | TMR0IF | INTF | RBIF |
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: NA for Timers
RBIE: NA for Timers
TMR0IF: TMR0 Overflow Interrupt Flag bit
1-TMR0 register has overflowed (must be cleared in software)
0-TMR0 register did not overflow
INTF: NA for Timers
Delay Calculations for 1ms @20Mhz with Prescalar as 32: $$RegValue = 256-(Delay * Fosc)/(Prescalar*4)) = 256-((1ms * 20Mhz)/(32*4)) = 256-156=100$$
Code
Below are the steps for configuring and using the Timer0 for delay generation:
- Calculate the Timer Count for the required delay.
- Set the Presaclar bits in OPTION_REG as per the delay calculations.
- Clear the PSAbit for using the prescalar.
- Select the Clock Source Internal/External using TOCS bit.
- Load the timer value into TMRO register.
Below is the sample code to blink the LEDs with 1ms delay.
Delay measured using CRO:
Timer 1
The timer TMR1 module is an 16-bit timer/counter with the following features:
- 16-bit timer/counter with two 8-Bit register TMR1H/TMR1L
- Readable and writable
- software programmable prescaler upto 1:8
- Internal or external clock select
- Interrupt on overflow from FFFFh to 00h
- Edge select for external clock
Timer1 Registers
The below table shows the registers associated with PIC16f877A Timer1 module.
Register | Description |
---|---|
T1CON: | This registers is used to configure the TIMER1 Prescalar, Clock Source etc |
TMRIH | This register holds the higher 8-bits of timer value. TMR1H and TMR1L are used in pair to increment from 0000 - FFFFh |
TMRIL | This register holds the lower 8-bits of timer value. TMR1H and TMR1L are used in pair to increment from 0000 - FFFFh |
PIR1 | This register contains the Timer1 overflow flag(TMR1IF). |
PIE1 | This register contains the Timer1 Interrupt Enable flag(TMR1IE). |
T1CON | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
— | — | T1CKPS1 | T1CKPS0 | T1OSCEN | T1SYNC | TMR1CS | TMR1ON |
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: Timer1 Oscillator Enable Control bit
1-Oscillator is enabled
0-Oscillator is shut-off
T1SYNC: Timer1 External Clock Input Synchronization Control bit
1-Do not synchronize external clock input
0-Synchronize external clock input
TMR1CS: Timer1 Clock Source Select bit
1-External clock from pin RC0/T1OSO/T1CKI (on the rising edge)
0-Internal clock (FOSC/4)
TMR1ON: Timer1 On bit
1-Enables Timer1
0-Stops Timer1
Delay Calculations for 100ms @20Mhz with Prescalar as 8: $$RegValue = 65536-(Delay * Fosc)/(Prescalar*4)) = 65536-((100ms * 20Mhz)/(8*4)) = 65536-62500=3036 = 0xBDC$$
Code
Below are the steps for configuring and using the Timer0 for delay generation:
- Calculate the Timer Count for the required delay.
- Set the Presaclar bits in OPTION_REG as per the delay calculations.
- Clear the PSAbit for using the prescalar.
- Select the Clock Source Internal/External using TOCS bit.
- Load the timer value into TMRO register.
Below is the sample code to blink the LEDs with 1ms delay.
Delay measured using CRO: