Файл: Microcontroller Programming. Thi Micro Chip PIC (Julio Sanchez, 2007).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 14.06.2025
Просмотров: 8520
Скачиваний: 0
Interrupts |
221 |
;============================
; Program flashes LED wired to Port-B, line 2 lights:
movlw |
b’00000010’ |
; Mask with bit 1 set |
xorwf |
portb,f |
; Complement bit 1 |
call |
long_delay |
; Local delay routine |
call |
long_delay |
|
call |
long_delay |
|
goto |
lights |
RB0 Interrupt Service Routine
The Service Routine for the RB0 interrupt depends on the specific application. Nevertheless, the following processing steps should be considered:
1.Determine if the source is an RB0 interrupt.
2.Clear the RB0 interrupt flag (INTF bit) in the INTCON Register.
3.Save the context. Which registers and variables need to be saved depends on the specific application.
4.Perform the interrupt action.
5.Restore the context.
6.Return from the interrupt with the retfie instruction.
In addition, the interrupt handler may have to perform operations that are specific to the application. For example, debounce a switch or initialize local variables. The following Interrupt Service routine is from the program RB0Int in the book’s online software:
;=======================================================
; |
Interrupt Service Routine |
;=======================================================
;Service routine receives control when there is
;action on pushbutton switch wired to port-B, line 0 IntServ:
;First test if source is an RB0 interrupt
btfss |
INTCON,INTF |
; INTF flag |
is RB0 interrupt |
goto |
notRB0 |
; Go if not |
RB0 origin |
; Save context |
|||
movwf |
old_w |
; Save w register |
|
swapf |
STATUS,w |
; STATUS to |
w |
movwf |
old_status |
; Save STATUS |
|
;=========================
;interrupt action ;=========================
;Debounce switch
;Logic:
;Debounce algorithm consists in waiting until the
;same level is repeated on a number of samplings of the
222 |
Chapter 11 |
;switch. At this point the RB0 line is clear since the
;interrupt takes place on the falling edge. The routine
;waits until the low value is read several times.
movlw |
D’10’ |
; |
Number of repetitions |
movwf |
count2 |
; |
To counter |
wait:
;Check to see that port-B bit 0 is still 0
;If not, wait until it changes
btfsc |
portb,0 |
; |
Is |
bit set? |
|
goto |
exitISR |
; |
Go |
if |
bit not 0 |
; At this point RB0 bit is clear |
|||||
decfsz |
count2,f ; |
Count |
this iteration |
||
goto |
wait |
; Continue if not zero |
|||
;Interrupt action consists of toggling bit 2 of
;port-B to turn LED on and off
movlw |
b’00000100’; Xoring with a 1-bit produces |
||
; |
the complement |
||
xorwf |
portb,f ; |
Complement bit |
2, port-B |
;=========================
;exit ISR ;========================= exitISR:
;Restore context
swapf |
old_status,w |
; Saved status to w |
|
movfw |
STATUS |
; To STATUS register |
|
swapf |
old_w,f |
; Swap file register in itself |
|
swapf |
old_w,w |
; re-swap back to w |
|
notRB0: |
|||
; Reset interrupt |
|||
bcf |
INTCON,intf |
; Clear INTCON bit 1 |
|
retfie |
|||
Note that the interrupt handler listed previously contains a debouncing routine that cleans the switch’s signal. In this particular implementation the detection of a signal of the wrong value determines that the interrupt is aborted. For the particular switch used in the test circuit this approach seemed to work better. Alternatively, the routine can be designed so that if a wrong edge is detected, execution continues in the wait loop. In any case, the entire complication of software debouncing can be avoided by debouncing the switch in hardware.
11.3.2 Wakeup from SLEEP Using the RB0 Interrupt
The PIC microcontroller sleep mode provides a useful mechanism for saving power. It is particularly useful in battery-operated devices.
The sleep mode is activated by executing the SLEEP instruction; it suspends all normal operations and switches of the clock oscillator.
Interrupts |
223 |
The sleep mode is suitable for applications that are not required to run continuously. For example, a device that records temperature at daybreak can be designed so that a light-sensitive switch generates an interrupt that turns the device on each morning. Once the data is recorded, the device goes into the sleep mode until the next daybreak.
Several events can make the device wake up from the sleep mode:
1.A device reset on the !MCLR pin
2.Watchdog timer wake-up signal, if WDT is enabled
3.Interrupt on RB0 line
4.Port change interrupt on RB4 to RB7 lines
5.EEPROM write complete interrupt
In the sleep mode, the device is placed on a power-down state that generates the lowest power consumption. The system clock is turned off in the sleep mode so signals that depend on the clock cannot be used to terminate the sleep. If enabled, the Watchdog Timer is cleared by the sleep instruction but keeps running. The PD bit in the STATUS register is also cleared and the TO bit is set. The ports maintain the status they had before the SLEEP instruction was executed.
The TO and PD bits in the STATUS register can be used to determine the cause of wake-up, since the TO bit is cleared if a Watchdog Timer wake-up took place. The corresponding interrupt enable bit must be set for the device to wake-up up due to an interrupt. Wake-up takes place regardless of the state of the General Interrupt Enable (GIE) bit. If the bit is clear, the device continues execution at the instruction following SLEEP. Otherwise, the device executes the instruction after the SLEEP instruction and then branches to the interrupt address. If the execution of the instruction following SLEEP is undesirable, the program should contain a NOP instruction after the SLEEP instruction.
The SleepDemo Program
The program named SleepDemo in the book’s online software package is a trivial demonstration of using the RB0 interrupt to wake the processor from sleep mode. The program can be tested using the circuit in Figure 11-4. SleepDemo flashes the green LED at ½ second intervals during 20 iterations and then goes into sleep mode. Pressing the pushbutton switch on line RB0 generates an interrupt that wakes the processor from sleep mode. The following code fragment shows the coding of the main loop in the program:
;============================
;flash LED 20 times ;============================ wakeUp:
;Program flashes LED wired to port-B, line 2
;20 times before entering the sleep state
movlw |
D’20’ |
; |
Number of iterations |
movwf |
count2 |
; |
To counter |
224 |
Chapter 11 |
|
lights: |
||
movlw |
b’00000010’; Mask with bit 1 set |
|
xorwf |
portb,f |
; Complement bit 1 |
call |
long_delay |
|
call |
long_delay |
|
call |
long_delay |
|
decfsz |
count2 |
; Decrement counter |
goto |
lights |
|
; 20 iterations have taken place |
||
clrwdt |
; Clear WDT |
|
sleep |
||
nop |
; Recommended! |
|
goto |
wakeUp |
; Resume execution |
In the SleepDemo program the Interrupt Service Routine does nothing. Its coding is as follows:
;=======================================================
;Interrupt Service Routine ;=======================================================
;The interrupt service routine performs no operation IntServ:
bcf |
INTCON,INTF |
; Clear flag |
retfie
The initialization of the RB0 interrupt is identical to the one in the RB0Int program previously listed.
11.3.3 Port-B Bits 4-7 Status Change Interrupt
In the PIC 16F84 microcontroller, a change of input signal on Port-B, lines 4 to 7, generates an interrupt. This interrupt sets the RBIF bit in the INTCON Register to indicate that at least one of the ports have changed value. The port change takes place when the port’s previous value changes from logic one to logic zero or vice versa. In order for port pins to recognize this interrupt, they must have been defined as input. If any one of the port pins (4 to 7) is defined as output the interrupt takes place. The status change of the ports is in reference to the last time port-B was read.
The principal application of this interrupt source is in detecting several different interrupt sources. Its principal disadvantage is that it forces the declaration of four port-B lines as input, although during processing not all lines need be recognized as interrupt sources. The conclusion is that applications that only need a single external interrupt source should use the RB0 interrupt described in previous sections. Only applications that require more than one external interrupt should use the Port-B lines 4 to 7 interrupt on change source.
Interrupts |
225 |
Since the interrupt takes place on any status change (high-to-low or low-to-high) the service routine executes on both signal edges. If interrupt processing is required on only one edge, that is, either when the port goes high or low, then the filtering must be performed in software. The circuit in Figure 11-5 allows testing the Port-B Status Change Interrupt.
+5 V |
+5 V |
4 MHz |
4.7K Ohm |
4.7K Ohm |
|||||||||||||||||||||||||||||||||||||
Osc |
+5 V |
||||||||||||||||||||||||||||||||||||||
16 |
15 |
14 |
10 |
||||||||||||||||||||||||||||||||||||
17 |
|||||||||||||||||||||||||||||||||||||||
18 |
13 |
12 |
11 |
||||||||||||||||||||||||||||||||||||
RA1 |
RA0 |
OSC1 OSC2 |
Vdd |
RB7 |
RB6 |
RB5 |
RB4 |
||||||||||||||||||||||||||||||||
green |
16F84 |
||||||||||||||||||||||||||||||||||||||
red |
RA2 |
T0Tkl |
|||||||||||||||||||||||||||||||||||||
RA3 |
MCLR Vss |
RB0/INT RB1 |
RB2 |
||||||||||||||||||||||||||||||||||||
RB3 |
|||||||||||||||||||||||||||||||||||||||
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
|||||||||||||||||||||||||||||||
2x470 Ohm
+5 V
10K Ohm
Figure 11-5 Circuit for Testing the Port-B Status Change Interrupt
In the circuit of Figure 11-5, a pushbutton switch is wired to the RB7 port and another one to RB4. Both of these switches produce the interrupt when pressed. A red LED is wired to port RA1 and a green LED to port RA0. The red and green LEDs are toggled on and off when the corresponding pushbutton switches are pressed. The switches contain a 4.7K Ohm resistor that keeps the port high until the contact is made and sent to ground. This makes both switches active low and the interrupt is programmed on the falling edge of the signal.
RB4-7 Interrupt Initialization
In order to initialize the RB4-7 change interrupt the following operations must take place:
1.Port-B lines 4 to 7 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.
226 |
Chapter 11 |
3.The RB port change interrupt flag (RBIF 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 RB port change interrupt must be enabled by setting the RBIE bit in the INTCON Register.
6.Internal pull-ups on port-B should be disabled in the OPTION register.
The following code fragment from the program RB4to7Int in the book’s online software package shows the required processing:
;=============================
;main program ;============================= main:
;Disable port-B internal pull-ups
;Interrupts on falling edge of pushbutton action
Movlw |
b’10111111’ |
||||||||
option |
|||||||||
; Wiring: |
|||||||||
; |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
<= port-B |
; |
| |
|_______________ red pushbutton |
|||||||
; |
|________________________ black pushbutton |
||||||||
; |
|||||||||
; |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
<= Port-A |
; |
| |
|_____ red LED |
|||||||
; |
|________ green LED |
||||||||
; |
|||||||||
movlw |
b’00000000’ |
; Set Port-A for ouput |
|||||||
tris |
porta |
||||||||
movlw |
b’11110000’ |
; Port-B bit 0-3 are output |
|||||||
; bits 4-7 are input |
|||||||||
tris |
portb |
; all others are output |
|||||||
clrf |
portb |
; All port-B to 0 |
|||||||
movlw |
b’00000000’ |
; Zero to w |
|||||||
movwf |
bitsB47 |
; Store in local variable |
|||||||
; Initially turn on LEDs |
|||||||||
bsf |
porta,0 |
; Set LEDs on line 0 |
|||||||
bsf |
porta,1 |
; and on line 1 |
|||||||
;============================
;setup interrupts ;============================
;Clear external interrupt flag (intf = bit 1)
bcf |
INTCON,rbif |
; Clear flag |
;Enable global interrupts (gie = bit 7)
;Enable RB0 interrupt (inte = bit 4)
bsf |
INTCON,gie |
; |
Enable |
global int (bit |
7) |
bsf |
INTCON,rbie |
; |
Enable |
RB0 int (bit 3) |