workflow of timer1 in pic16f877a

PIC16F877A timer

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.

PIC16F877A timer Block Diagram

pic16f877a timer block diagram

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.

PIC16F877A timer modules

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.

TIMER 0

The main features of Timer 0 is given below:

  • 8-bit timer/counter with prescaler
  • Readable and Writable
  • Internal or external Clock set
  • Build 8-bit software programmable prescaler
  • Edge select for external clock
  • Interrupt on overflow from 0XFF to 0X00

Timer 0 Registers

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]

Structure of OPTION_REG :

option_reg

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)

timer prescaler rate select bits

Prescaler is not accessible but can be configured using PS2:PS0 bits of OPTION_REG.

Structure of INTCON :

intcon register in pic16f877a

 

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.

Work Flow of TIMER 0

Working process to implement Timer 0

workflow of timer0 in pic16f877a

  • Timer 0 can be operated both as a timer and counter.
  • The Timer 0 stores the value TMR0 registers
  • All the parts to the left are the clock source circuits.
  • T0CON (Timer 0 Control) register is used to program the timer and includes the bits shown in figure (T0CS, PSA etc.)
  • The clock source can be internal or external and is controlled by T0CS bit.
  • In some cases, the clock coming from the oscillator could be too fast for our applications: we can lower it by using the frequency prescaler.
  • The prescaler is a circuit that divides the signal frequency by 2, 4, 8, 16, …, 256.
  • The prescaler is activated by bit PSA. Prescaler value is written to TMR0 register.

Delay Calculation

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.

PIC16F877A timer0 firmware example

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

TIMER 1

The main features of Timer 1 is given below:

  • 16-bit timer/counter. It consists of two 8 bit (8+8) registers (TMR1H, TMR1L)
  • Readable and writable
  • Internal or External clock select.
  • 1,2,4,8 programmable Prescaler
  • External can be syn. or asyn.
  • Interrupt on overflow from FFFFh to 0000h
  • Second Crystal Permitted

TIMER 1 REGISTERS

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.

registers for timer1 in pic16f877a

Structure of T1CON :

timer1 in pic16f877a T1CON register - PIC16F877A timer

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

Work Flow of Timer 1

workflow of timer1 in pic16f877a

  • Timer 1 clock source(TMR1CS) bit is used to select the clock source.
  • If TMR1CS becomes 0, then the internal clock is given to the input of the timer peripheral. If we programmed on to 1, it will get the clock source from the external source. That external source can be T1CKI or a crystal oscillator.
  • When it can be a crystal oscillator, then T1OSC is logic one if it is enabled it will get the clock pulse from the crystal oscillator. If it is disabled it will get the clock pulse directly from the T1CKI pin.
  • Prescaler bit is used to divide the incoming clock any one of the factors(1,2,4,8)
  • T1SYNC bit is logic 1 it will not be synchronized. The external clock will not be synchronized with the internal oscillator clock. If TISYNC is 0, it will be synchronized and it will be given to the AND gate.
  • Another bit of the AND gate is TMR1 ON bit. If TMRI becomes 1 then the clock moves to the TMR1 register and it will become 0 the AND gate also becomes 0(TMR1 will not counting).

Delay Calculation

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

PIC16F877A timer1 firmware example

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

TIMER 2

The main features of Timer 0 is given below:

  • Two 8-bit registers (TMR2 and PR2)
  • Readable and Writable
  • A Prescaler and a Postscaler
  • Connected only to an internal clock – 4 MHz crystal
  • Interrupt on overflow

TIMER 2 REGISTERS

PIC16F877A Timer 2 module registers are shown below:

PIC16F877A timer2 registers

Structure of T2CON :

t2con register in pic16f877a

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

Work Flow of Timer 2

workflow of timer 2 pic16f877a - PIC16F877A timers

  • Get the clock from the FOSC/4 and then going to the Prescaler. The Prescaler divides the incoming clock frequency from some factors(it maybe 1,4,16)
  • Then this clock frequency is given to the TMR2 register, it will count the incoming clock pulse.
  • As it is counting the incoming clock pulses the value present in the TMR2 register is also compared with PR2 register.
  • If TMR2 and PR2 register are equal, the output of the comparator will reset the TMR2 register.
  • Then this equal output is given to the input of the Postscaler. It is not generated an interrupt immediately.
  • When the Postscaler bit obtains any of the value, it will generate some delay and TMR2 Interrupt Flag bit set.

Delay Calculation

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

PIC16F877A timer2 firmware example

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