list p=p12f1840 include __CONFIG _CONFIG1, _MCLRE_OFF & _WDTE_OFF __CONFIG _CONFIG2, _LVP_OFF #define TXPIN 2 #define RXPIN 4 cblock 0x20 wait1 iter input got tmp endc org 0 ;;; Define pin 5 (RA2) as output movlb 0 ; select bank 0 (PORTA) clrf 0x0C ; clear PORTA movlb 2 ; select bank 2 (LATA) clrf 0x0C ; clear LATA movlb 3 ; select bank 3 (ANSELA) clrf 0x0C ; clear ANSELA movlb 1 ; select bank 1 (TRISA) ;; TRISA (0: output, 1: input) bcf 0x0C, TXPIN bsf 0x0C, RXPIN ;;; program movlb 0 ; select bank 0 (PORTA) bsf 0x0C, TXPIN ; init tx loop0: btfsc 0x0C, RXPIN ; loop while input is high bra $-1 call get movf got, 0 call send goto loop0 get: ;; get contents of W over 1200 baud ;; wait 1200 baud (1.2ms) ;; wait instructions 500 khz / 4 c/i / 1200 ms = 104.17 clrf got ; ready output movlw 0x08 movwf iter ; set up iterator ;; wait half a tick movlw 0x0E call waiti movlw 0x1F ; wait past start bit call waiti goto loop1 shift: lsrf got, 1 ; right shift got loop1: btfsc 0x0C, RXPIN ; if current bit = 1 bsf got, 7 ; set got:0 = 1 ;; wait a tick (100) movlw 0x20 call waiti decfsz iter, 1 goto shift return send: ;; send contents of W over 1200 baud ;; wait 1200 baud (1.2ms) ;; wait instructions 500 khz / 4 c/i / 1200 ms = 104.17 movwf input ; store W in input movlw 0x08 movwf iter ; set up iterator movlb 0 ; select bank 0 (PORTA) bcf 0x0C, TXPIN ; transmit start bit loop2: ;; wait 104 - 9 = 95 movlw 0x1E call waiti btfss input, 0 ; if bit = 0 bcf 0x0C, TXPIN ; transmit a 0 btfsc input, 0 ; if bit = 1 bsf 0x0C, TXPIN ; transmit a 1 lsrf input, 1 ; left shift 0x20 by 1 decfsz iter, 1 ; while bits left to transmit goto loop2 ;; wait 102 - 2 = 100 movlw 0x20 call waiti bsf 0x0C, TXPIN ; transmit stop bit movlw 0x24 ; wait > 104 instructions call waiti return waiti: ;; W - 0x1E: wait 94 instructions ;; W = 0x1F: wait 97 instructions ;; W = 0x20: wait 100 instructions ;; wait 95 instructions ;; 4 + 1 + x * (1 + 2) - 1 = 4 + 3x movwf wait1 decfsz wait1, 1 bra $-1 return end