PIC Specific  GPS / Centronix IO

Brian Kraut [engalt@earthlink.net] says:

here is the printer interface code.
Sorry to all you MPLAB users that it is in Parallax code.  Also, sorry that it
is not very well doccumented and I don't have a schematic handy.  If there is
enough interest I could be persuaded to write a construction article on this for
Circuit Cellar or whoever else would publish it.

; PROGRAM: PRNT6.SRC     
; Written     May 1, 1999
; Revised     June 13, 1999   
; This program takes a NMEA input and outputs Lat/Long to a standard
; parallel printer
; 3 Changed to 16c72, added optocoupler input
; 4 added input of VTG sentence and speed, heading and status output
; 5 added variable print times on switch
; 6 date from RMC

                device  pic16c72,xt_osc,wdt_off,protect_off
		
		

bit_K           =       49              ;Change this value for desired baudrate
half_bit        =       bit_K/2         ;as shown in table.
parout          =       rb              ;parallel port data 0-7
strobe          =       rc.3            ;strobe line output
busy            =       rc.2            ;busy line input
serial_in       =       rc.0            ;NMEA input
short           =       rc.4            ;2 minute switch
long            =       rc.5            ;1 hour switch



		org     020h            ;Start of available RAM

bit_cntr        ds      1               ;Number of received bits
delay_cntr      ds      1
rcv_byte        ds      1               ;The received byte
commas          ds      1
t_1             ds      1               ;first character
t_2             ds      1               ;second character
t_3             ds      1               ;third character
t_4             ds      1               ;fourth character
t_5             ds      1               ;fifth character
t_6             ds      1               ;
t_7             ds      1               ;
t_8             ds      1               ;
t_9             ds      1               ;
t_10            ds      1               ;
t_11            ds      1               ;
t_12            ds      1               ;
t_13            ds      1               ;
t_14            ds      1               ;
t_15            ds      1               ;
t_16            ds      1               ;
t_17            ds      1               ;
t_18            ds      1               ;
t_19            ds      1               ;
t_20            ds      1               ;
t_21            ds      1               ;
t_22            ds      1               ;
t_23            ds      1               ;
t_24            ds      1               ;
t_25            ds      1               ;
t_26            ds      1               ;
t_27            ds      1               ;
t_28            ds      1               ;
t_29            ds      1               ;
t_30            ds      1               ;
t_31            ds      1               ;
t_32            ds      1
t_33            ds      1
t_34            ds      1
t_35            ds      1
t_36            ds      1
t_37            ds      1
t_38            ds      1
t_39            ds      1
t_40            ds      1
t_41            ds      1
t_42            ds      1
t_43            ds      1
t_44            ds      1
t_45            ds      1
t_46            ds      1
t_47            ds      1
temp            ds      1
waitdly         ds      1
waitdly2        ds      1
minutes         ds      1
nogga           ds      1
nozda           ds      1
comms           ds      1

		org     0               ;Start of code space
		jmp     begin            


; Set up chip 
		org     05h

begin           setb    rp0 
                mov     trisc,#00110101b ;rc.0, 2, 4, 5 input, others output
                clr     trisb           ;rb output
                mov     option,#04h     ;
                mov     adcon1,#07h
                clrb    rp0
                                
RMC             call    ser_in
                cjne    rcv_byte,#24h,RMC       ;"$"
                call    ser_in
                cjne    rcv_byte,#47h,RMC       ;"G"
                call    ser_in
                cjne    rcv_byte,#50h,RMC       ;"P"
                call    ser_in
                cjne    rcv_byte,#52h,RMC       ;"R"
                call    ser_in
                cjne    rcv_byte,#4dh,RMC       ;"M"
                call    ser_in
                cjne    rcv_byte,#43h,RMC       ;"C"
                call    ser_in
                cjne    rcv_byte,#2Ch,RMC       ;","
                
time            call    ser_in                  ;input time t_1 to t_9
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_1,rcv_byte            ;h
                call    ser_in                  
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_2,rcv_byte            ;h
                call    ser_in                  
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_3,rcv_byte            ;m
                call    ser_in                  
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_4,rcv_byte            ;m
                call    ser_in                  
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_5,rcv_byte            ;s
                call    ser_in
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_6,rcv_byte            ;s
		call    ser_in
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_7,rcv_byte            ;.
                call    ser_in
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_8,rcv_byte            ;s
                call    ser_in
                cje     rcv_byte,#2ch,:com1     ;goto next field
                mov     t_9,rcv_byte            ;s
                call    ser_in
                cje     rcv_byte,#2ch,:com1     ;goto next field
                call    ser_in
                cje     rcv_byte,#2ch,:com1     ;goto next field
                jmp     begin

:com1           call    ser_in
                cje     rcv_byte,#2ch,:com1a
                call    ser_in
                cje     rcv_byte,#2ch,:com1a
                call    ser_in
                cje     rcv_byte,#2ch,:com1a
                jmp     begin

:com1a          call    ser_in                  ;input lat t_10 to t_16
                cje     rcv_byte,#2ch,:com2     ;goto next field
                mov     t_10,rcv_byte           ;d
		call    ser_in   
                cje     rcv_byte,#2ch,:com2     ;goto next field
                mov     t_11,rcv_byte           ;d
		call    ser_in
                cje     rcv_byte,#2ch,:com2     ;goto next field
                mov     t_12,rcv_byte           ;m
		call    ser_in
                cje     rcv_byte,#2ch,:com2     ;goto next field
                mov     t_13,rcv_byte           ;m
		call    ser_in
                cje     rcv_byte,#2ch,:com2     ;goto next field
                mov     t_14,rcv_byte           ;.
		call    ser_in   
                cje     rcv_byte,#2ch,:com2     ;goto next field
                mov     t_15,rcv_byte           ;m
		call    ser_in
                cje     rcv_byte,#2ch,:com2     ;goto next field
                mov     t_16,rcv_byte           ;m
                call    ser_in
                cje     rcv_byte,#2ch,:com2     ;goto next field
                call    ser_in
                cje     rcv_byte,#2ch,:com2     ;goto next field
                jmp     begin

:com2           call    ser_in                  ;input N/S t_17
                cje     rcv_byte,#2ch,:com3     ;goto next field
                mov     t_17,rcv_byte           ;N/S
                call    ser_in
                cje     rcv_byte,#2ch,:com3     ;goto next field
                jmp     begin


:com3           call    ser_in                  ;input lon t_18 to t_25
                cje     rcv_byte,#2ch,:com4     ;goto next field
                mov     t_18,rcv_byte           ;d
		call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                mov     t_19,rcv_byte           ;d
                call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                mov     t_20,rcv_byte           ;d
                call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                mov     t_21,rcv_byte           ;m
		call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                mov     t_22,rcv_byte           ;m
		call    ser_in   
                cje     rcv_byte,#2ch,:com4     ;goto next field
                mov     t_23,rcv_byte           ;.
		call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                mov     t_24,rcv_byte           ;m
                call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                mov     t_25,rcv_byte           ;m
		call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                call    ser_in
                cje     rcv_byte,#2ch,:com4     ;goto next field
                jmp     begin

:com4           call    ser_in                  ;input E/W t_26
                cje     rcv_byte,#2ch,:com5     ;goto next field
                mov     t_26,rcv_byte           ;E/W
		call    ser_in
                cje     rcv_byte,#2ch,:com5     ;goto next field
                jmp     begin

:com5           call    ser_in                  ;input speed t_27 to t_30
                cje     rcv_byte,#2ch,:com6     ;goto next field
                mov     t_27,rcv_byte           ;tens
		call    ser_in   
                cje     rcv_byte,#2ch,:com6     ;goto next field
                mov     t_28,rcv_byte           ;ones
		call    ser_in
                cje     rcv_byte,#2ch,:com6     ;goto next field
                mov     t_29,rcv_byte           ;.
		call    ser_in
                cje     rcv_byte,#2ch,:com6     ;goto next field
                mov     t_30,rcv_byte           ;tents
		call    ser_in   
                cje     rcv_byte,#2ch,:com6     ;goto next field
                call    ser_in
                cje     rcv_byte,#2ch,:com6     ;goto next field
                call    ser_in
                cje     rcv_byte,#2ch,:com6     ;goto next field
                jmp     begin

:com6           call    ser_in                  ;input heading t_31 to t_35
                cje     rcv_byte,#2ch,:com7     ;goto next field
                mov     t_31,rcv_byte           ;hundreds
                call    ser_in
                cje     rcv_byte,#2ch,:com7     ;goto next field
                mov     t_32,rcv_byte           ;tens
                call    ser_in
                cje     rcv_byte,#2ch,:com7     ;goto next field
                mov     t_33,rcv_byte           ;ones
                call    ser_in
                cje     rcv_byte,#2ch,:com7     ;goto next field
                mov     t_34,rcv_byte           ;.
                call    ser_in
                cje     rcv_byte,#2ch,:com7     ;goto next field
                mov     t_35,rcv_byte           ;tenths

:com7           call    ser_in                  ;input date T_37 to T_42
                cje     rcv_byte,#2ch,:com9     ;goto next field
                mov     t_37,rcv_byte           ;day
                call    ser_in
                cje     rcv_byte,#2ch,:com9a    ;single character
                mov     t_38,rcv_byte           ;day
:com9           call    ser_in
                cje     rcv_byte,#2ch,:com10    ;goto next field
                mov     t_39,rcv_byte           ;month
                call    ser_in
                cje     rcv_byte,#2ch,:com10a   ;single character
                mov     t_40,rcv_byte           ;month
:com10          call    ser_in
                cje     rcv_byte,#2ch,:com11    ;goto next field
                call    ser_in   
                cje     rcv_byte,#2ch,:com11    ;goto next field
                call    ser_in
                cje     rcv_byte,#2ch,:com11    ;goto next field
:com11          call    ser_in
                cje     rcv_byte,#2ch,output
                mov     T_41,rcv_byte
                call    ser_in
                mov     T_42,rcv_byte
                call    ser_in
                cje     rcv_byte,#2ch,output
                mov     T_41,rcv_byte
                call    ser_in
                mov     T_42,rcv_byte
                jmp     output
                
                
:com9a          mov     t_38,t_37
                mov     t_37,#30h
                jmp     :com9

:com10a         mov     t_40,t_39
                mov     t_39,#30h
                jmp     :com10




:cr             call    ser_in
                cjne    rcv_byte,#0dh,:cr       ;goto next field

GGA                                             ;input status from GGA 
                mov     nogga,#14h              ;check up to 20 sentences 
                mov     t_36,#33h               ;quality n/a
:next           dec     nogga
                jz      output
:nextx          call    ser_in
                cjne    rcv_byte,#24h,:nextx    ;"$"
                call    ser_in
                cjne    rcv_byte,#47h,:nextx    ;"G"
                call    ser_in
                cjne    rcv_byte,#50h,:nextx    ;"P"
                call    ser_in
                cjne    rcv_byte,#47h,:next     ;"G"
                call    ser_in
                cjne    rcv_byte,#47h,:next     ;"G"
                call    ser_in
                cjne    rcv_byte,#41h,:next     ;"A"
                call    ser_in
                cjne    rcv_byte,#2Ch,:next     ;","
                
                mov     comms,#05h              ;count 5 commas
:comma          call    ser_in
                cjne    rcv_byte,#2ch,:comma    ;
                djnz    comms,:comma
:input          call    ser_in
                mov     T_43,rcv_byte           ;gps quality

                cjne    T_43,#30h,:next2        ;0
                mov     T_44,#44h               ;"D"
                mov     T_45,#52h               ;"R"
                mov     T_46,#20h               ;space
                mov     T_47,#20h               ;space
                jmp     output
:next2          cjne    T_43,#31h,:next3        ;1
                mov     T_44,#47h               ;"G"
                mov     T_45,#50h               ;"P"
                mov     T_46,#53h               ;"S"
                mov     T_47,#20h               ;space
                jmp     output
:next3          cjne    T_43,#32h,:next4
                mov     T_44,#44h               ;"D"
                mov     T_45,#47h               ;"G"
                mov     T_46,#50h               ;"P"
                mov     T_47,#53h               ;"S"
                jmp     output
:next4          mov     T_44,#58h               ;"X"
                mov     T_45,#58h               ;"X"
                mov     T_46,#58h               ;"X"
                mov     T_47,#58h               ;"X"
                jmp     output

                
          

                
                
         


ser_in          snb     serial_in       ;Detect start bit. Change to
					;sb serial_in if using 22k resistor
					;input. 
                jmp     ser_in

start_bit       call    start_delay     ;Wait one-half bit time to the middle
					;of the start bit. 
		
                jb      serial_in,ser_in

					;If the start bit is still good,
					;continue. Otherwise, resume waiting.
					;Change to jnb Serial_in, :start_bit
					;if using 22k resistor input. 

		mov     bit_cntr, #8    ;Set the counter to receive 8 data bits
		clr     rcv_byte        ;Clear the receive byte to get ready
					;for new data. 

:receive        call    bit_delay       ;Wait one bit time. 
                movb    c,serial_in     ;Put the data bit into carry. 
                                        ;Change to movb c,/serial_in if using
					;22k resistor input. 
		rr      rcv_byte        ;Rotate the carry bit into the receive
					;byte.
		djnz    bit_cntr,:receive       
					;Not eight bits yet? Get next bit.
                call    bit_delay       ;Wait for stop bit. 
                ret 

output          clrb    strobe
                mov     parout,T_10     ;lat T_10 to T_16
                call    strb
                mov     parout,T_11
                call    strb
                mov     parout,T_12
                call    strb
                mov     parout,T_13
                call    strb
                mov     parout,T_14     ;decimal
                call    strb
                mov     parout,T_15
                call    strb
                mov     parout,T_16
                call    strb
                mov     parout,#20h     ;space
                call    strb
                mov     parout,T_17     ;N/S
                call    strb
                mov     parout,#2ch     ;","
                call    strb
                mov     parout,#20h     ;space
                call    strb

                mov     parout,T_18     ;lon T_18 to T_25
                call    strb
                mov     parout,T_19
                call    strb
                mov     parout,T_20
                call    strb
                mov     parout,T_21  
                call    strb
                mov     parout,T_22
                call    strb
                mov     parout,T_23
                call    strb
                mov     parout,T_24
                call    strb
                mov     parout,T_25
                call    strb
                mov     parout,#20h     ;space
                call    strb
                mov     parout,T_26     ;E/W
                call    strb
                mov     parout,#2ch     ;","
                call    strb
                mov     parout,#20h     ;space
                call    strb

                mov     parout,#44h     ;"D"
                call    strb
                mov     parout,#41h     ;"A"
                call    strb
                mov     parout,#54h     ;"T"
                call    strb
                mov     parout,#45h     ;"E"
                call    strb
                mov     parout,#20h     ;space
                call    strb
                mov     parout,T_37     ;D
                call    strb
                mov     parout,T_38     ;D
                call    strb
                mov     parout,#2fh     ;"/"
                call    strb
                mov     parout,T_39     ;M
                call    strb
                mov     parout,T_40     ;M
                call    strb
                mov     parout,#2fh     ;"/"
                call    strb
                mov     parout,T_41     ;Y
                call    strb
                mov     parout,T_42     ;Y
                call    strb
                mov     parout,#2ch     ;","
                call    strb
                mov     parout,#20h     ;space
                call    strb

                mov     parout,#55h     ;"U"
                call    strb
                mov     parout,#54h     ;"T"
                call    strb
                mov     parout,#43h     ;"C"
                call    strb
                mov     parout,#20h     ;space
                call    strb

                mov     parout,T_1      ;time T_1 to T_9
                call    strb
                mov     parout,T_2
                call    strb
                mov     parout,T_3
                call    strb
                mov     parout,T_4
                call    strb
                mov     parout,T_5
                call    strb
                mov     parout,T_6
                call    strb
                mov     parout,T_7
                call    strb
                mov     parout,T_8
                call    strb
                mov     parout,T_9
                call    strb
                mov     parout,#2ch     ;","
                call    strb
                mov     parout,#20h     ;space
                call    strb

                mov     parout,#53h     ;"S"
                call    strb
                mov     parout,#4fh     ;"O"
                call    strb
                mov     parout,#47h     ;"G"
                call    strb
                mov     parout,#20h     ;space
                call    strb

                mov     parout,T_27     ;speed T_27 to T_30
                call    strb
                mov     parout,T_28
                call    strb
                mov     parout,T_29
                call    strb
                mov     parout,T_30
                call    strb
                mov     parout,#2ch     ;","
                call    strb
                mov     parout,#20h     ;space

                mov     parout,#48h     ;"H"
                call    strb
                mov     parout,#44h     ;"D"
                call    strb
                mov     parout,#47h     ;"G"
                call    strb
                mov     parout,#20h     ;space
                call    strb

                mov     parout,T_31     ;heading T_31 to T_35
                call    strb
                mov     parout,T_32
                call    strb
                mov     parout,T_33
                call    strb
                mov     parout,T_34
                call    strb
                mov     parout,T_35
                call    strb
                mov     parout,#2ch     ;","
                call    strb
                mov     parout,#20h     ;space
                call    strb

                mov     parout,T_44     ;status T_44 to T_47
                call    strb
                mov     parout,T_45
                call    strb
                mov     parout,T_46
                call    strb
                mov     parout,T_47
                call    strb
                mov     parout,#0dh     ;cr
                call    strb
                mov     parout,#0ah     ;lf
                call    strb

prntdelay       jnb     short,min2      ;jump to 2 minute delay
                jnb     long,hour       ;jump to 1 hour delay

min15           mov     minutes,#10h    ;15 minute delay
                jmp     wait

hour            mov     minutes,#3dh    ;60 minute delay
                jmp     wait

min2            mov     minutes,#03h    ;2 minte delay
                

wait            dec     minutes         ;decrement minutes and restart
                jz      begin           ;at 0

                mov     waitdly,#03fh
:wait2          nop
                mov     waitdly2,#31h
:wait3          nop
                call    outdelay
                djnz    waitdly2,:wait3
                djnz    waitdly,:wait2
                jmp     wait



strb            call    outdelay        ;printer strobe
                setb    strobe
                call    outdelay
                clrb    strobe
                ret
                
                

outdelay        mov     delay_cntr,#0ddh
:loop           nop
                djnz    delay_cntr,:loop
                jb      busy,outdelay
                ret
                


; This delay loop delays the correct time for the serial in routine

bit_delay       mov     delay_cntr,#bit_K       ;no overflow, delay and ret
:loop           nop
		djnz    delay_cntr,:loop
		ret

; This delay loop is identical to bit_delay above, but provides half the delay
; time. 

start_delay     mov     delay_cntr,#half_bit 
:loop           nop
		djnz    delay_cntr, :loop
		ret


Code:

Comments: