Assignment title: Information


51 6 Lab 6 – Timer1 Module 6.1 Aim This laboratory practical will introduce you to the Timer1 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 Timer1 module in timer mode only. 6.2 Learning Outcomes After this laboratory practical you will: • Understand the structure of the Timer1 module on the PIC16F877A. • Be able to configure the Timer1 module using the appropriate special function registers. • Be able to develop projects to utilise the Timer1 module in a range of applications. 6.3 Background 6.3.1 Introduction Timer1 is one of three timer modules on board the PIC16F877A MCU. It is a 16 bit timer meaning that it is capable storing a maximum of 2 65536 16 = counts per overflow. Compare this to the 8 bit Timer0 module which can only provide 2 256 8 = counts per overflow. Figure 6-1 Timer 1 module block diagram Figure 6-1 shows block diagram representation of the Timer1 module. Timer1 has shares several similar features with Timer0. There is a prescaler available for use, however the maximum divide down ratio is 1:8 (compared with a maximum of 1:256 for Timer0). There is also a Timer1 overflow interrupt which utilises the TMR1IE and TMR1IF bits that can be found in the PIE1 and PIR1 registers respectively. TMR1IF can be polled to check for the occurrence of Timer1 overflows. The process for doing this is similar to that used in Lab 4, where TMR0IF bit was polled to check for a Timer0 overflow. The Timer1 module can act as a counter whereby the count value increases with every occurrence of a rising edge of an external clock input supplied to pin connected to PORTC bit 0 (RC0). There is also an option to connect a low frequency crystal oscillator to provide a lower power timer facility that continues to operate even when the MCU is in sleep mode. In this laboratory practical we will be considering the use of the Timer1 module in timer mode only. In this case the count value is continuously updated at the instruction clock rate, f f CY OSC = / 4. As 52 such, the formulae for calculating count intervals and overflow periods are exactly the same as for Timer0, except for the changes available prescaler ratios and the larger maximum count capacity, which is now 65536. 4 prescaler 1count delay osc TMR f ´ ´ = delay 1count 4 prescaler fosc TMR = ´ ´ 6.3.2 Timer1 configuration The configuration bits relating to the Timer1 module can be found in the T1CON (Timer1 CONtrol) register (see figure 6-2). Figure 6-2 T1CON register bits To use the clock as a timer sourced from the internal instruction clock the TMR1CS bit needs to be set to zero. It is also necessary to configure the prescaler using the T1CKPS bitfield. Finally, the timer must be started by setting the TMR1ON bit. All other bits can safely assume a 'don't care' state and thus may be set to zero. Note that bits 6 and 7 are unused and can be set to zero in the interests of consistency. Table 6-1 Prescaler configuration T1CKPS1:T1CKPS0 Bitfield Value TMR1 Rate 00 0 1:1 01 1 1:2 10 2 1:4 11 3 1:853 Table 6-2 TIMER1CON summary of bit configuration Bit Name Bit location in T1CON MPLAB XC8 syntax Configuration requirements T1CKPS1:0 5:4 T1CONbits.T1CKPS Define as required by application T1OSCEN 3 T1CONbits.T1OSCEN No effect in timer mode (don't care state) T1SYNC 2 T1CONbits.T1SYNC No effect in timer mode (don't care state) TMR1CS 1 T1CONbits.TMR1CS Set to 0 to enable internal clock source (timer mode) TMR1ON 0 T1CONbits.TMR1ON Set to 1 to enable timer To summarise, the bitwise configuration of T1CON (see figure 6-2) for the operation of timer 1 in timer mode may be considered as follows: T1CON = XXUU XX0U where X = a 'don't care' state and U = a user defined state. For instance to set up Timer1 to provide a prescaler value of 1:4 we need to write the following to value to T1CON (all don't care states are set to zero here), T1CON = 0010 0000 = 0x20 In this instance the Timer1 module is configured but still currently disabled (turned off). 6.3.3 Timer1 preload calculation Remember that the maximum number of counts the 16 bit Timer1 module can make before overflowing is 65536. For example, if a 100 ms delay is required, with the prescaler divide down ratio set to 1:8, then the required number of TMR1 counts is as follows. delay 100 10 3.2768 10 3 6 1count 10240 4 prescaler 4 8 fosc TMR - ´ ´ ´ ´ = = = ´ ´ When 10240 counts of the Timer1 module have occurred, we know that 100 ms have elapsed. If we are going to use the overflow polling to measure the delay, then the preload value required is then simply preload 65536 TMR1count = - which for the example cited above equates to a preload value of 55296. 6.3.4 Procedure for loading Timer 1 Timer1 is a 16 bit timer module which means it requires 16 bits to store its count value. However, because the PIC16f877A MCU has an 8-bitarchitecture, the maximum data register width is only 8 bits 54 (1 byte) wide. This means that two SFRs are required to hold the 16 bit count value. These are separated into the high (TMR1H) and low (TMR1L) bytes, which must be loaded individually. Timer1 should be disabled to this two stage load process to ensure proper operation. The procedure is as follows: Convert the required preload value into hexadecimal. Turn Timer1 OFF (T1CONbits.TMR1ON=0). Take the leftmost two digits (most significant byte) and load into the TMR1H SFR. Take the rightmost two digits (least significant byte) and load that value into the TMR1L SFR. Turn Timer1 ON (T1CONbits.TMR1ON=1). For a preload value of 55296 (see section 6.3.3) the hexadecimal notation is 0xD800. So we can write the following code to load Timer1: T1CONbits.TMR1ON = 0; // Turn Timer 1 OFF TMR1H = 0xD8; // Load high byte TMR1L = 0x00; // Load low byte T1CONbits.TMR1ON = 1; // Turn Timer 1 ON 6.4 Procedure 6.4.1 Exercise 1 – Simple Timer1 delay example Create a new project in the MPLAB X IDE, create an empty source file, and populate it with the following code listing. // Filename: Lab6Ex1.c // Version: 1.0 // Date: // Author: // // Description: Implementing a Timer1 delay #include // Required for all MPLAB XC8 source files void main(void) { TRISB = 0x00; // Configure PORTB PORTB = 0x00; T1CON = 0x30; // Timer1 OFF, Prescaler 1:8 while(1) { T1CONbits.TMR1ON = 0; // Turn Timer 1 OFF TMR1H = 0x9C; // Load high byte TMR1L = 0x00; // Load low byte T1CONbits.TMR1ON = 1; // Turn Timer 1 ON while(!PIR1bits.TMR1IF); // Delay PORTB++; PIR1bits.TMR1IF = 0; // Clear overflow flag } }55 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? Calculate the delay time created using the Timer1 preload value in the example code. Confirm the result of your calculation 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. Look through the PIC16F877A datasheet and locate the section describing the contents of the PIR1 SFR. Copy the information into your logbook and note the location of the Timer1 overflow interrupt flag in the SFR. Calculate the maximum delay possible using a single overflow of Timer1 assuming an oscillator frequency of 3.2768 MHz. 6.4.2 Exercise 2 – Creating a short delay using Timer1 Calculate the parameters required to create a 1 second delay using Timer 0. You should determine a suitable preload value which, when combined with an integer number of overflows, will produce the required delay. 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 Timer1Delay(unsigned char); The delay must be implemented using Timer1. You may find it useful to review your solution to section 4.4.4 in which you completed a similar exercise involving the creation of a configurable delay function using Timer0. In addition, the flowchart shown in figure 6-3 may be a useful aid to help you develop your code. Configure T1CON Start TMR1IF==1? Finish Configure Ports Start Timer1Delay() Toggle LED NO YES while YES NO56 Figure 6-3 Flowchart showing one possible implementation for the Timer1Delay() function 6.4.3 Exercise 3 – Validating the operation of your Timer1 delay function Validate the operation of your new function by creating suitable test code which calls the function and measure the delays created. To achieve this, the test code should toggle an LED of your choice on one of the E-Block boards. The implementation of your code should be similar to that shown in figure 6-4. The flowchart symbol denotes a subroutine (function) call. In this case it represents a call to the function you developed in the previous exercise. The symbol is a display symbol which represents the display of information to the user. In this case the toggling of the LED is considered to be the information. Writing output to the LCD would be another example of a display process. Figure 6-4 Flowchart for Timer1Delay() function testing Confirm that the function works correctly for delays of 1, 2 and 5 second delays. Make sure you provide evidence of the results in your logbook. 6.4.4 Exercise 4 – Applying a configurable delay function to create a simple stopwatch The aim of this exercise is to develop create a simple stopwatch using the LCD and the configurable delay function you developed in the previous exercise. Create a new project in the MPLAB X IDE. The project should be developed to provide the following functionality: • Display on the LCD an elapsed time in the form mm:ss where mm and ss are the current count in minutes and seconds respectively. • The elapsed time displayed on the LCD should update automatically once per second. Start the design process by developing a flow chart. It may take a few iterations to come up with a suitable design. Upload the following HEX file to the MCU to observe the correct operation of your code: J:/Embedded Systems/MPLAB/Examples/SimpleStopwatch.hex Configure T1CON Start TMR1IF==0? Finish Configure Ports Start Timer1Delay() Toggle LED YES NO while(1) loop Configure Ports Start Timer1Delay() Toggle LED Timer1Delay() Toggle LED O while(1) loop Configure T1CON Start TMR1IF==1? Finish Configure Ports Start Timer1Delay() Toggle LED Timer1Delay() Toggle LED NO YES while(1) loop YES NO57 6.4.5 Exercise 5 – Adding functionality to the stopwatch Create another new project in MPLAB X and further develop the code created in section 6.4.4 to add the following functionality: • The initial state of the stopwatch when the code executes should be displaying 00:00 and be stopped. • The operation of the stopwatch is toggled by pressing RD0. Pressing RD0 once will start the stopwatch. Pressing RD0 a second time will stop operation. This operation should be repeatable. • The stopwatch can be reset at any time to pressing the switch connected to RD1. Once reset the stopwatch should revert to the initial state i.e. stopped and displaying 00:00.