
- •Table of Contents
- •Preface
- •Additional Material
- •Basic Electronics
- •1.0 The Atom
- •1.1 Isotopes and Ions
- •1.2 Static Electricity
- •1.3 Electrical Charge
- •1.4 Electrical Circuits
- •1.5 Circuit Elements
- •1.6 Semiconductors
- •Number Systems
- •2.0 Counting
- •2.1 The Origins of the Decimal System
- •2.2 Types of Numbers
- •2.3 Radix Representations
- •2.4 Number System Conversions
- •Data Types and Data Storage
- •3.0 Electronic-Digital Machines
- •3.1 Character Representations
- •3.2 Storage and Encoding of Integers
- •3.3 Encoding of Fractional Numbers
- •3.4 Binary-Coded Decimals (BCD)
- •Digital Logic, Arithmetic, and Conversions
- •4.0 Microcontroller Logic and Arithmetic
- •4.1 Logical Instructions
- •4.2 Microcontroller Arithmetic
- •4.3 Bit Manipulations and Auxiliary Operations
- •4.4 Unsigned Binary Arithmetic
- •4.5 Signed Binary Arithmetic
- •4.6 Data Format Conversions
- •Circuits and Logic Gates
- •5.0 Digital Circuits
- •5.1 The Diode Revisited
- •5.2 The Transistor
- •5.3 Logic Gates
- •5.4 Transistor-Transistor Logic
- •5.5 Other TTL Logic Families
- •5.6 CMOS Logic Gates
- •Circuit Components
- •6.0 Power Supplies
- •6.1 Clocked Logic and Flip-flops
- •6.2 Clocks
- •6.3 Frequency Dividers and Counters
- •6.4 Multiplexers and Demultiplexers
- •6.5 Input Devices
- •The Microchip PIC
- •7.0 The PICMicro Microcontroller
- •7.1 PIC Architecture
- •Mid-range PIC Architecture
- •8.0 Processor Architecture and Design
- •8.1 The Mid-range Core Features
- •8.2 Mid-Range CPU and Instruction Set
- •8.3 EEPROM Data Storage
- •8.4 Data Memory Organization
- •8.5 Mid-range I/O and Peripheral Modules
- •PIC Programming: Tools and Techniques
- •9.0 Microchip’s MPLAB
- •9.1 Integrated Development Environment
- •9.2 Simulators and Debuggers
- •9.3 Programmers
- •9.4 Engineering PIC Software
- •9.5 Pseudo Instructions
- •Programming Essentials: Input and Output
- •10.0 16F84A Programming Template
- •10.1 Introducing the 16F84A
- •10.2 Simple Circuits and Programs
- •10.3 Programming the Seven-segment LED
- •10.4 A Demonstration Board
- •Interrupts
- •11.0 Interrupts on the 16F84
- •11.1 Interrupt Sources
- •11.2 Interrupt Handlers
- •11.3 Interrupt Programming
- •11.4 Sample Programs
- •Timers and Counters
- •12.0 The 16F84 Timer0 Module
- •12.1 Delays Using Timer0
- •12.2 Timer0 as a Counter
- •12.3 Timer0 Programming
- •12.4 The Watchdog Timer
- •12.5 Sample Programs
- •LCD Interfacing and Programming
- •13.0 LCD Features and Architecture
- •13.1 Interfacing with the HD44780
- •13.2 HD44780 Instruction Set
- •13.3 LCD Programming
- •13.4 Sample Programs
- •Communications
- •14.0 PIC Communications Overview
- •14.1 Serial Data Transmission
- •14.2 Parallel Data Transmission
- •14.4 PIC Protocol-based Serial Programming
- •14.5 Sample Programs
- •Data EEPROM Programming
- •15.0 PIC Internal EEPROM Memory
- •15.1 EEPROM Devices and Interfaces
- •15.2 Sample Programs
- •Analog to Digital and Realtime Clocks
- •16.0 A/D Converters
- •16.1 A/D Integrated Circuits
- •16.2 PIC On-Board A/D Hardware
- •16.3 Realtime Clocks
- •16.4 Sample Programs
- •Index

Chapter 11
Interrupts
An interrupt is an asynchronous signal calling for processor attention. Interrupts can originate in hardware or in software. The interrupt mechanism is a way to avoid wasting processor time, since without interrupts code has to poll hardware devices in ineffective, closed loops. With interrupts, the processor can continue to do its work since the interrupt mechanism ensures that the CPU receives a signal whenever an event occurs that requires its attention. PIC microcontrollers provide varying levels of support for interrupts. We focus on interrupts on the 16F84.
11.0 Interrupts on the 16F84
Four different sources of interrupts are available in the 16F84. These are discussed in Section 11.1. One instruction (RETFIE for return-from-interrupt) is specifically related to interrupt processing. Its purpose is to return to the program counter the address of the instruction that follows the location in code where the interrupt took place. It does so by loading into the program counter register the 13-bit address saved at the top of the stack. In addition, RETFIE sets the Global Interrupt Enable bit in the INTCON register (discussed in Section 11.0.1) automatically re-enabling interrupts.
In addition to the RETFIE instruction, two PIC hardware elements relate directly to interrupts: the OPTION register and the INTCON register. Both registers are readable and writeable and contain bits that allow setting up, controlling, and detecting the various interrupts. INTCON records individual interrupt requests in flag bits. It also contains the individual and global interrupt enable bits. The OPTION register has several bits that must be accessed in order to initialize interrupts.
11.0.1 The Interrupt Control Register
INTCON (the Interrupt Control Register) is a readable and writeable register located at offset 0x08 in bank 0. The INTCON register contains two classes of bits: bits to enable and disable the various interrupt sources, and flag bits that allow detecting the occurrence of the various interrupts. The bits to enable and disable interrupts have names that end with the letter E, while the interrupt flag bit names end with the letter F. They are known collectively as the INTCON E and INTCON F bits. Figure 11-1 is a bitmap of the INTCON Register.
211
212 |
Chapter 11 |
bit 7 |
|
|
|
|
|
|
bit 0 |
|
|
|
|
|
|
|
|
GIE |
EEIE |
TOIE |
INTE |
RBIE |
TOIF |
INTF |
RBIF |
|
|
|
|
|
|
|
|
bit 7 GIE: Global Interrupt Enable bit
1 |
= |
Enables all unmasked interrupts |
0 |
= |
Disables all interrupts |
bit 6 EEIE: EE |
Write Complete Interrupt Enable bit |
|
1 |
= |
Enables the EE Write Complete interrupts |
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 Interrupt Enable bit |
||
1 |
= |
Enables the RB0 external interrupt |
0 |
= |
Disables the RB0 external interrupt |
bit 3 RBIE: Port Change Interrupt Enable bit |
||
1 |
= |
Enables the RB port change interrupt |
0 |
= |
Disables the RB port change interrupt |
bit 2 T0IF: TIMER0 Overflow Interrupt Flag bit |
||
1 |
= |
TMR0 register has overflowed |
0 |
= |
TMR0 register did not overflow |
bit 1 INTF: RB0 External Interrupt Flag bit |
||
1 |
= |
The RB0/INT external interrupt occurred |
0 |
= |
The RB0/INT external interrupt did not |
|
|
occur |
bit 0 RBIF: RB0-RB3 Port Change Interrupt Flag bit |
||
1 |
= |
At least one of the RB7:RB4 pins changed |
|
|
state |
0 |
= |
None of the RB7:RB4 pins have changed |
|
|
state |
Figure 11-1 INTCON Register Bitmap
11.0.2 The OPTION Register
The OPTION Register is a readable and writeable register that contains controls for configuring the prescaler bits and assigning them to either TIMER0 or the Watchdog Timer, for selecting the increment mode on the RA4/TOCKI pin, the TIMER0 source clock, the rising or falling edge in the RB0 interrupt, and for enabling and disabling the internal Port-B’s pull-up resistors. The OPTION register is located in Bank1, at address 0x81. Although this register is not directly related to interrupts, several of its bits are related to the various interrupts. Figure 11-2 is a bitmap of the OPTION register.
Interrupts |
213 |
bit 7 |
|
|
|
|
|
|
|
bit 0 |
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INTEDG |
TOCS |
TOSE |
RBIE |
|
PS2 |
|
PS1 |
|
PS0 |
|
|
RBPU |
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
Prescaler bits |
|
|
||||
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|||||
bit 7 RBPU: Port B Pull-up Enable bit |
|
|
|
|
|
|||||||||
1 |
= Port B pull-ups are disabled |
|
|
|
||||||||||
0 |
= Port B pull-ups are enabled by individual |
|||||||||||||
|
|
|
|
port latch values |
|
|
|
|
|
|
|
|||
bit 6 INTEDG: Interrupt Edge Select bit |
|
|
|
|
|
|||||||||
1 |
= Interrupt on rising edge of RB0 |
|
|
|
||||||||||
0 |
= Interrupt on falling edge of RB0 |
|
|
|
||||||||||
bit 5 T0CS: TMR0 Clock Source Select bit |
|
|
|
|
|
|||||||||
1 |
= Transition on RA4/T0CKI pin |
|
|
|
||||||||||
0 |
= Internal instruction cycle clock (CLKOUT) |
|||||||||||||
bit 4 T0SE: TMR0 Source Edge Select bit |
|
|
|
|
|
|||||||||
1 |
= Increment on high-to-low transition on |
|||||||||||||
|
|
|
|
RA4/T0CKI pin |
|
|
|
|
|
|
|
|||
0 |
= Increment on low-to-high transition on |
|||||||||||||
|
|
|
|
RA4/T0CKI pin |
|
|
|
|
|
|
|
|||
bit 3 PSA: Prescaler Assignment bit |
|
|
|
|
|
|
|
|||||||
1 |
= Prescaler is assigned to the Watchdog Timer |
|||||||||||||
0 |
= Prescaler is assigned to the Timer0 module |
|||||||||||||
bit 2-0 PS2:PS0: Prescaler Rate Select bits |
|
|
|
|||||||||||
|
|
|
Value |
Timer0 Rate |
|
|
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 11-2 OPTION Register Bitmap
11.1 Interrupt Sources
The 16F8X supports four different sources of interrupt:
1.External interrupt detected by line 0 of Port-B
2.Interrupts that originate in the timer (TMR0 overflow interrupt)
3.Interrupts that originate in changes of lines RB7 to RB4 in Port-B
4.EEPROM complete data write interrupt
214 |
Chapter 11 |
11.1.1 Port-B External Interrupt
This external interrupt is triggered by either the rising or falling signal edge on port-B, line 0. Whether it is the rising or the falling edge of the signal depends on the setting of the INTEDG bit of the OPTION register.
The Port-B interrupt is useful in detecting and responding to external events; for example, in measuring the frequency of a signal or in responding with some PIC action to a change in the state of a hardware device. This interrupt can be disabled by clearing the corresponding bit in the INTCON register. If enabled, once the interrupt takes place, code must clear the corresponding flag bit before re-enabling the interrupt.
Suppose there is a circuit that contains an emergency switch that is activated by some critical event. One possible approach is to check the state of the switch by continuously polling the port to which it is wired. But in a complex program it may be difficult to ensure that the switch polling routine is called with sufficient frequency so that an emergency event is detected immediately. A more effective solution is to connect the emergency switch to line number 0 of Port-B and set up the Port-B external interrupt source. Now, whenever the emergency switch is activated, the program immediately responds via the interrupt mechanism. Furthermore, once the interrupt code has been developed and debugged it continues to function correctly no matter what changes are made to the rest of the program.
11.1.2 Timer0 Interrupt
The 16F84 is equipped with a special timer module, named Timer0, which serves both as a timer and as a counter. The Timer0 module, which is discussed in greater detail in Chapter 12, consists of an 8-bit readable register operated by an internal or external clock and attached to an 8-bit programmable prescaler. The prescaler is used to delay the timer by dividing the previous clock signal. The timer0 module can be set up to interrupt on overflow. In this case, an interrupt is generated whenever the counter goes from 0xff to 0x00.
The Timer0 counter interrupt can be used to measure events and to respond to elapsed periods. For example, the timer is used to measure events by determining the number of timer interrupts that have taken place since an event occurred. The timer of each interrupt is determined from the processor clock speed and the prescaler set up. The event time is calculated by multiplying the time of each interrupt by the number of interrupts that have occurred. In this case, the interrupt routine increments a counter register that is accessible to code anywhere in the program; so the actual count can be reset from inside or outside the service routine.
In responding to an elapsed period, the Timer0 interrupt service routine not only keeps track of the time elapsed since the event, but also tests for a certain counter value that represents the desired time limit. Once the timer counter reaches this pre-set limit, the service routine responds directly with the required action.
Interrupts |
215 |
One powerful and common application of a Timer0 interrupt is in implementing serial communications. In this case, the timer interrupt is set up to take place at the baud rate at which the serial line is polled for data or at which individual data bits are sent. The sample program LapseTmrInt, developed in Chapter 12, demonstrates this use of the timer interrupt.
11.1.3 Port-B Line Change Interrupt
The third 16F84 interrupt source relates to a change in the values stored in Port-B lines 4 to 7. When this interrupt is enabled, any change in status in any of the four Port-B pins labeled RB7, RB6, RB5, and RB4 can trigger an interrupt. The interrupt is set up to take place when their status changes from logic one to logic zero, or vice versa. For this interrupt to take place, Port-B pins 4 to 7 must be defined as input. Otherwise, the interrupt does not take place.
The Port-B line-change interrupt provides a mechanism for monitoring up to four different interrupt sources, typically originating in hardware devices. When the interrupt is enabled, the current state of the Port-B lines is constantly compared to the old values. If there is a change in state in any of the four lines the interrupt is generated.
Implementation of the line change interrupt is not without complications. The characteristics of the external signal are necessary to develop code that correctly handles the various possible sources. Two pieces of information that are necessary in this case are:
1.The signal’s rising and falling edges
2.The pulse width of the interrupt trigger
The signal’s rising and falling edges determine the service routine’s entry point. For example, if the device is an active-low pushbutton switch, an interrupt typically is desired on the signal’s falling edge, that is, when it goes from high-to-low.
Knowledge about the signal’s width determines the processing required by the service routine. This is due to the fact that both the rising and the falling edge of the signal can trigger the interrupt. So, if the triggering signal has a small pulse width compared to the time of execution of the interrupt handler, then the interrupt line has returned to the inactive state before the service routine completes and a possible false interrupt on the signal’s falling edge is not possible. On the other hand, if the pulse width of the interrupt signal is large and the service routine completes before the signal returns to the inactive state, then the signal’s falling edge can trigger a false interrupt. Figure 11-3 (in the following page) shows both situations.
In the context of Figure 11-3, the period between the edge that triggers the interrupt and the termination of the interrupt handler is called the mismatch period. The mismatch period terminates when the service routine completes and the corresponding interrupt is re-enabled. If this happens after the interrupt signal is reset, no possible false interrupt takes place and no special provision is required in the handler. In fact, the interrupt handler runs correctly as long as the service routine takes longer to execute than the interrupt frequency. However, if the handler termi-

216 |
Chapter 11 |
nates before the signal returns to its original state, then the handler must make special provisions to handle a possible false interrupt. In order to do this, the handler must first determine if the interrupt took place on the rising or the falling signal edge, which can be done by examining the corresponding port-B line. For example, if the interrupt is to take place on the rising edge only, and the line is low, then it can be ignored since it takes place on the falling edge.
CASE 1: relatively small pulse width
Signal |
|
|
|
|
||
Raising edge |
|
|
|
|
|
Service routine complete |
|
|
|
|
|||
|
|
|
|
|||
|
|
|
|
|||
triggers interrupt |
|
|
|
Interrupt flag clear |
||
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
No possible false interrupt |
|
|
|
|
|
|
|
|
|
|
Interrupt handler |
|||
|
|
|
progress |
CASE 2: relatively large pulse width
Signal
Falling edge can trigger Raising edge false interrupt
triggers interrupt
Service routine complete Interrupt handler Interrupt flag cleared
in progress
Figure 11-3 Signal Pulse Width and Interrupt Latency
When an interrupt can take place on either the rising or the falling edge of the triggering signal, the interrupt source must have a minimum pulse width in order to ensure that both edges are detected. In this case, the minimum pulse width is the maximum time from the edge that triggered the interrupt to the moment when the interrupt flag is cleared. Otherwise, the interrupt is lost since the interrupt mechanism is disabled at the time it takes place.
The preceding discussion leads directly to the possibility of an interrupt taking place while the service routine of a previous interrupt is still in progress. These are called reentrant or nested interrupts. Several things must happen to allow reentrant interrupts. One of them is that interrupts must be re-enabled before the handler terminates. In addition, the service routine must be able to create different instances of the variables in use, usually allocated in the stack. The lack of a pro- gram-accessible stack and the PIC interrupt mechanism itself forces the conclusion that reentrant interrupts should not be attempted in PIC programs.