Sunteți pe pagina 1din 15

Using the Counter / Timers

This is probably the most complicated area of the microcontroller as there are 3 timers on the PIC16F877 (only 1 on the 84) and they have several modes of operation: Timer0: 8-bit timer/counter with 8-bit prescaler Timer1: 16-bit timer/counter with prescaler whichcan be incremented during sleep via an external crystal/clock Timer2: 8-bit timer/counter with 8-bit period register, prescaler and postscaler
Timer0

This timer is very neatly summarised in Figure 26. It can be configured to: Count system clock periods at 1/4 of input clock frequency. Useful for accurate timing such as precise delays Count at a rate of various factors of the system clock using the prescaler. Prescaler extends the range of the timer to enable longer time periods Count pulses on portA bit 4 on either rising or falling edges. Useful for input pulses from a car wheel for example Can generate an interrupt on count overflow. This enables the application and the timer to run concurrently

DrTony Nicol - University of Central Lancashire Department of Computing.

121

Microcontrollers

Figure 26 - PIC timer configuration

All the status bits associated with the various timer modes are shown on this diagram. It is simply a case of setting the appropriate control bits in order to select the required mode. For example, for the timer to count pulses on bit 4 of portA, TOSE is set to a 1 for falling edge (XOR will invert) and 0 for rising edge clocking. TOCS is set to a 1 and PSA is set to 1 and that's it. The timer register can be read when required or wait until timeout by polling T0IF or use interrupt. The T0IF bit is found in the INTCON register illustrated on page 132. If you want to count to 1010, for example, load the counter with 25610-1010=24610 and the counter will overflow (FF to 00) after counting 10 pulses and set the T0IF bit to indicate that this has happened. The counter timer can be used to count pulses from the system clock or external pulses from pin RA4. When counting system clock pulses it is generally used as a timer as the period of the clock is known. For example, if the system oscillator is 20MHz then the clock pulses (Fosc/4) are 20,000,000 / 4 = 5MHz which causes the counter to increment every 200nS.

DrTony Nicol - University of Central Lancashire Department of Computing.

122

Microcontrollers
The EasyPIC boards have a system clock of 8MHz so the timer is incremented at a rate of 500ns. The clock pulses would need to be steered to the counter by clearing the T0CS bit and the PSA bit in the OPTION register. However, as the clock is so fast and the timer is only an 8 bit device, the maximum time period it could produce would be 256 x 200ns = 51.2 uS. (or 256 x 500ns = 128us on the EasyPIC). To increase the length of the period, use the prescaler.

Prescaler
The prescaler is basically a counter which enables access to any single output bit based on the setting of PS0 to PS2. Using a counter in this way, it acts as a programmable divider. It can be used to either divide the number of pulses going to timer0 or divide the watchdog (discussed later) clock to enable longer timeouts. How the prescaler fits in with things is well illustrated in Figure 28. Bits PS0 to PS2 are used to select the required output from the prescaler counter using the 8 channel multiplexor. For example, if PS0 = 0, PS1 = 0 and PS2 = 0 then channel 0 is selected and bit 0 of the prescaler counter is selected so the output from the prescaler has twice the period (half the frequency) of the clock entering it. If at the other extreme, PS0 = 1, PS1 = 1 and PS2 = 1 then bit 8 of the prescaler counter is selected so the output is 28 times longer than the input i.e. a reduction in frequency of 256. See figure Figure 27 on page 124 for all the division ratios.

DrTony Nicol - University of Central Lancashire Department of Computing.

123

Microcontrollers
PS2-PS0
000 001 010 011 100 101 110 111

TMR0Rate
1:2 1:4 1:8 1:16 1:32 1:64 1:128 1:256

WDT Rate
1:1 1:2 1:4 1:8 1:16 1:32 1:64 1:128

Figure 27 Prescaler division ratios

Figure 28 - Prescaler configuration options

DrTony Nicol - University of Central Lancashire Department of Computing.

124

Microcontrollers
Example to generate a timer overflow of 1 millisecond when CLKOUT = 400ns
To get 1mS we need to delay the clock by
1103 400 109

= 2500. The

prescaler only works in multiples of 2 (division of 2, 4, 8, 16, 32, 64, 128 r 256) so we need two factors of 2500 where one is a multiple of 2. So: 2500 2500 2500 2500 2500 2500 2500 2500 / / / / / / / / 256 128 64 32 16 8 4 2 = = = = = = = = 9.765625 19.53125 39.0625 78.125 156.25 312.5 625 1250

As the prescaler and counter are integer devices, we need to choose two integer factors. Unfortunately, the only two combinations producing two integers are 4 x 625 and 2 x 1250 so the prescaler would need to be set to 4 and the timer set to count 625 or the prescaler set to 2 and the counter set to count to 1250. But, the counter is only 8 bits so can count up to a maximum of 256 so neither of these combinations is acceptable.

DrTony Nicol - University of Central Lancashire Department of Computing.

125

Microcontrollers
It is necessary to reach a compromise. Looking at the list of factors, the one which loses least accuracy after truncation is 39.0625 so we will use the factors 64 for the prescaler and 39 for the timer. This will actually give us a division of 39x64=2496 instead of 2500 so the counter will timeout after 2496 x 400 x 10-9 = 0.9984 milliseconds instead of 1 milliseconds. This may or may not be accurate enough depending on the application. Dont forget, there will be some timing overhead when calling and returning from a function and reading the timer overflow bit and in reloading this counter so the inaccuracy may be slightly less. The procedure (with reference to Figure 28) is as follows: Clear T0IF as we will be looking for this to go to a 1 after a millisecond Load the timer with 256 39 so it counts 39 clocks. Clear PSA to divert clock pulses to the prescaler instead of them going straight to the timer Set PS0 to PS2 to 5 (divide by 64) ie in binary 101 Clear T0CS to enable system clocks through to the prescaler and roughly 1mS later the T0IF flag will be set. Your code would monitor T0IF and when it becomes a 1, 1mS has elapsed. Clear T0IF, reload the counter, do what you wanted to do after 1mS then monitor the T0IF again. A more efficient way to do this is to use interrupts which are discussed in the next section. An example program follows:
Timers 1 and 2

These are similar to timer 0 with some additional features which are not discussed here. Timer 1 is a 16 bit timer.
DrTony Nicol - University of Central Lancashire Department of Computing.

126

Microcontrollers
Watchdog
The watchdog uses its own oscillator and by default times out after 18ms and unless the device is in sleep mode, it will cause a processor reset. Timeout periods of up to 2.3 seconds can be achieved by using the prescaler. However, if the prescaler is used, it is not available for timer0. The watchdog is reset with a CLRWDT instruction. The watchdog is used as a safety measure. If enabled, the software continually resets it using a CLRWDT instruction before it times out. If a program runs wild say electrical interference has caused it to execute a jump instruction so the program is now executing the wrong sequence, the loop that periodically resets the watchdog timer is probably no longer executing so the timer times out which causes a reset and the program jumps back into the correct program sequence from start-up.

Multiplexing
As discussed in the timer section, multiplexing enables the combining and extracting of a sequence of data. It is often used in microprocessor based systems to drive segmented displays. For example, if a 7 segment display is to be driven from a port, all 8 bits would be required (7 for the segments and one for the decimal point). If the port bit is a logic 1, Current will flow out of a port bit into the Anode of the LED, through the LED, out of the cathode and down to ground and the LED will light up. If all 8 port bits are a 1, all 7 segments and the decimal point will be lit. A problem occurs when more than one display is required. Say you require 4 displays; this would occupy 32 port bits which required a large microcontroller with lots of ports. To save on port bits, the displays can be multiplexed. This means that all corresponding
DrTony Nicol - University of Central Lancashire Department of Computing.

127

Anodes of all displays are connected together and driven by the same 8 port bits. The problem here is that when you output a number to the displays, all displays will show the same number. The solution is to disconnect the common cathodes of all the displays and enable them through control of a port bit. This way, by using 4 extra port bits we can enable any one of the 4 displays. The sequence is: Enable display 0, write a number to it. Disable display 0 and enable display 1 and write a number to it. Disable display 1 and enable display 2, write a number to it and the same for display 3. Then Reenable display 0, refresh the number then refresh display 1 then 2 etc. So at any one time there is only one number visible but if the sequencing is fast enough the eye cannot tell that there is only one number lit and it looks like there are 4 numbers. Advantages: only one display is lit at any one time so power consumption is less. Only 8 port bits plus one for each display are needed so there is a reduction in the size and cost of the microcontroller. For example, 6 discrete displays would need 6x8 = 48 port bits whereas a multiplexed system would need 8 + 6 = 14 port bits. Complexity and cost of wiring the board are reduced. Disadvantages: Code is more complex Displays need switching devices such as transistors so board size and component costs increase. EasyPIC3 implements its displays as illustrated in the following diagram:

DrTony Nicol - University of Central Lancashire Department of Computing.

128

Figure 29 Multiplexed 7 segment displays

DrTony Nicol - University of Central Lancashire Department of Computing.

129

Interrupts
What are they?
An interrupt stops the normal sequencing of a program to perform a subroutine (function call). When the subroutine completes, the program picks up the sequence from the position it was interrupted. Consider what happens when reading a book and the phone rings: save current position by bending page corner answer phone return phone receiver pick up book & read from previous position

The phone call gets higher priority (usually) than the main task otherwise the caller will ring off assuming you are out. You could choose to ignore the call or disconnect the phone; this is the equivalent of disabling interrupts on the processor. For a processor to respond to an interrupt, interrupts must be enabled. It is also possible that the phone call is interrupted by the doorbell. The same options are open: ignore it or suspend the current interrupt to service one of a higher priority (i.e. the phone caller knows you are in but the person at the door doesn't. If you want to speak with the person at the door then they will be given priority). Finish with the person at door & return to phone with "where were we? Once finished return to book with "where was I"...

How do they work?


You may need your program to respond to an event. This is often when something happens outside of the processor which needs to be dealt with as soon as possible. E.g. character received at serial port needs to be read before the next one comes in and overwrites it.

DrTony Nicol - University of Central Lancashire Department of Computing.

130

Interrupts
Overview of interrupts on the PIC16F8x
When an interrupt is requested, if interrupts are enabled, the program counter position of the next instruction will be saved on the stack, the program counter will be loaded with 0004 and GIE is disabled to avoid interrupts interrupting the interrupt. Location 4 is where the next instruction will be executed; this is the interrupt vector. The instruction at location 4 is either the start of the interrupt service routine or is a jump instruction to the interrupt service routine (ISR). The PIC 16F84 has four interrupt sources whereas the PIC16F877 has 14 so not all of them are covered here but an overview is provided to cover the concept. The interrupt register INTCON is used to enable and detect some of the interrupt sources. When a device causes an interrupt condition e.g. timer0 times out, the interrupt bit is set in INTCON. The interrupt will only trigger if that interrupt is enabled and global interrupts are enabled. Note: the interrupt flags need to be cleared in software to avoid continual interrupts. Because there is only one interrupt vector, the ISR needs to determine what it was that caused the interrupt. This is done by reading the INTCON and other interrupt register bits if implemented, to find out which bit is set. Using this information, the function effectively has a switch statement that switches on interrupt type to perform the appropriate code. At the end of the interrupt routine, a RETFI instruction is executed (return from interrupt). This causes the stack value to be popped into the program counter so returns to the part of the program that was interrupted. It also re-enabled the global interrupt enable bit.

DrTony Nicol - University of Central Lancashire Department of Computing.

131

Interrupts
Interrupt Control Register

Bit7 R/W0 GIE

Bit6 R/W0

Bit5 R/W0

Bit4 R/W0

Bit3 R/W0

Bit2 R/W0

Bit1 R/W0

Bit0 R/Wx

EEIE T0IE INTE RBIE T0IF INTF RBIF R = Readable bit W = Writable bit - n = Value at reset
Table 7 - Interrupt Control register (INTCON) bit allocations

Interrupt enable bits

Bit 7: GIE: Global Interrupt Enable bit 1 = Enables all un-masked interrupts 0 = Disables all interrupts Bit 6: EEIE: EE Write Complete Interrupt Enable bit 1 = Enables the EE write complete interrupt 0 = Disables the EE write complete interrupt Bit 5: T0IE: TMR0 Overflow Interrupt Enable bit 1 = Enables the TMR0 interrupt 0 = Disables the TMR0 interrupt Bit 4: INTE: RB0/INT Interrupt Enable bit 1 = Enables the RB0/INT interrupt 0 = Disables the RB0/INT interrupt Bit 3: RBIE: RB Port Change Interrupt Enable bit 1 = Enables the RB port change interrupt 0 = Disables the RB port change interrupt

DrTony Nicol - University of Central Lancashire Department of Computing.

132

Interrupts
Interrupt flag bits

Interrupt flag bits are set when an interrupt condition occurs. Bit 2: T0IF: TMR0 overflow interrupt flag bit 1 = TMR0 has overflowed (must be cleared in software) 0 = TMR0 did not overflow The TMR0 interrupt is generated when the TMR0 register overflows from FFh to 00h. This overflow sets the T0IF bit. The interrupt can be masked by clearing enable bit T0IE (INTCON B5). The T0IF bit must be cleared in software by the Timer0 Module interrupt service routine before re-enabling this interrupt. Bit 1: INTF: RB0/INT Interrupt Flag bit 1 = The RB0/INT interrupt occurred 0 = The RB0/INT interrupt did not occur Port B bit 0 can be used as a general external interrupt pin like the 8086 int pin (discussed later). Bit 0: RBIF: RB Port Change Interrupt Flag bit 1 = When at least one of the RB7:RB4 pins changed state 0 = None of the RB7:RB4 pins have changed state Four of PORTBs pins, RB7:RB4, have an interrupt on change feature. Only pins configured as inputs can cause this interrupt to occur (i.e., any RB7:RB4 pin configured as an output is excluded from the interrupt on change comparison). The pins' value in input mode are compared with the old value latched on the last read of PORTB. The mismatch outputs of the pins are ORed together to generate the RB port change interrupt.

DrTony Nicol - University of Central Lancashire Department of Computing.

133

Interrupts
The EEPROM interrupt flag EEIF is in the EECON1 register on the PIC16F84 but it is in the PIR2 register on the PIC16F877. When the EEPROM write cycle is complete this flag is set. If the interrupt is enabled (Bit 6 of INTCON) and global interrupts are enabled then the interrupt will trigger.

Handling interrupts
As the PIC (and typical microcontrollers) tend to only have a single interrupt vector so it is necessary for the interrupt routine to determine what actually caused the interrupt. The interrupt control register (INTCON) records individual interrupt requests in flag bits. It also contains the individual and global interrupt enable bit. The global interrupt enable bit, GIE (INTCON B7) enables (if set) all un-masked interrupts or disables (if cleared) all interrupts. Individual interrupts can be disabled through their corresponding enable bits in INTCON register. Bit GIE is cleared on reset. The return from interrupt instruction, RETFIE, exits the interrupt routine as well as sets the GIE bit, which re-enable interrupts. When an interrupt is responded to; the GIE bit is cleared to disable any further interrupt, the return address is pushed onto the stack and the PC is loaded with 0004h. Once in the interrupt service routine the source(s) of the interrupt can be determined by testing the interrupt flag bits. The interrupt flag bit(s) must be cleared in software before re-enabling interrupts to avoid infinite interrupt requests.

DrTony Nicol - University of Central Lancashire Department of Computing.

134

Interrupts
An important difference between the handling of interrupts on typical microprocessors such as the 8086 is that the PIC does not save the CPU status flags. As an interrupt can occur at any time these flags should be saved by the programmer as the instruction following the interrupted instruction may be dependent on the flags at that point. As it is not implemented in hardware it should be done in software.
Example of saving the status register during interrupt MOVWF W_TEMP ; Copy W to TEMP register, SWAPF STATUS, W ; Swap status to be saved into W MOVWF STATUS_TEMP ; Save status to STATUS_TEMP register : ; Interrupt Service Routine : ; should configure Bank as required : ; SWAPF STATUS_TEMP, W MOVWF STATUS SWAPF W_TEMP, F SWAPF W_TEMP, W ; ; ; ; ; ; ; ; Swap nibbles in STATUS_TEMP register and place result into W Move W into STATUS register (sets bank to original state) Swap nibbles in W_TEMP and place result in W_TEMP Swap nibbles in W_TEMP and place result into W

It is not a good idea to simply copy the status register with a mov instruction as the mov instruction affects a status bit of the register you are moving. i.e. simply copying the status register can change its contents so there is little point in saving it in the first place. However, if the swapf instruction is used, the contents of the status register may be copied into w without affecting the status bits. The saved contents are swapped back to the correct value when the status register is restored at the end of the interrupt routine.

DrTony Nicol - University of Central Lancashire Department of Computing.

135

S-ar putea să vă placă și