Code:
SerialIN ;receive serial byte with pre-determined timeout
movf R6 ,W ;move timeout delay to temp
movwf R0 ;
movf R15 ,W ;
movwf R9 ;
movlw 0x01 ;
movwf R1 ;set inside loop counter
clrf R10 ;
serial_loop ;
clrwdt ;keep watchdog timer clear
call SerinX ;get one bit
btfss status ,C ;wait for start bit
goto serinstart ;
decfsz R1 ,F ;
goto serial_loop ;
movlw 0xFF ;
addwf R10 ,F ;
btfsc status ,C ;
goto serial_loop ;
addwf R0 ,F ;
btfss status ,C ;
addwf R9 ,F ;
btfss status ,C ;
goto DoneX ;time out
movlw 0x32 ;
movwf R1 ;reset inside loop counter
clrw ;
movwf R10 ;
goto serial_loop ;
SerialIN_notimeout ;
clrwdt ;receive byte serialy with no timeout
call SerinX ;get one bit
btfsc status ,C ;wait for start bit
goto SerialIN_notimeout ;
serinstart ;
call serialdelay ;wait 1/4 bit time
clrf R4 ;zero parity accumulator
movlw 0x08 ;number of bits in one byte
movwf R10 ;
serpar ;
call seroutdelay ;wait bit time
call SerinX ;get one bit
btfsc status ,C ;accumulate parity
incf R4 ,F ;
btfss R14 ,05 ;if no parity...
clrf R4 ;...keep it even
rrf R1 ,F ;move bit into byte
decfsz R10 ,F ;check for more bits
goto serpar ;
btfsc R14 ,05 ;if parity...
bcf R1 ,07 ;...clear top bit of result
call seroutdelay ;delay to stop bit
bsf status ,C ;carry shifts in clear
movf R1 ,W ;get char to W
return ;
SerinX ;
movf RR2 ,W ;receive one bit for serial in
movwf fsr ;
movf RR1 ,W ;
bsf fsr ,07 ;
iorwf indf ,F ;
bcf fsr ,07 ;
andwf indf ,W ;
btfsc R14 ,06 ;
xorwf RR1 ,W ;
addlw 0xFF ;
return ;
SerialIN_skipbyte ;
movf R13 ,W ;ignore received byte for serial in
bsf status ,C ;
btfsc status ,Z ;
goto DoneX ;
call skipX ;
btfss status ,C ;
return ;
decf R13 ,F ;
goto SerialIN_skipbyte ;
serialOUT ;transmit byte serialy from port pin
movwf R3 ;save byte to send
movf RR2 ,W ;get port to fsr
movwf fsr ;
movlw 0x80 ;zero parity accumulator (preserve blanking)
andwf RM2 ,F ;
movlw 0x08 ;1 start bit + 7 data bits
movwf R12 ;
bcf status ,C ;start bit low
seroutloop ;
btfsc status ,C ;accumulate parity bits
incf RM2 ,F ;
call seroutbit ;send a bit and delay bit time
rrf R3 ,F ;move to next bit
decfsz R12 ,F ;do next bit, if any
goto seroutloop ;
nop ;
btfsc R14 ,05 ;send parity
rrf RM2 ,W ;get parity to carry
call seroutbit ;send parity or last bit and delay bit time
call Done ;
bsf status ,C ;stop bit high
call seroutbit ;send stop bit and delay bit time
movf R16 ,W ;do pacing
movwf R10 ;
movf R7 ,W ;
goto DelayX ;
seroutbit ;
bcf fsr ,07 ;make sure we're pointing to the port
btfss R14 ,07 ;check for TRIS mode
goto seroutnorm ;handle normal mode
movf indf ,W ;get port data
iorwf RR1 ,W ;set bit on
btfss R14 ,06 ;bit matches invert mode
xorwf RR1 ,W ;set bit off
movwf indf ;write it out
bsf fsr ,07 ;point fsr to port tris
movf indf ,W ;get tris data
iorwf RR1 ,W ;make bit an input
btfss status ,C ;bit direction matches bit
xorwf RR1 ,W ;make bit an output
movwf indf ;write it out
goto seroutdelay ;wait remainder of bit time
seroutnorm ;
movf indf ,W ;get port data
iorwf RR1 ,W ;set bit on
btfss status ,C ;skip if bit should be on
xorwf RR1 ,W ;set bit off
btfsc R14 ,06 ;invert if 'N' mode
xorwf RR1 ,W ;flip for invert
movwf indf ;write it out
bsf fsr ,07 ;point fsr to port tris
comf RR1 ,W ;get complemented bit mask to W
andwf indf ,F ;clear tris bit to set output
goto seroutdelay ;wait remainder of bit time
serialdelay ;
bsf RM2 ,06 ;
seroutdelay ;
movf R14 ,W ;get high baud byte
andlw 0x1F ;mask to our bits
addlw 0xFF ;fix baud
movwf R9 ;save it
movf R5 ,W ;get low baud byte
addlw 0xF5 ;
btfsc status ,C ;bump up high byte if low overflowed
incf R9 ,F ;
btfss RM2 ,06 ;
goto pauseUSL ;
bcf RM2 ,06 ;clear short delay mark
movwf R0 ;save low part
movlw 0x02 ;divide time by 4
call shiftR ;
goto pauseUSL ;do 1/4 delay
That's quite a lot of code asking to be placed in the first 2K code space (and kicking your code out).
Code:
Delay
clrf R10 ;delay 1
DelayX ;
movwf R1 ;delay 2
DelayXX ;
movlw 0xFF ;
addwf R1 ,F ;
btfss status ,C ;
addwf R10 ,F ;
btfss status ,C ;
goto DoneX ;
movlw 0x03 ;
movwf R9 ;
movlw 0xDF ;
call pauseUSL ;
goto DelayXX ;
clrf R9 ;
pauseUSL ;
addlw 0xE8 ;
movwf R0 ;
comf R9 ,F ;
movlw 0xFC ;
btfss status ,C ;
goto XpauseUSL ;
pauseX ;
addwf R0 ,F ;
btfsc status ,C ;
goto pauseX ;
XpauseUSL ;
addwf R0 ,F ;
clrwdt ;
incfsz R9 ,F ;
goto pauseX ;
btfsc R0 ,00 ;
goto pausedoneX ;
pausedoneX ;
btfss R0 ,01 ;
goto pausedone ;
goto Done ;
or on chip-EEPROM Read/Write:
Code:
EEPROMread ;read byte from on-chip EEPROM
bsf status ,rp0 ;for bank 1
movwf EEADR ;set the EEPROM address
bsf EECON1 ,0x0 ;EECON1 in bank 3
movf EEDATA ,W ;read from data memory
goto DoneX ;done
EEPROMwrite ;write byte to on-chip EEPROM
bsf status ,rp0 ;for EE in bank 1
movwf EEDATA ;set the EEPROM data
bsf EECON1 ,02 ;
movlw 0x55 ;unlock the door
movwf EECON2 ;
movlw 0xAA ;
movwf EECON2 ;
bsf EECON1 ,01 ;do the write
writeloop ;
btfsc EECON1 ,01 ;wait for the write to complete
goto writeloop ;
bcf EECON1 ,02 ;lock up when we're done
goto DoneX ;
So bottom line is if you are using any of these, insert them in your code once, straight away
Bookmarks