Assignment title: Information
58
7 Lab 7 – Timer2 Module
7.1 Aim
This laboratory practical will introduce you to the Timer2 module which is one of three timer/counter
peripherals located on the PIC16F877A MCU. The practical exercises will focus on the proper
configuration and usage of the Timer2 module.
7.2 Learning Outcomes
After this laboratory practical you will:
• Understand the structure of the Timer2 module on the PIC16F877A.
• Be able to configure the Timer2 module using the appropriate special function registers.
• Be able to develop projects to utilise the Timer2 module in a range of applications.
7.3 Background
7.3.1 Introduction
Timer2 is one of three timer modules on board the PIC16F877A MCU. Like Timer0, it is an 8 bit timer
meaning that it is capable storing a maximum of 2 256 8 = counts per overflow. Figure 7-1 shows a
block diagram representation of the Timer2 module. Note the lack of external inputs from pins on the
device, Timer2 is driven by the internal instruction clock only. An important function of Timer2 is that
it is used to produce the timebase for the pulse-width modulation (PWM) modules, which is something
we will look at in section 10. In addition, the Timer2 module can provide the baud clock for the
synchronous serial port (SSP) module, although this is not something we will be considering further in
this work.
Figure 7-1 Timer2 block diagram
Timer2 operates in a fundamentally different manner to the Timer0 and Timer1 modules. Timer0 and
Timer 1 interrupt flags are set on overflow, so we must preload the relevant timer register to create
the required duration prior to an overflow. Timer2 does not set an interrupt flag on overflow, instead
it features a period register, PR2. When the current Timer2 count value, held in TMR2 register,
matches the value held in the period register then Timer2 self-resets (TMR2=0) and an interrupt flag,
TMR2IF is set. In this way, it is only necessary to calculate the required number of counts for a given 59
delay, and then load the period register, PR2 accordingly. Note that the interrupt flag TMR2IF is found
in the PIR1 peripheral interrupt flags SFR.
7.3.2 Timer2 configuration
Timer2 features both a prescaler and postscaler. The prescaler operates in precisely the same manner
as for the Timer0 and Timer1 moduled, it simply divides down the incoming clock frequency. The
postscaler divides down the number of matches with the period register, PR2 required to set the
interrupt flag, TMR2IF. The purpose of the postscaler is to reduce the overhead associated with
servicing interrupts.
Timer2 configuration is controlled by the T2CON register which provides for the setting of the
prescaler, postscaler and enables the module to be switched on and off. Figure 7-2 shows the structure
of the T2CON register bits.
Figure 7-2 T2CON register bits
The following tables summarise the bitfields in T2CON and how they relate to the configuration of the
Timer2 module. For the postscaler it should be apparent that the ratio is always the bitfield value of
TOUTPS + 1.
Table 7-1 Timer2 prescaler configuration
T2CKPS1:T2CKPS0 Bitfield Value Ratio
00 0 1:1
01 1 1:4
1X 2/3 1:16
Table 7-2 Timer 2 postscaler configuration
TOUTPS3:TOUTPS0 Bitfield Value Ratio
0000 0 1:1
0001 1 1:2
0010 2 1:3
⁞ ⁞ ⁞
1111 15 1:1660
To summarise, the bitwise configuration of T2CON (see figure 6-2) for the operation of Timer2 may be
considered as follows:
T2CON = XUUU U1UU
where X = a ‘don’t care’ state and U = a user defined state.
For instance to set up Timer2 with prescaler and postscaler values of 1:4 and 1:10 respectively we
need to write the following to value to T2CON (all don’t care states are set to zero here),
T2CON = 0100 1101 = 0x4D
In this instance the Timer2 module is enabled (turned on), and bitfields T2CKPS and TOUTPS are set
to 1 and 9 respectively to set the prescaler and postscaler values as stipulated.
Table 7-3 summarises the bit configuration requirements in the T2CON SFR
Table 7-3 Summary of bit configuration in T2CON
Bit Name Bit location in
T2CON
MPLAB XC8 syntax Configuration requirements
TOUTPS3:0 6:3 T2CONbits.T1CKPS Define as required by application
TMR2ON 2 T12CONbits.TMR1ON Set to 1 to enable Timer2 module
T2CKPS1:0 1:0 T2CONbits.T1OSCEN Define as required by application
7.3.3 Timer2 period register calculations
To configure Timer2 for a specific delay we need determine suitable prescale and postscale ratios and
then calculate a value with which to load the period register (PR2). Remember that Timer2 is a selfresetting timer, when the count value matches the value stored in PR2 we get a self-reset and the
TMR2IF interrupt flag is set.
The PR2 load value for a given delay can be calculated by the following formula.
delay
2
4 prescaler postscaler
fosc
PR = ´
´ ´
Both the prescaler and postscaler ratios operate to divide down the rate at which the TMR2IF interrupt
flag is set, hence their presence in the denominator. Remember the maximum value possible for PR2
is 255 because it is an 8 bit wide register.
For example if we wish to generate a 20 ms delay using the Timer2 module, and assume a prescaler
value of 1:16 and postscaler value of 1:8 then the following evaluation provides the PR2 load value.
delay 20 10 3.2768 10 3 6
2 128
4 prescaler postscaler 4 16 8
fosc
PR
-
´ ´ ´ ´
= = =
´ ´ ´ ´
The resulting configuration code required is then,
T2CONbits.T2CKPS = 2; // Set prescaler to 1:1661
T2CONbits.TOUTPS = 7; // Set postscaler to 1:8
PR2 = 128; // Setup period register
T2CONbits.TMR2ON = 1; // Turn Timer2 ON
Alternatively, the configuration can be done more efficiently by writing the T2CON SFR in a single shot
as follows,
T2CON = 0x3E; // TOUTPS bitfield = 7, T2CKPS bitfield = 2, TMR2ON = 1
PR2 = 128; // Load PR2 with 128
7.4 Procedure
7.4.1 Exercise 1 – Simple Timer2 delay example
Create a new project in the MPLAB X IDE, create an empty source file, and populate it with
the following code listing. This implements a 20 ms delay using the configuration outlined in
section 7.3.3.
// Filename: Lab7Ex1.c
// Version: 1.0
// Date:
// Author:
// Description: Implementing a Timer2 delay
#include // Required for all MPLAB XC8 source files
void main(void)
{
TRISB = 0x00; // Configure PORTB
PORTB = 0x00;
T2CON = 0x3E; // Timer2 ON, Prescaler 1:16, Postscaler 1:8
PR2 = 128;
while(1)
{
while(!PIR1bits.TMR2IF); // Delay
PORTB++;
PIR1bits.TMR2IF = 0; // Clear overflow flag
}
}
Build the project and upload the HEX file onto the PIC16F877A MCU.
Study the code listing carefully and observe what is happening. Comment on the operation
of the code, how is the delay being implemented?
Confirm the whether the expected 20 ms delay has been correctly generated by measuring
the total time for PORTB to count up to 256 in binary and then dividing that value accordingly
to get the duration for a single count.
Calculate the maximum delay possible with Timer2 using a single interrupt, assuming an
oscillator frequency of 3.2768 MHz.
7.4.2 Exercise 2 – Changing the delay length
Create a new project in the MPLABX IDE and create a 1 ms delay using the previous exercise
as a starting point. You will need to alter the prescaler, postscaler and period register values 62
to achieve this. Note that it is not possible to create delay of exactly 1 ms, however aim to
get as close as you can.
Calculate the percentage error for the exact delay you have created. You can do this my
rearranging the equation for calculating the PR2 value in terms of delay as follows,
4 prescaler postscaler 2
delay
osc
PR
f
´ ´ ´
=
The percentage error is then simply,
( )
3
3
1 10 delay
error % 100
1 10
-
-
æ ö ´ -
= ´ç ÷
è ø ´
This exercise illustrates the limitations of clock resolution in realtime embedded systems.
7.4.3 Exercise 3 – Creating a flexible delay function using Timer2
Create a new project in the MPLABX IDE and develop a configurable function which has a
single parameter that determines the integer number of seconds delay invoked. The function
prototype should have the following form:
void Timer2Delay(unsigned char);
The delay must be implemented using Timer2.