LIST P = 16F84A ; 115200 full duplex (send delayed up to 8us) ; 115200 = ; 20 MHz = .2 us/instruction ; ; pic0.asm is the current robot PIC0 program ; INCLUDE __CONFIG _PWRTE_OFF & _HS_OSC & _WDT_OFF ; configuration switches ; SP equ 0 ;Send Pin GP equ 1 ;Get Pin PICN1 equ 2 ;Pin to send 8 bit address to PIC1 EIO0 equ 3 ;Enable IO 4-16 #0 EIO1 equ 4 ;Enable IO 4-16 #1 OMSK equ 0x04 ;or mask for PICN1 AMSK equ 0xfb ;and mask for PICN1 ;OMSK equ 0x08 ;or mask for PICN1 ;AMSK equ 0xf7 ;and mask for PICN1 GR equ 0xc ;byte to get SR equ 0xd ;byte to send GF equ 0xe ;get flag SF equ 0xf ;send flag GK equ 0x10 ;get count SK equ 0x11 ;send count TGR equ 0x12 ;temp Get Register GR2 equ 0x13 ;Get Register for byte 2 DELA equ 0x14 ;delay count KR equ 0x15 ;clear port count EIO equ 0x16 ;bit 0=4-16 (0/1),bit1=send input (0/1),bit7=check for addr=0 later ; ORG 0 ; ; bsf STATUS,RP0 ;select reg bank 1 movlw 0x2 movwf TRISA ;set port A pin 0 as out, pin 1 as in movlw 0x0 movwf TRISB ;set PORTB to output bcf STATUS,RP0 ;select reg bank 0 bsf PORTA,EIO0 ;set 4-16 enable high bsf PORTA,EIO1 ;set 4-16 enable high bsf PORTA,SP ;set send pin bsf PORTA,PICN1 ;set send pin for pic1 ; bcf PORTA,PICN1 ;clear send pin for pic1 (reversed) clrf PORTB ; ; goto TOP0 ;skip init movlw 0xff ;8 1.2 us b4 pic1 starts movwf DELA ;9 Dlay0 decfsz DELA,1 ;DELA*3+1 DELA>0 goto Dlay0 ;1=2,2=5,3=8,4=11,5=14,6=17,7=20,8=23,9=26,10=29,11=32 ;9+(11=32)=41 ; go thru addressed 0x0c-0x0f, and 0xc0-0xf0 and ; clear 8-bit ports movlw 0xc movwf SR movlw 0xc movwf TGR ;send address to PIC1 LUP call SndByt ;set address lines clrf PORTB ;clear data lines bcf PORTA,EIO0 ;enable 8-bit port nop bsf PORTA,EIO0 incf TGR,1 nop movf TGR,0 movwf SR btfss TGR,4 goto LUP movlw 0xc0 movwf SR movlw 0xc0 movwf TGR ; goto TOP0 ;test LUP2 call SndByt ;set address lines clrf PORTB ;clear data lines bcf PORTA,EIO1 ;enable 8-bit port nop bsf PORTA,EIO1 movlw 0x10 addwf TGR,1 ; incf TGR,1 nop movf TGR,0 movwf SR movf TGR,0 btfss STATUS,Z goto LUP2 ;end clear 8 output ports ;15+14+14=43*.2=8.6us (8.68us) ;now start 115200 communciation with serial port TOP0 clrf GR clrf GR2 clrf SR clrf GF clrf SF ;movlw 0x30 ;for testing ;movwf SR ;for testing ;bsf SF,0 ;for testing movlw 0xa movwf SK TOP btfss GF,0 ;1 goto I1GA1 ;2 check for start bit decfsz GK,1 ;3 goto I2GA1 ;4 get bit clrf GF ;5 stop bit movf GR,0 ;6 btfsc STATUS,Z ;7 both zeros goto TOPA ;8 andlw 0xf0 ;9 btfss STATUS,Z ;10 bsf EIO,0 ;11 bits in high addr nop ;12 ; bcf PORTA,PICN1 ;**13 stop for PIC1 reversed bsf PORTA,PICN1 ;**13 stop for PIC1 goto TOP2 ;15 ;later finish send stop bit ;I can only guess that the end bit can delay an extra inst (15 not 14) ;and goes early to check for a new start bit ;the main idea is that TOP2 will land early on the stop bit ;the stop bit is 1 and the program will have time to get the ;next start bit (0) ;could infact go without using an end/stop bit TOPA bsf EIO,7 ;10 later part set EIO,0 based on data byte nop ;11 nop ;12 ; bcf PORTA,PICN1 ;**13 stop for PIC1 reversed bsf PORTA,PICN1 ;**13 stop for PIC1 goto TOP2 ;15 ;later finish send stop bit NEXT btfss SF,0 goto I1S btfsc SF,1 goto I2S ;send start bit decfsz SK,1 goto I3S ;send data bit goto I4S ;send stop bit I3S movf PORTA,0 ;8 btfsc SR,0 iorlw 0x1 btfss SR,0 andlw 0xfe movwf PORTA ;13 * ; nop rrf SR,1 ;14 ;15+14+14=3.0+2.8+2.8=8.6 us (8.6806 us) LAST btfss GF,1 ;1 goto I1GB1 ;2 check for start bit decfsz GK,1 ;3 goto I2GB1 ;4 get bit clrf GF ;5 stop bit movf GR,0 ;6 btfsc STATUS,Z ;7 both zeros goto LASTA ;8 andlw 0xf0 ;9 btfss STATUS,Z ;10 bsf EIO,0 ;11 bits in high addr nop ;12 ; bcf PORTA,PICN1 ;**13 stop for PIC1 reversed bsf PORTA,PICN1 ;**13 stop for PIC1 goto TOP2 ;15 (14+14=28 early 5.6 us) ok to be late (14) LASTA bsf EIO,7 ;10 later part set EIO,0 based on data byte nop ;11 nop ;12 ; bcf PORTA,PICN1 ;**13 stop for PIC1 reverse bsf PORTA,PICN1 ;**13 stop for PIC1 goto TOP2 ;15 ;later finish send stop bit ok to be late (14) ;could have 2 nop ;-------------- ;get byte 2 15+14+14 (TOP2+LAST2+NEXT2 [never a send during byte 2]) ;could be 15+15+13 ;-------------- ;INST is sent during time of end/stop bit TOP2 btfss GF,0 ;1 goto I1GA2 ;2 check for start bit decfsz GK,1 ;3 goto I2GA2 ;4 get bit movf GR2,0 ;5 set b7-b0 (d7 d6 d5 d4 d3 d2 d1 d0) movwf PORTB ;6 movlw 3 ;7 * movwf SF ;8 set send flag clrf GF ;9 nop ;10 btfss EIO,0 ;11 goto INST0 ;13 4-16A goto INST1 ;14 4-16B make 14 for end/stop bit+15 ; goto INST ;13 goto INST (16+15=31 extra 6us) ;would normally delay for 43 inst, but instead sent INST during time of end/stop bit LAST2 btfss GF,1 ;1 goto I1GB2 ;2 check for start bit decfsz GK,1 ;3 goto I2GB2 ;4 get bit movf GR2,0 ;5 set b7-b0 (d7 d6 d5 d4 d3 d2 d1 d0) movwf PORTB ;6 movlw 3 ;7* movwf SF ;8 set send flag clrf GF ;9 nop ;10 btfss EIO,0 ;11 goto INST0 ;13 ; goto INST0 ;13 test goto INST1 ;14 ; goto INST ;13 (16+15= 31) ;decide in/out (EIO,1) ;this is a delay for 1/3 NEXT2 btfsc EIO,0 ;1 goto NEXT2A ;2 movlw 0xf4 ;3 addwf GR,0 ;4 btfss STATUS,C ;5 bsf EIO,1 ;6 no carry=is input (0-11) ; movlw 0xc ;3 ; subwf GR,0 ;4 ; btfsc STATUS,DC ;5 ; bsf EIO,1 ;6 did borrow=is input (0-11) nop ;7 nop ;8 nop ;9 nop ;10 nop ;11 nop ;12 ; nop ;13 GOTO TOP2 ;14 NEXT2A movlw 0x40 ;4 addwf GR,0 ;5 btfss STATUS,C ;6 bsf EIO,1 ;7 no carry=is input (<12) ; movlw 0xc0 ;4 high addr ; subwf GR,0 ;5 ; btfsc STATUS,DC ;6 ; bsf EIO,1 ;7 did borrow =is input (0-11) nop ;8 nop ;9 nop ;10 nop ;11 nop ;12 ; nop ;13 GOTO TOP2 ;14 ;sending intruction has 43-7(to INST)-15(INS)-14(NEXT)=7 extra instructions ;that are 1 end bit anyway ;no send while getting byte 2 ;INST is sent during get of end/stop bit ;to process PIC instructions for external devices (inputs, motors, ...) ;already set address lines thru PIC1 and data lines (PORTB) INST0 nop ;14 extra from goto btfss EIO,1 ;1=get input ; btfss EIO,6 ;test goto I1I0 ;2 bsf STATUS,RP0 ;3 select reg bank 1 movlw 0xff ;4 movwf TRISB ;5 set PORTB to iiiiiiii bcf STATUS,RP0 ;6 select reg bank 0 ;the 4-16 address and data lines are set ;this will send the PIC the (input) instruction bcf PORTA,EIO0 ;7 enable 4-16 0 movf PORTB,0 ;8 copy PORTB to Send Register bsf PORTA,EIO0 ;9 disable 4-16 0 movwf SR ;10 bsf STATUS,RP0 ;11 select reg bank 1 clrf TRISB ;12 set PORTB back to oooooooo bcf STATUS,RP0 ;13 select reg bank 0 goto NEXT ;15 1st do any send is going back early? INST1 btfss EIO,1 ;1=get input goto I1I1 ;2 bsf STATUS,RP0 ;3 select reg bank 1 movlw 0xff ;4 movwf TRISB ;5 set PORTB to iiiiiiii bcf STATUS,RP0 ;6 select reg bank 0 ;the 4-16 address and data lines are set ;this will send the PIC the (input) instruction bcf PORTA,EIO1 ;7 enable 4-16 1 movf PORTB,0 ;8 copy PORTB to Send Register bsf PORTA,EIO1 ;9 disable 4-16 1 movwf SR ;10 bsf STATUS,RP0 ;11 select reg bank 1 clrf TRISB ;12 set PORTB back to oooooooo bcf STATUS,RP0 ;13 select reg bank 0 goto NEXT ;15 1st do any send ;---end main loop I1GA1 btfsc GF,1 ;4 check for start bit (A) goto I3GA1 ;5 nop ;6 btfss PORTA,GP ;7 * start bit = 0 bsf GF,1 ;8 got sb, get sb in other part (not this part) movlw 0xa ;9 10 (1=sb,8=bits,1=eb) movwf GK ;10 clrf EIO ;11 btfsc GF,0 ;12 if got sb, send sb to PIC1 ; bsf PORTA,PICN1 ;** 13 reversed ;bcf PORTA,PICN1 ;** 13 start bit will be sent like other bits nop ;13 goto NEXT ;15 I2GA1 rrf GR,1 ;6 get bit movf PORTA,0 ;7 * movwf TGR ;8 btfsc TGR,GP ;9 start new code iorlw OMSK ;10 set to 1 btfss TGR,GP ;11 andlw AMSK ;12 set to 0 movwf PORTA ;13 ** send bit to PIC1 ; setting bit in GR is now done in other part ; btfsc TGR,GP ;9 ; bsf GR,7 ;10 ; btfss TGR,GP ;11 ; bcf GR,7 ;12 ; nop ;13 goto NEXT ;15 ;getting byte in other part I3GA1 btfsc TGR,GP ;7 fill Get Register bsf GR,7 ;8 btfss TGR,GP ;9 bcf GR,7 ;10 nop ;11 nop ;12 nop ;13 goto NEXT ;15 I1S nop ;4 nop nop nop nop nop nop ;10 nop nop ; nop goto LAST ;14 I2S nop ;6 send start bit nop nop decfsz SK,1 bcf SF,1 ;clear bit 1 = do not send start bit again nop nop bcf PORTA,SP ;13 * nop ;14 ; goto LAST ;15 ;duplicate LAST btfss GF,1 ;1 goto I1GB1 ;2 check for start bit decfsz GK,1 ;3 goto I2GB1 ;4 get bit clrf GF ;5 stop bit movf GR,0 ;6 btfsc STATUS,Z ;7 both zeros goto LASTA ;8 andlw 0xf0 ;9 btfss STATUS,Z ;10 bsf EIO,0 ;11 bits in high addr nop ;12 ; bcf PORTA,PICN1 ;**13 stop for PIC1 reversed bsf PORTA,PICN1 ;**13 stop for PIC1 goto TOP2 ;15 (14+14=28 early 5.6 us) ok to be 15 (late) I4S movlw 0xa ;9 movwf SK clrf SF ;9 inst 43 inst is most close nop bsf PORTA,SP ;13 * nop ;14 ; goto LAST ;15 ;duplicate LAST btfss GF,1 ;1 goto I1GB1 ;2 check for start bit decfsz GK,1 ;3 goto I2GB1 ;4 get bit clrf GF ;5 stop bit movf GR,0 ;6 btfsc STATUS,Z ;7 both zeros goto LASTA ;8 andlw 0xf0 ;9 btfss STATUS,Z ;10 bsf EIO,0 ;11 bits in high addr nop ;12 ; bcf PORTA,PICN1 ;**13 stop for PIC1 reversed bsf PORTA,PICN1 ;**13 stop for PIC1 goto TOP2 ;15 (14+14=28 early 5.6 us) ok to be 15 (late) I1GB1 btfsc GF,0 ;4 check for start bit (B) goto I3GB1 ;5 nop ;6 btfss PORTA,GP ;7 * start bit = 0 bsf GF,0 ;8 got sb, get byte next part movlw 0xa ;9 movwf GK ;10 clrf EIO ;11 btfsc GF,1 ;12 if got sb, send sb to PIC1 ; bsf PORTA,PICN1 ;** 13 reverse ;bcf PORTA,PICN1 ;** 13 nop ;13 ;goto TOP ;15 should be 14 nop ;14 ;need duplicated TOP btfss GF,0 ;1 TOP goto I1GA1 ;2 check for start bit decfsz GK,1 ;3 goto I2GA1 ;4 get bit clrf GF ;5 movf GR,0 ;6 btfsc STATUS,Z ;7 both zeros goto TOPA ;8 andlw 0xf0 ;9 btfss STATUS,Z ;10 bsf EIO,0 ;11 bits in high addr nop ;12 ; bcf PORTA,PICN1 ;**13 stop for PIC1 reverse bsf PORTA,PICN1 ;**13 stop for PIC1 goto TOP2 ;15 ;later finish send stop bit ;end duplicated TOP I2GB1 rrf GR,1 ;6 movf PORTA,0 ;7 * movwf TGR ;8 btfsc TGR,GP ;9 iorlw OMSK ;10 set to 1 btfss TGR,GP ;11 andlw AMSK ;12 set to 0 movwf PORTA ;13 ** send bit to PIC1 nop ;14 ;need duplicated TOP (again) btfss GF,0 ;1 TOP goto I1GA1 ;2 check for start bit decfsz GK,1 ;3 goto I2GA1 ;4 get bit clrf GF ;5 movf GR,0 ;6 btfsc STATUS,Z ;7 both zeros goto TOPA ;8 andlw 0xf0 ;9 btfss STATUS,2 ;10 bsf EIO,0 ;11 bits in high addr nop ;12 ; bcf PORTA,PICN1 ;**13 stop for PIC1 reverse bsf PORTA,PICN1 ;**13 stop for PIC1 goto TOP2 ;15 ;later finish send stop bit ;end duplicated TOP (again) ;getting byte in other part I3GB1 btfsc TGR,GP ;7 fill Get Register bsf GR,7 ;8 btfss TGR,GP ;9 bcf GR,7 ;10 nop ;11 nop ;12 goto TOP ;14 ;-------------------------- ;byte 1 above, byte 2 below ;-------------------------- I1GA2 btfsc GF,1 ;4 check for start bit goto I3GA2 ;5 nop ;6 btfss PORTA,GP ;7 * start bit = 0 bsf GF,1 ;8 got start bit in next part movlw 0xa ;9 movwf GK ;10 nop ;11 nop ;12 nop ;13 goto LAST2 ;15 I2GA2 rrf GR2,1 ;6 get bit movf PORTA,0 ;7 * movwf TGR ;8 btfsc TGR,GP ;9 bsf GR2,7 ;10 btfss TGR,GP ;11 bcf GR2,7 ;12 nop ;13 goto LAST2 ;15 ;getting byte in other part I3GA2 btfss EIO,7 ;7 address=0x00, last bit = 4-16 goto I4GA2 ;8 nop ;9 btfsc GR2,0 ;10 GR2,0 is 0 until last rrf bsf EIO,0 ;11 nop ;12 nop ;13 goto LAST2 ;15 I4GA2 nop ;10 nop ;11 nop ;12 nop ;13 goto LAST2 ;15 I1GB2 btfsc GF,0 ;4 goto I3GB2 ;5 nop ;6 btfss PORTA,GP ;7 * start bit = 0 bsf GF,0 ;8 get byte in next part movlw 0xa ;9 stop bit - no need to get movwf GK ;10 nop ;11 nop ;12 goto NEXT2 ;14 I2GB2 rrf GR2,1 ;6 movf PORTA,0 ;7 * movwf TGR ;8 btfsc TGR,GP ;9 bsf GR2,7 ;10 btfss TGR,GP ;11 bcf GR2,7 ;12 goto NEXT2 ;14 ;getting byte in other part I3GB2 btfss EIO,7 ;7 goto I4GB2 ;8 btfsc GR2,0 ;9 GR2,0 is 0 until last rrf bsf EIO,0 ;10 nop ;11 nop ;12 goto NEXT2 ;14 I4GB2 nop ;10 not addr=0x00 nop ;11 nop ;12 goto NEXT2 ;14 I1I0 nop ;4 output only nop nop nop ;7 nop nop nop ;10 ;the 4-16 address and data lines are set ;this will send the output instruction bcf PORTA,EIO0 ;11 enable 4-16 bsf PORTA,EIO0 ;12 disable 4-16 clrf SF ;13 clear Send Flag set in past to save time goto TOP ;15 go back to getting byte 1 no need to send first I1I1 nop ;4 output only nop nop nop ;7 nop nop nop ;10 ;the 4-16 address and data lines are set ;this will send the output instruction bcf PORTA,EIO1 ;11 enable 4-16 bsf PORTA,EIO1 ;12 disable 4-16 clrf SF ;13 clear Send Flag set in past to save time goto TOP ;15 go back to getting byte 1 no need to send first ;===================================== ;initial clearing output port code ;===================================== SndByt movlw 8 ;1 movwf SK ;2 nop ;3 nop ;4 nop ;5 ; bsf PORTA,PICN1 ;*1 start bit reversed start/stop bit bcf PORTA,PICN1 ;*1 start bit nop ;2 movlw 0xb ;3 movwf DELA ;4 Dlay1 decfsz DELA,1 ;4+32=36 goto Dlay1 ;1=2,2=5,3=8,4=11,5=14,6=17,7=20,8=23,9=26,10=29,11=32 ;9+(11=32)=41 nop ;37 nop ;38 SndByt1 movf PORTA,0 ;39 btfsc SR,0 ;40 iorlw OMSK ;41 3 set to 1 btfss SR,0 ;42 andlw AMSK ;43 set to 0 movwf PORTA ;*1 rrf SR,1 ;2 movlw 0xa ;3 movwf DELA ;4 Dlay2 decfsz DELA,1 ;4+29=33 goto Dlay2 ;1=2,2=5,3=8,4=11,5=14,6=17,7=20,8=23,9=26,10=29,11=32 ;9+(10=29)=38 nop ;34 nop ;35 decfsz SK,1 ;36 goto SndByt1 ;38 ;delay 6 and send stop bit nop ;38 lost 1 inst from decfsz nop ;39 nop ;40 nop ;41 nop ;42 nop ;43 ; bcf PORTA,PICN1 ;*1 stop bit reversed start/stop bit bsf PORTA,PICN1 ;*1 stop bit nop ;2 movlw 0xd ;3 movwf DELA ;4 Dlay3 decfsz DELA,1 ;4+38=42 goto Dlay3 ;1=2,2=5,3=8,4=11,5=14,6=17,7=20,8=23,9=26,10=29,11=32,12=35,13=38 ;9+(11=32)=41 return ;44 ;43 ;14+15+14=3.0+2.8+2.8=8.6 us (8.6806 us) END