Timers and interrupts

Document Sample
Timers and interrupts Powered By Docstoc
					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

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

DrTony Nicol - University of Central Lancashire Department of Computing.   121

                              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

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.

DrTony Nicol - University of Central Lancashire Department of Computing.   122
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.

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.

DrTony Nicol - University of Central Lancashire Department of Computing.   123
                       PS2-PS0                   TMR0Rate                    WDT Rate
                          000                        1:2                      1:1
                          001                        1:4                      1:2
                          010                        1:8                      1:4
                          011                        1:16                     1:8
                          100                        1:32                     1:16
                          101                        1:64                     1:32
                          110                        1:128                    1:64
                          111                        1:256                    1:128

                                Figure 27 Prescaler division ratios

                        Figure 28 - Prescaler configuration options

DrTony Nicol - University of Central Lancashire Department of Computing.              124
Example to generate a timer overflow of 1 millisecond
when CLKOUT = 400ns
To get 1mS we need to delay the clock by                                                 = 2500. The
                                                                             400 109
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        /     256       =    9.765625
2500        /     128       =    19.53125
2500        /     64        =    39.0625
2500        /     32        =    78.125
2500        /     16        =    156.25
2500        /     8         =    312.5
2500        /     4         =    625
2500        /     2         =    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.

DrTony Nicol - University of Central Lancashire Department of Computing.                      125
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. Don’t 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
     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.

DrTony Nicol - University of Central Lancashire Department of Computing.   126
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

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.

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
DrTony 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 Re-
enable 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.

   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.

   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:

DrTony Nicol - University of Central Lancashire Department of Computing.   128
                                                            Figure 29 Multiplexed 7 segment displays

 DrTony Nicol - University of Central Lancashire Department of Computing.              129
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.

 DrTony Nicol - University of Central Lancashire Department of Computing.   130
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.

DrTony Nicol - University of Central Lancashire Department of Computing.   131
Interrupt Control Register
Bit7          Bit6           Bit5           Bit4           Bit3          Bit2   Bit1   Bit0
R/W-          R/W-           R/W-           R/W-           R/W-          R/W-   R/W-   R/W-
0             0              0              0              0             0      0      x
          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

DrTony Nicol - University of Central Lancashire Department of Computing.             132
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 PORTB’s 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 OR’ed together to
generate the RB port change interrupt.

DrTony Nicol - University of Central Lancashire Department of Computing.   133
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

DrTony Nicol - University of Central Lancashire Department of Computing.   134
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                      ;   Swap nibbles in STATUS_TEMP register
                                          ;   and place result into W
MOVWF STATUS                              ;   Move W into STATUS register
                                          ;   (sets bank to original state)
SWAPF W_TEMP, F                           ;   Swap nibbles in W_TEMP and place
                                          ;   result in W_TEMP
SWAPF W_TEMP, W                           ;   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.

DrTony Nicol - University of Central Lancashire Department of Computing.   135

Shared By: