list P=16F1708
#include "p16f1708.inc"
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _LVP_OFF
prta equ 0x0C ;PORTA
prtb equ 0x0D ;PORTB
prtc equ 0x0E ;PORTC
cblock 0x20
pvi ;Used to store the previous input values
TMR0_k ;constant used in delay routine
count_a ;used in delay routine
count_b ;used in delay routine
count_k
endc
cblock 0x70
tmp ;used in pp1 ~ 6
endc
#define p_1 prta, 5 ;p wire 1 state
#define p_2 prta, 4 ;p wire 2 state
#define p_3 prtc, 5 ;p wire 3 state
#define p_4 prtc, 4 ;p wire 4 state
#define p_5 prtc, 3 ;p wire 5 state
#define p_6 prtc, 6 ;p wire 6 state
#define pv_1 pvi, 1 ;previous p_1 state
#define pv_2 pvi, 2 ;previous p_2 state
#define pv_3 pvi, 3 ;previous p_3 state
#define pv_4 pvi, 4 ;previous p_4 state
#define pv_5 pvi, 5 ;previous p_5 state
#define pv_6 pvi, 6 ;previous p_6 state
#define Q_1 prtc, 2 ;Q1 on to busy P1
#define Q_2 prtc, 1 ;Q2 on to busy P2
#define Q_3 prtc, 0 ;Q3 on to busy P3
#define Q_4 prta, 2 ;Q4 on to busy P4
#define Q_5 prta, 1 ;Q5 on to busy P5
#define Q_6 prta, 0 ;Q6 on to busy P6
#define rls prtc, 7 ;release all p wires
#define tmr0_of INTCON, TMR0IF ;TMR0 overflow (bit 2)
#define c_bit STATUS, C
#define z_bit STATUS, Z
ORG 0x000
call Init
;Programme start
main
call clr_param
call delay_5m
bsf INTCON, 3 ;IOCIE
call clr_flgs ;clear flags
slp nop
sleep
nop
call clr_flgs ;clear flags
call delay_30m ;debounce
btfsc rls ;Release p wire high?
goto ppr ;Yes - process release
;determine which P wire(s)have changed
call pp1 ;process P1
call pp2 ;process P2
call pp3 ;process P3
call pp4 ;process P4
call pp5 ;process P5
call pp6 ;process P6
goto slp
ppr movlw 0x00 ;turn MOSFETs off - tempLC - to be 0x07
movwf prtc ;release P wires 1 ~ 3
movwf prta ;release P wires 4 ~ 6
call delay_100m
btfsc rls ;is rsl p wire still high?
goto $-2 ;Yes - wait
call delay_100m ;repeat to avoid possibility of a spike
btfsc rls ;is release p wire still high?
goto $-2 ;Yes - wait
goto slp ;No
; SUBROUTINES ------------------------------------------------------------------------------
pp1 movlw 0x20
movwf tmp
btfsc pv_1 ;previous P wire 1 (RA5)
goto pb1
btfss p_1 ;is p_1 (RA5) high?
return ;No => no change
btfsc Q_1 ;is Q1 on?
return ;Yes
call chg_a ;No - set the bit in IOCAN & clears same bit in IOCAP
bsf pv_1 ;indicates current value of p_1
return
pb1 btfsc p_1 ;is p_1 (RA5) high?
return ;Yes => no change
call delay_30m ;blink period
call clr_an ;clear relevant bit
bsf Q_1 ;tempLC to be bcf ultimately
bcf pv_1 ;indicates current value of p_1
return
;------------------------------------------------------------------
pp2 movlw 0x10
movwf tmp
btfsc pv_2 ;previous P wire 2 (RA4)
goto pb2
btfss p_2 ;is p_2 (RA4) high?
return ;No => no change
btfsc Q_2 ;is Q2 on?
return ;Yes
call chg_a ;No - set the relevant bit in IOCAN & clears same bit in IOCAP
bsf pv_2 ;indicates current value of p_2
return
pb2 btfsc p_2 ;is p_2 (RA4) high?
return ;Yes => no change
call delay_30m ;blink period
call clr_an ;clear relevant bit
bsf Q_2 ;tempLC to be bcf ultimately
bcf pv_2 ;indicates current value of p_2
return
;-------------------------------------------------------------------
pp3 movlw 0x20
movwf tmp
btfsc pv_3 ;previous P wire 3 (RC5)
goto pb3
btfss p_3 ;is p_3 (RC5) high?
return ;No => no change
btfsc Q_3 ;is Q3 on?
return ;Yes
call chg_c
bsf pv_3 ;indicates current value of p_3
return
pb3 btfsc p_3 ;is p_3 (RC5) high?
return ;Yes => no change
call delay_30m ;blink period
call clr_cn ;clear relevant bit
bsf Q_3 ;tempLC to be bcf ultimately
bcf pv_3 ;indicates current value of p_3
return
;------------------------------
pp4 movlw 0x10
movwf tmp
btfsc pv_4 ;previous P wire 4 (RC4) value
goto pb4
btfss p_4 ;is p_4 (RC4) high?
return ;No => no change
btfsc Q_4 ;is Q4 on?
return ;Yes
call chg_c ;No
bsf pv_4 ;indicates current value of p_4
return
pb4 btfsc p_4 ;is p_4 (RC4) high?
return ;Yes => no change
call delay_30m ;blink period
call clr_cn ;clear relevant bit
bsf Q_4 ;tempLC to be bcf ultimately
bcf pv_4 ;indicates current value of p_4
return
;--------------------------------
pp5 movlw 0x08
movwf tmp
btfsc pv_5 ;previous P wire 5 (RC3) value
goto pb5
btfss p_5 ;is p_5 (RC3) high?
return ;No => no change
btfsc Q_5 ;is Q5 on?
return ;Yes
call chg_c ;No
bsf pv_5 ;indicates current value of p_5
return
pb5 btfsc p_5 ;is p_5 (RC3) high?
return ;Yes => no change
call delay_30m ;blink period
call clr_cn ;clear relevant bit
bsf Q_5 ;tempLC to be bcf ultimately
bcf pv_5 ;indicates current value of p_5
return
;-----------------------------
pp6 movlw 0x40
movwf tmp
btfsc pv_6 ;previous P wire 6 (RC6) value
goto pb6
btfss p_6 ;is p_6 (RC6) high?
return ;No => no change
btfsc Q_6 ;is Q6 on?
return ;Yes
call chg_c ;No
bsf pv_6 ;indicates current value of p_6
return
pb6 btfsc p_6 ;is p_6 (RC6) high?
return ;Yes => no change
call delay_30m ;blink period
call clr_cn ;clear relevant bit
bsf Q_6 ;tempLC to be bcf ultimately
bcf pv_6 ;indicates current value of p_6
return
;-------------------------------------------------------------------
chg_a
banksel IOCAP
movfw tmp
iorwf IOCAN, f ;set respective bit in IOCAN
comf tmp, w
andwf IOCAP, f ;clear respective bit in IOCAP
banksel PORTA
return
chg_c
banksel IOCAP
movfw tmp
iorwf IOCCN, f ;set respective bit in IOCCN
comf tmp, w
andwf IOCCP, f ;clear respective bit in IOCCP
banksel PORTA
return
clr_an
banksel IOCAN
comf tmp, w
andwf IOCAN, f ;clear respective bit in IOCAN
banksel PORTA
return
clr_cn
banksel IOCAF ;selects Bank 7
comf tmp, w
andwf IOCCN, f ;clear respective bit in IOCCN
banksel PORTA
return
clr_flgs ;Clear flag(s) IOCAF & IOCCF
banksel IOCAF ;selects Bank 7
movlw 0xFF
xorwf IOCAF, w
andwf IOCAF, f ;this resets IOCAF - see spec p. 147
movlw 0xFF
xorwf IOCCF, w
andwf IOCCF, f ;this resets IOCCF - see spec p. 147
banksel PORTA ;selects Bank 0
return
clr_param
clrf prta ;tempLC - to be set prta ultimately
clrf prtc ;tempLC - to be set prtc
clrf tmp
clrf pvi
return
Init
banksel TRISA ;selects BANK 1
movlw 0x38
movwf TRISA ;RA5:3 i/p - RA3 is MCLR & not used
clrf TRISB ;RB7:0 o/p
movlw 0xF8
movwf TRISC ;RC7:3 i/p
movlw 0x81 ;prescaler 1:4, internal clock
movwf OPTION_REG ;disable RB pull up resistors
banksel INLVLA ;selects Bank 7
movlw 0x30
movwf INLVLA ;RA5:4 set for Schmitt Trigger
movlw 0x30
movwf IOCAP ;RA5:4 set for positive edge change
clrf IOCAN ;RA5:4 negative edge change not used initially
movlw 0xF8
movwf IOCCP ;RC7:3 set for positive edge change
clrf IOCCN ;RC6:3 negative edge change not used initially
banksel ANSELA ;selects BANK 3
clrf ANSELA
clrf ANSELB
clrf ANSELC
banksel SLRCONA ;selects BANK 6
clrf SLRCONA
clrf SLRCONB
clrf SLRCONC
banksel WPUA ;selects BANK 4
clrf WPUA
clrf WPUB
clrf WPUC
banksel PORTA ;selects BANK 0
movlw 0x00 ;tempLC to be 0x07
movwf PORTA
movwf PORTC ;turn MOSFETs off
bsf INTCON, IOCIE ;bit 3 : awake on IOC
bsf INTCON, TMR0IE ;bit 5 : enable TMR0 overflow
return
end