Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Microcontroller Programming. Thi Micro Chip PIC (Julio Sanchez, 2007).pdf
Скачиваний:
475
Добавлен:
12.08.2013
Размер:
4.99 Mб
Скачать

Interrupts

229

Processing by the interrupt service routine is straightforward. The code first determines which line caused the interrupt and takes the corresponding action in each case. In either case, the handler waits until all pushbuttons have been released before returning from the interrupt. This serves to debounce the switches.

11.4 Sample Programs

The following programs demonstrate the programming discussed in this chapter.

11.4.1 The RB0Int Program

;File: RB0Int.ASM

;Date: April 22, 2006

;Author: Julio Sanchez

;Processor: 16F84A

;Description:

;Program to test interrupt on port RB0

;A pushbutton switch is connected to port RB0.

;The pushbutton toggles a LED on port-B, line 2

;Another LED on port-B, line 1, flashes on and off

;at 1/2 second intervals ;===========================

;switches

;===========================

; Switches used in __config directive:

;

 

_CP_ON

Code protection ON/OFF

; *

_CP_OFF

 

;

*

_PWRTE_ON

Power-up timer ON/OFF

;_PWRTE_OFF

;

_WDT_ON

Watchdog timer ON/OFF

 

; * _WDT_OFF

 

 

 

;

_LP_OSC

Low power crystal

occilator

 

; * _XT_OSC

External parallel

resonator/crystal oscillator

;

_HS_OSC

High speed crystal resonator (8 to

10 MHz)

;

 

Resonator: Murate

Erie CSA8.00MG =

8 MHz

;

_RC_OSC

Resistor/capacitor oscillator (simplest, 20%

error)

;|

;|_____ * indicates setup values

;========================= ; setup and configuration ;=========================

processor 16f84A include <p16f84A.inc>

__config _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF ;=====================================================

230

 

Chapter 11

;

variables in PIC RAM

;=====================================================

; Local variables

 

cblock

0x0d

; Start of block

J

 

; counter J

K

 

; counter K

count1

 

; Auxiliary counter

count2

 

; ISR counter

old_w

 

; Context saving

old_STATUS ; Idem

endc

 

 

;========================================================

;

m a i n

p r o g r a m

;========================================================

org

0

; start at address 0

goto

main

 

;

;============================= ; 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

 

 

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)

 

;============================

Interrupts

231

;flash LED ;============================

;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

 

call

long_delay

 

call

long_delay

 

goto

lights

 

;=======================================================

;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

;Make sure that interrupt occurred on the falling edge

;of the signal. If not, abort handler

btfsc

PORTB,0

;

Is

bit set?

goto

exitISR

;

Go

if clear

;=========================

;interrupt action ;=========================

;Debounce switch

;Logic:

;Debounce algorithm consists in waiting until the

;same level is repeated on a number of samplings of the

;switch. At this point the RB0 line is clear since the

;interrupt takes place on the falling edge. An initial

;short delay makes sure that spikes are ignored.

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

232

; port-B to turn LED on and off movlw b’00000100’

xorwf PORTB,f ;=========================

;exit ISR ;========================= exitISR:

;Restore context

swapf old_STATUS,w movfw STATUS

swapf old_w,f swapf old_w,w

; Reset,interrupt notRB0:

Chapter 11

;Xoring with a 1-bit produces

;the complement

;Complement bit 2, port-B

;Saved STATUS to w

;To STATUS register

;Swap file register in itself

;re-swap back to w

bcf INTCON,INTF ; Clear INTCON bit 1

retfie ;=======================

;Procedure to delay

;10 machine cycles ;======================= delay:

movlw

D’4’

; Repeat 12 machine cycles

movwf

count1

; Store value in counter

repeat

 

 

decfsz

count1,f

; Decrement counter

goto

repeat

; Continue if not 0

return

 

 

;=============================

;long delay sub-routine

;(for debugging) ;============================= long_delay

 

movlw

D’200’ ; w = 200 decimal

 

movwf

J

; J = w

jloop:

movwf

K

; K = w

kloop:

decfsz

K,f

; K = K-1, skip next if zero

 

goto

kloop

 

 

decfsz

J,f

; J = J-1, skip next if zero

 

goto

jloop

 

 

return

 

 

 

end

 

 

11.4.2 The SleepDemo Program

;File: SleepDemo

;Date: April 25, 2006

Interrupts

233

; Author: Julio Sanchez

;Processor: 16F84A

;Description:

;Program to use the External Interrupt on port RB0

;to terminate the power-down state caused by the

;SLEEP instruction. A pushbutton switch is connected to

;port RB0. The pushbutton generates the interrupt that

;ends the SLEEP conditions.

;Demonstration:

;A LED on port-B, line 1, flashes on and off at 1/2

;second intervals for 20 iterations. At that time the

;program enters the SLEEP condition. Pressing the

;pushbutton switch on line RB0 generates the interrupt

;that ends the SLEEP.

;===========================

;switches ;===========================

;Switches used in __config directive:

;

 

_CP_ON

Code protection ON/OFF

; *

_CP_OFF

 

;

*

_PWRTE_ON

Power-up timer ON/OFF

;_PWRTE_OFF

;

_WDT_ON

Watchdog timer ON/OFF

 

; * _WDT_OFF

 

 

 

;

_LP_OSC

Low power crystal

occilator

 

; * _XT_OSC

External parallel

resonator/crystal oscillator

;

_HS_OSC

High speed crystal resonator (8 to

10 MHz)

;

 

Resonator: Murate

Erie CSA8.00MG =

8 MHz

;

_RC_OSC

Resistor/capacitor oscillator (simplest, 20%

error)

;|

;|_____ * indicates setup values

;=========================

 

; setup and configuration

 

;=========================

 

 

processor 16f84A

 

 

include

<p16f84A.inc>

 

 

__config

_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

;=====================================================

;

variables in PIC RAM

;=====================================================

; Local variables

 

 

 

cblock

0x0d

; Start of block

 

J

 

; counter J

234

 

Chapter 11

K

 

; counter K

count1

 

; Auxiliary counter

count2

 

; Second auxiliary counter

old_w

 

; Context saving

old_STATUS ; Idem

endc

 

 

;========================================================

;

m a i n

p r o g r a m

;========================================================

org

0

; start at address 0

goto

main

 

;

;============================= ; 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

 

 

 

 

movlw

b’00000001’

; Port-B bit

0 is input

tris

PORTB

;

all

others

are output

clrf

PORTB

;

All

port-B

to 0

;============================

;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 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

Interrupts

 

235

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,f ; Decrement counter

goto

lights

 

; 20 iterations have taken place

 

sleep

 

 

nop

 

; Recommended!

goto

wakeUp

; Resume execution

;=======================================================

;Interrupt Service Routine ;=======================================================

;The interrupt service routine performs no operation IntServ:

 

bcf

INTCON,INTF

; Clear flag

 

retfie

 

 

;=============================

 

;

long delay sub-routine

 

;=============================

 

long_delay

 

 

 

movlw

D’200’ ; w = 200 decimal

 

movwf

J

; J = w

jloop:

 

 

 

movwf

K

; K = w

kloop:

 

 

 

decfsz

K,f

; K = K-1, skip next if zero

 

goto

kloop

 

 

decfsz

J,f

; J = J-1, skip next if zero

 

goto

jloop

 

 

return

 

 

end

11.4.3 The RB4to7Int Program

;File: RB4to7Int.ASM

;Date: April 26, 2006

;Author: Julio Sanchez

;Processor: 16F84A

;Description:

;Program to test the port-B, bits 4 to 7, STATUS

236

Chapter 11

;change interrupt. Pushbutton switches are connected

;to port-B lines 4 and 7. A red LED is wired to port

;RA1 and a green LED to port RA0. The pushbuttons

;generate interrupts that toggle a LEDs on and off. ;===========================

;switches

;===========================

; Switches used in __config directive:

;

 

_CP_ON

Code protection ON/OFF

; *

_CP_OFF

 

;

*

_PWRTE_ON

Power-up timer ON/OFF

;_PWRTE_OFF

;

_WDT_ON

Watchdog timer ON/OFF

 

; * _WDT_OFF

 

 

 

;

_LP_OSC

Low power crystal

occilator

 

; * _XT_OSC

External parallel

resonator/crystal oscillator

;

_HS_OSC

High speed crystal resonator (8 to

10 MHz)

;

 

Resonator: Murate

Erie CSA8.00MG =

8 MHz

;

_RC_OSC

Resistor/capacitor oscillator (simplest, 20%

error)

;|

;|_____ * indicates setup values

;========================= ; set up and configuration ;=========================

 

processor 16f84A

 

 

include

<p16f84A.inc>

 

__config

_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

;=====================================================

;

variables in PIC RAM

;=====================================================

; Local variables

 

 

 

cblock

0x0d

; Start of block

 

J

 

; counter J

 

K

 

; counter K

 

count1

 

; Auxiliary counter

 

count2

 

; ISR counter

 

old_w

 

; Context saving

 

old_STATUS ; Idem

 

bitsB47

 

; Storage for previous value

 

 

 

; in port-B bits 4-7

 

temp

 

; Temporary storage

 

endc

 

 

;========================================================

; m a i n p r o g r a m

Interrupts

 

237

;========================================================

org

0

; start at address 0

goto

main

 

;

 

 

;=============================

; interrupt handler

;=============================

org

0x04

goto IntServ

;=============================

;main program ;============================= main:

;Disable port-B internal pullups

;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

;============================

;set up 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)

 

;============================

 

 

 

 

;

flash LED

 

 

 

 

238

Chapter 11

;============================

;Main program does nothing. All action takes place in

;Interrupt Service Routine

lights:

nop

goto lights

;=======================================================

;

Interrupt Service Routine

;=======================================================

;Service routine receives control whenever any of

;port-B lines 4 to 7 change state

IntServ:

; First test: make sure source is an RB4-7 interrupt

btfss

INTCON,RBIF

; RBIF flag is interrupt

goto

notRBIF

; Go if not RBIF origin

; Save context

 

 

movwf

old_w

; Save w register

swapf

STATUS,w ; STATUS to w

movwf

old_STATUS

; Save STATUS

;=========================

;interrupt action ;=========================

;The interrupt occurs when any of Port-B bits 4 to 7

;have changed STATUS.

movf

PORTB,w

; Read Port-B bits

movwf

temp

; Save reading

xorwf

bitsB47,f

;

Xor with old bits,

 

 

;

result in f

; Test each meaningful bit (4 and 7 in this example)

btfsc

bitsB47,4

; Test bit 4

goto

bit4Chng ; Routine for changed bit 4

; At this point bit 4 did not change

btfsc

bitsB47,7

; Test bit 7

goto

bit7Chng ; Routine for changed bit 7

; Invalid port line change. Exit

 

goto

pbRelease

 

;========================

 

;bit 4 change routine ;========================

;Check for signal falling edge, ignore if not bit4Chng:

btfsc

PORTB,4

; Is bit

4 high

goto

pbRelease

; Bit is

high. Ignore

; Toggling bit 1 of Port-A turns LED on and off

movlw

b’00000010’

; Xoring

with a 1-bit produces

 

 

; the complement

xorwf

PORTA,f

; Complement bit 1, Port-A

goto

pbRelease

 

 

Interrupts

239

;========================

;bit 7 change routine ;========================

;Check for signal falling edge, ignore if not bit7Chng:

btfsc

PORTB,7

; Is bit 7 high

goto

exitISR

; Bit is high. Ignore

; Toggling bit 0 of Port-A turns LED on and off

movlw

b’00000001’

; Xoring with a 1-bit produces

 

 

; the complement

xorwf

PORTA,f

; Complement bit 1, Port-A

;

 

 

pbRelease:

 

 

call

delay

; Debounce switch

movf

PORTB,w

; Read port-B into w

andlw

b’10010000’ ; Eliminate unused bits

btfsc

STATUS,Z ; Check for zero

goto

pbRelease

; Wait

;At this point all port-B pushbuttons are released ;=========================

;exit ISR

;=========================

 

exitISR:

 

 

; Store new value of port-B

 

movf

temp,w

; This port-B value to w

movwf

bitsB47

; Store

; 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

; Reset,interrupt

 

 

notRBIF:

 

 

bcf

INTCON,RBIF

; Clear INTCON bit 0

retfie

 

 

;=======================

;Procedure to delay

;10 machine cycles ;======================= delay:

movlw

D’6’

; Repeat 18 machine cycles

movwf

count1

; Store value in counter

repeat:

 

 

decfsz

count1,f

; Decrement counter

goto

repeat

; Continue if not 0

return

 

 

;=============================

240

Chapter 11

;long delay sub-routine

;(for debugging) ;============================= long_delay

movlw

D’200’

; w = 200 decimal

movwf

J

; J = w

jloop:

 

 

movwf

K

; K = w

kloop:

 

 

decfsz

K,f

; K = K-1, skip next if zero

goto

kloop

 

decfsz

J,f

; J = J-1, skip next if zero

goto

jloop

 

return

 

 

end