Beruflich Dokumente
Kultur Dokumente
Abdel-Rahman M. Jaradat
April 24, 2012
Abstract
PIC 16F877 Interrupt System
The delay=ms (20) is a crude way to debounce a (mechanical) switch. In general, you will not want to sit in an
ISR for 20 MS to allow the switch to debounce. A more elegant solution is to set a timer on the first interrupt and
wait until the timer overflows. Do not process further changes on the pin.
void main()
{
port_b_pullups(0); // disable
enable_interrupts(int_rb);
enable_interrupts(global);
while(1) {
}
}
and in assembly language: Sanchez pages 235-240
; 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 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 LED 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
;========================================================
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
;============================
; 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
;========================
; 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
movwf 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
;=============================
; 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
;