Файл: Microcontroller Programming. Thi Micro Chip PIC (Julio Sanchez, 2007).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 14.06.2025
Просмотров: 8485
Скачиваний: 0
Interrupts |
217 |
Multiple External Interrupts
One of the practical applications of the port-B line-change interrupt is in handling several different interrupt sources; for example, a circuit containing four push-button switches that activate four different circuit responses. If the switches are wired to the corresponding pins in Port-B (RB4 to RB7) and the line-change interrupt is enabled, the interrupt takes place when any one of the four switches changes level, that is, when any one of the interrupt lines go from high to low or from low to high. The interrupt handler software can easily determine which of the switches changed state and if the change took place on the signal’s rising or falling edge. The corresponding software routines then handle each case.
Later in this chapter we develop a sample program that uses the Port-B line-change interrupt to respond to action on four pushbutton switches.
11.1.4 EEPROM Data Write Interrupt
The origin of this interrupt relates to the relative slowness of the EEPROM data write operation, which is of 10 ms. The interrupt serves no other function than to allow the microcontroller to continue execution while the data write operation is in progress. The interrupt service routine informs the microcontroller when writing has ended through the EEIF bit located in the EECON1 register. The use of this interrupt is considered in Chapter 15, in the context of EEPROM data memory access and programming.
11.2 Interrupt Handlers
The interrupt handler, also called the interrupt service routine or the ISR, is the code that receives control upon occurrence of the interrupt. Most of the programming that goes into the service routine is specific to the application; however, there are certain housekeeping operations that should be included. The following list describes the structure of an interrupt service routine for the mid-range PICs:
1.Preserve the value in the w register.
2.Preserve the value of the STATUS register.
3.Execute the application-specific operations.
4.Restore the value of the STATUS register at the time of the interrupt.
5.Restore the value of the w register at the time of the interrupt.
6.Issue the RETFIE instruction to end the interrupt handler.
In the PIC 16F84, the interrupt service routine must be located at offset 0x004 in code memory. A simple org directive takes care of ensuring this location, as in the following code fragment:
org |
0x000 |
; Beginning of code area |
|
goto |
start |
; |
Jump to program start |
org |
0x004 |
; |
Start of Service routine |
. |
|
. |
; SERVICE ROUTINE GOES HERE |
. |
218 |
Chapter 11 |
|
retfie |
; |
End of ISR |
start: |
; |
Program starts here |
Alternatively, code can place a jump at offset 0x004 and locate the Service Routine elsewhere in the code. In this case, it is important to remember not to call the Service Routine, but to access it with a goto instruction. The reason is that the call opcode places a return address in the stack, which then polls for the retfie instruction.
11.2.1 Context Saving Operations
The only value automatically preserved by the interrupt mechanism is PC (the Program Counter), which is stored in the stack. Applications often need to restore the processor to the same state as when the interrupt took place, so the first operation of most interrupt handlers is saving the processor’s context. This usually includes the w and the STATUS registers and occasionally others used by the specific implementation.
Saving w and STATUS Registers
Saving the w and the STATUS registers requires using register variables, but the process requires special care. Saving the w register is simple enough: its value at the start of the Service Routine is stored in a local variable from which it is restored at termination. But saving the STATUS register cannot be done with the MOVF instruction, since this instruction changes the zero flag. The solution is to use the SWAPF instruction which does not affect any of the flags. Of course, SWAPF inverts the nibbles in the operand, so it must be repeated so as to restore the original state. The following code fragment assumes that file register variables named old_w and old_status were previously created.
save_cntx: |
|||
movwf |
old_w |
; |
Save w register |
swapf |
STATUS,w ; STATUS to w |
||
movwf |
old_status |
; |
Save STATUS |
;
; Interrupt handler operations go here
; |
|
swapf |
old_status,w ; Saved status to w |
movfw |
STATUS ; To STATUS register |
;At this point all operations that change the
;STATUS register must be avoided, but swapf does not.
swapf |
old_w,f |
; |
Swap file register in itself |
swapf |
old_w,w |
; |
reswap back to w |
retfie |
11.3 Interrupt Programming
In the sections that follow, we discuss programming interrupts that originate in Port-B, line 0, and those that originate in changes of port-B lines RB4 to RB7. Interrupts that relate to the Timer0 overflow or to EEPROM data write operations are cov-
Interrupts |
219 |
ered in the chapter on Serial Communications and the one on EEPROM Data Operations, respectively.
11.3.1 Programming the External Interrupt
Port-B, line 0, is referred to as the External Interrupt source. The name is not the most adequate since other interrupts can also have external sources. One of the important uses of this interrupt source is to wake the processor from the SLEEP mode. This allows developing applications that can run on a small power source (such as batteries) since the program uses almost no power until some action associated with the interrupt source wakes up the PIC. A sample program using the RB0 interrupt is developed later in this chapter. Our first sample program is a simple demonstration of the installation and action of the interrupt. The program is based on the circuit in Figure 11-4.
2x470 Ohms |
|||||||||
4 MHz |
|||||||||
Osc |
|||||||||
green |
red |
||||||||
+5 V |
|||||||||
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
|
RA1 RA0 OSC1 OSC2 Vdd RB7 RB6 RB5 RB4
16F84
RA2 RA3 T0Tkl MCLR Vss RB0/INT RB1 RB2 RB3
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
+5 V
10K Ohms
4.7K Ohms
+5 V
Figure 11-4 Circuit for RB0 Interrupt Demonstration
In the circuit of Figure 11-4, a pushbutton switch is wired to the RB0 port. It is this switch which produces the interrupt when pressed. A red LED is wired to port RB1 and a green LED to port RB2. The main program flashes the green LED on and off at a rate of approximately one-half second. The red LED is toggled on and off when the pushbutton switch is pressed. The switch contains a 4.7K Ohm resistor that keeps the port high until the contact is made and sent to ground. This makes the
220 |
Chapter 11 |
switch active low and the interrupt is programmed on the falling edge of the signal, which takes place when the contact is made.
RB0 Interrupt Initialization
In order to initialize the RB0 interrupt, the following operations must take place:
1.Port-B, line 0, must be initialized for input.
2.The interrupt source must be set to take place either on the falling or the rising edge of the signal.
3.The external interrupt flag (INTF in the INTCON Register) must be initially cleared.
4.Global interrupts must be enabled by setting the GIE bit in the INTCON Register.
5.The External Interrupt on RB0 must be enabled by setting the INTE bit in the INTCON Register.
The following code fragment, from the program RB0Int in the book’s online software package, performs these operations:
;============================= ; interrupt handler ;=============================
org 0x04 goto IntServ
;=============================
;main program ;============================= main:
;Set up interrupt on falling edge
;by clearing OPTION register bit 6 movlw b’10111111’
option
movlw |
b’11111111’ |
; Set Port-A |
for input |
tris |
porta |
; (not necessary for this program) |
|
movlw |
b’00000001’ |
; Port-B bit |
0 is input |
tris |
portb |
; all others |
are output |
clrf |
portb |
; All Port-B |
to 0 |
; Initially turn on LED |
|||
bsf |
portb,0 |
; Set line 0 |
bit |
;============================ |
|||
;setup interrupts ;============================
;Clear external interrupt flag (intf = bit 1)
bcf |
INTCON,intf |
; Clear flag |
;Enable global interrupts (gie = bit 7)
;Enable RB0 interrupt (inte = bit 4)
bsf |
INTCON,gie |
; |
Enable |
global int (bit |
7) |
|
bsf |
INTCON,inte |
; |
Enable |
RB0 int (bit 4) |
||
;============================ |
||||||
; |
flash LED |
|||||