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.