LIST p=16F88
INCLUDE "p16f88.inc"
__CONFIG _CONFIG1,_INTRC_IO & _WDT_OFF & _LVP_OFF & _MCLR_ON & _BODEN_OFF
ERRORLEVEL 0, -302
btDone equ 0x00
btStart equ 0x01
btCommand equ 0x02
cblock 0x20
dlen,Time2,BitCount,DeviceCode,CommandCode,IRStatus,Bit,ScratchCode
w_temp,status_temp,pclath_temp,the_end
endc
org 0x0000
goto Init
;*****
; ISR
org 0x0008
ISR movwf w_temp
swapf STATUS,W
clrf STATUS
movwf status_temp
movf PCLATH,W
movwf pclath_temp
clrf PCLATH
bcf PORTA,0 ;LEDs 1 & 2 off
bcf PORTA,6
bcf PORTA,7
btfsc IRStatus,btDone ;has a code already been read?
goto isr_done
banksel OPTION_REG ;bank 1
btfsc OPTION_REG,INTEDG ;check if falling or rising signal
goto Rise
banksel TMR0 ;bank 0
clrf TMR0 ;reset timer
banksel OPTION_REG ;bank 1
movlw b'01010111' ;Enable timer0, 256 prescaler, set RB0 rising edge
movwf OPTION_REG
banksel PORTA ;bank 0
goto isr_done
Rise
banksel TMR0 ;bank 0
movf TMR0,W ;Put timer 0 value into storage
movwf Time2
banksel OPTION_REG ;bank 1
bcf OPTION_REG,INTEDG ;set for falling edge
banksel PORTA ;bank 0
GetPulseWidth
movlw 0x12 ;Check for start pulse, should be between 0x12 and 0x14
subwf Time2,W
btfss STATUS,C ;Greater than 0x11?
goto CheckZero
movlw 0x14
subwf Time2,W ;Less than 0x15?
btfsc STATUS,C
goto IRError ;Start Bit exceeds tolerance
StartBit ;We have a Start Bit
btfsc IRStatus,btStart ;Check if already set (ERROR)
goto IRError
bsf IRStatus,btStart ;Flag IRStatus
movlw 0x07
movwf BitCount
goto isr_done
CheckZero
movlw 0x04 ;Check for zero pulse. Should be between 0x4 and 0x6
subwf Time2,W
btfss STATUS,C ;Greater than 0x3?
goto IRError
movlw 0x06
subwf Time2,W
btfsc STATUS,C ;Less than 0x7?
goto CheckOne
ZeroBit btfss IRStatus,btStart ;Check if we have previously had Start Bit
goto IRError
clrf Bit
call ProcessBit
goto isr_done
CheckOne
movlw 0x09 ;Check for One Pulse. Should be between 0x9 and 0xB
subwf Time2,W
btfss STATUS,C ;Greater than 0x8?
goto IRError
movlw 0x0b
subwf Time2,W ;Less than 0xC
btfsc STATUS,C
goto IRError
OneBit btfss IRStatus,btStart ;Check if we have previously had Start Bit
goto IRError
movlw 0x01
movwf Bit
call ProcessBit
goto isr_done
IRError clrf IRStatus ;clear variables
clrf DeviceCode
clrf CommandCode
clrf ScratchCode
banksel OPTION_REG ;bank 1
bcf OPTION_REG,INTEDG ;Interrupt on falling edge
isr_done
banksel PORTA ;bank 0
clrf PORTA
movf pclath_temp,W
movwf PCLATH
swapf status_temp,W
movwf STATUS
swapf w_temp,F
swapf w_temp,W
bcf INTCON,INT0IF
retfie
; End ISR
;********
Init
banksel OSCCON ;bank 1
movlw 0x7d ;Set Internal 8MHz
movwf OSCCON
bcf ANSEL,0 ;Set RA0 as digital
movlw b'00111110'
movwf TRISA
bsf TRISB,0 ;Make RB0 Input
bsf TRISB,4 ;Make RB4 Input
banksel PORTA ;bank 0
bcf PORTA,0
bcf PORTA,6
bcf PORTA,7
;clear variables from Time2 to the_end
movlw Time2 ;point FSR to variables
movwf FSR
movlw the_end-Time2 ;set counter = # of vars to clear
movwf dlen ;use dlen as counter
zero clrf INDF ;clear a variable
incf FSR,F ;increment the pointer
decfsz dlen,F ;finished?
goto zero ;no, go again
InitISR
banksel OPTION_REG ;bank 1
movlw b'00000111' ;enable weak pullups on PORTB - Interrupt on falling edge
movwf OPTION_REG
movlw b'10010000' ;Enable INT0 interrupt, Clear INT0 flag
movwf INTCON ;Disable peripheral interrupts, enable global interrupt
banksel PORTA ;bank 0
Main bsf PORTA,0 ;Light LED 1
bcf PORTA,6
bsf PORTA,7
btfss IRStatus,btDone
goto Main
bsf PORTA,0 ;Light LED 2
bcf PORTA,6
bcf PORTA,7
WaitForRB2
btfsc PORTB,4
goto WaitForRB2
clrf IRStatus ;clear variables
clrf DeviceCode
clrf CommandCode
clrf ScratchCode
goto Main
ProcessBit
btfss Bit,0 ;Check if bit set
goto WriteZero
WriteOne
bsf ScratchCode,0x07
goto RotateRight
WriteZero
bcf ScratchCode,0x07
RotateRight
rrf ScratchCode,F
btfss STATUS,C
goto rr1
bsf ScratchCode,7
goto rrdone
rr1 bcf ScratchCode,7
rrdone decfsz BitCount,F
return
WhichCode
btfss IRStatus,btCommand
goto CommandCodeDone
DeviceCodeDone
rrf ScratchCode,F ;a couple of more rotations
btfss STATUS,C
goto zero1
bsf ScratchCode,7
goto done1
zero1 bcf ScratchCode,7
done1 rrf ScratchCode,F
btfss STATUS,C
goto zero2
bsf ScratchCode,7
goto done2
zero2 bcf ScratchCode,7
done2 movf ScratchCode,W
movwf DeviceCode
bsf IRStatus,btDone
return
CommandCodeDone
movf ScratchCode,W
movwf CommandCode
bsf IRStatus,btCommand
movlw 0x5
movwf BitCount
clrf ScratchCode
return
end