Файл: 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)