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