-- serial routine from Axelk -- -- ------------------------------------------------------------------------ -- bit lengths: -- 9600 baud = 104 cycles -- 19200 baud = 52 cycles -- 38400 baud = 26 cycles -- 76800 baud = 13 cycles -- -- -- ------------------------------------------------------------------------ -- const asynch_baudrate = 19200 -- hardcoded var volatile bit asynch_in_pin is pin_a3 var volatile bit asynch_out_pin is pin_b7 -- -- ------------------------------------------------------------------------ -- some easy delays -- -- ------------------------------------------------------------------------ procedure delay10 is -- 10 usec including call -- call=2 + return=2 + 3*(goto=2) assembler local L1, L2, L3 goto L1 L1: goto L2 L2: goto L3 L3: end assembler end procedure -- -- ------------------------------------------------------------------------ procedure delay44 is -- 44 usec including call -- call=2 + return=2 + 4*10 delay10 delay10 delay10 delay10 end procedure -- -- ------------------------------------------------------------------------- -- send a byte -- -- ------------------------------------------------------------------------- procedure asynch_send( byte in x ) is var bit current_bit at x : 0 var byte times assembler local sendloop, L1, L2, by0, by1 -- wait 2 bits = 104 clocks call delay44 call delay44 call delay10 call delay10 -- 108 is ok here -- the start bit bcf asynch_out_pin -- low call delay44 -- the 8 data bits movlw 8 -- 8 times movwf times -- 46 goto L1 -- 48 L1: goto L2 -- 50 L2: sendloop: -- asynch_out_pin = current_bit btfss current_bit goto by0 bsf asynch_out_pin goto by1 by0: bcf asynch_out_pin nop by1: -- 5 -- x = x >> 1 rrf x, f -- 6 call delay44 -- 50 -- end loop decfsz times, f -- 51 goto sendloop -- 53 -- the stop bit(s) bsf asynch_out_pin -- high call delay44 call delay10 clrwdt end assembler end procedure -- -- ------------------------------------------------------------------------- -- receive a byte into lastreceived -- -- ------------------------------------------------------------------------- var byte lastreceived procedure asynch_receive is var byte times assembler local WaitIdle, WaitStart, RecvLoop clrwdt -- wait for idle WaitIdle: btfss asynch_in_pin -- active low goto WaitIdle -- wait for start bit WaitStart: btfsc asynch_in_pin -- active low goto WaitStart -- wait for half a bit time (26) until recvloop call delay10 call delay10 nop -- now repeat 8 times: -- wait for the next interval and sample movlw 8 -- 8 times movwf times goto recvloop -- 2 usec recvloop: call delay44 -- 44 nop -- 45 -- x = x >> 1 clrc -- 1 rrf lastreceived, f -- 2 -- bit x:7 = asynch_in_pin btfsc asynch_in_pin -- 3 bsf lastreceived, 7 -- 4 -- end loop decfsz times, f -- 5 goto recvloop -- 7 -- wait for the (first) stop bit call delay44 clrwdt end assembler end procedure -- asynch_receive
See: