Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

NMEA reader with Serial out

Status
Not open for further replies.

camerart

Well-Known Member
Hi,

I've built an NMEA: LAT LON TIME ALT reader with TX, I can share.
It switches between LAT LON and TIME ALT, by pressing a button, and gets it's information from a GPS, such as a NEO-6 module, connected to a 16F648A PIC RX pin.
When button not pressed, it will output TX using two wires, Gnd and signal and needs an FTDI serial to USB adaptor to connect to a computer.
Have fun,
Camerart.

Code:
'PIC 16F648A 4MHz INT NMEA LCD 260316 0900
Define CONFIG = 0x3f50
Define CLOCK_FREQUENCY = 4
AllDigital
'Define SIMULATION_WAITMS_VALUE = 1  'SIMULATION ONLY
Define LCD_CHARS = 16
Define LCD_LINES = 2
Define LCD_BITS = 4  'allowed values are 4 and 8 - the number of data interface lines
Define LCD_DREG = PORTB
Define LCD_DBIT = 4  '0 or 4 for 4-bit interface, ignored for 8-bit interface
Define LCD_RSREG = PORTA
Define LCD_RSBIT = 2
Define LCD_EREG = PORTA
Define LCD_EBIT = 3
Define LCD_RWREG = PORTA  'set to 0 if not used, 0 is default
Define LCD_RWBIT = 5  'set to 0 if not used, 0 is default
Define LCD_COMMANDUS = 5000  'delay after LCDCMDOUT, default value is 5000
Define LCD_DATAUS = 100  'delay after LCDOUT, default value is 100
Define LCD_INITMS = 100  'delay used by LCDINIT, default value is 100
CMCON = 7
Hseropen 9600
'PORT A
TRISA.0 = 0  'Pin 17
TRISA.1 = 0  'Pin 18 as LED
TRISA.2 = 0  'Pin 1 as LCD RS
TRISA.3 = 0  'pin 2 as LCD E
TRISA.4 = 1  'Pin 3 as Button
TRISA.5 = 0  'Pin 4 as R/W
TRISA.6 = 0  'Pin 15
TRISA.7 = 0  'Pin 16
'PORT B
TRISB.0 = 0  'pin 6
TRISB.1 = 1  'pin 7 as RX GPS IN
TRISB.2 = 1  'pin 8 as TX out (Set as in)
TRISB.3 = 0  'pin 9
TRISB.4 = 0  'pin 10 as lcd data 4
TRISB.5 = 0  'pin 11 as lcd data 4
TRISB.6 = 0  'pin 12 as lcd data 4
TRISB.7 = 0  'pin 13 as lcd data 4
PORTB = 0xff
Lcdinit
Dim str1(70) As Byte
Dim char As Byte
Dim rxi As Byte
Dim txi As Byte
Dim ix As Byte  'NEW
Symbol button = PORTA.4  'Push for TIME
Symbol led = PORTA.1
Lcdcmdout LcdClear
Lcdcmdout LcdLine1Home
Lcdout "READY1  READY1"
Lcdcmdout LcdLine2Home
Lcdout "READY2  READY2"
get_neo:
If RCSTA.OERR = 1 Then  'if over run error then flush RXD buffer
RCSTA.CREN = 0
RCSTA.CREN = 1
char = RCREG
char = RCREG
PIR1.RCIF = 0
Endif
sync1:  'wait for a $ start of string
If PIR1.RCIF = 0 Then Goto sync1
char = RCREG
If char <> 0x24 Then Goto sync1  '$'
str1(1) = char
rxi = 2
getmsg:  'read and save GPGGA msg
If PIR1.RCIF = 0 Then Goto getmsg
char = RCREG
str1(rxi) = char
rxi = rxi + 1
If rxi > 80 Then Goto get_neo  'msg bfr over run
If char = 0x0a Then Goto eomsg
Goto getmsg
If rxi < 60 Then  'invalid msg
   Goto get_neo
Endif
eomsg:
If str1(5) = 0x47 Then  'G'
   If button = 0 Then Goto time
   Lcdcmdout LcdClear
   Lcdcmdout LcdLine1Home
   Lcdout "LA  "
   For txi = 18 To 29  'LAT
     Lcdout str1(txi)
   Next txi
   Lcdcmdout LcdLine2Home
   Lcdout "LO "
   For txi = 31 To 43  'LON
     Lcdout str1(txi)
   Next txi
   For ix = 1 To 72
     Hserout str1(ix)  'show msg
   Next ix
   Hserout 0x0d, 0x0a
Endif
Goto get_neo
time:
   Lcdcmdout LcdClear
   Lcdcmdout LcdLine1Home
   Lcdout "TIME "
   For txi = 8 To 13  'TIME
     Lcdout str1(txi)
   Next txi
   Lcdcmdout LcdLine2Home
   Lcdout "ALT  "
   For txi = 55 To 61  'ALT
     Lcdout str1(txi)
   Next txi
Goto get_neo
End
[code = asm]
; Compiled with: PIC Simulator IDE v7.27
; Microcontroller model: PIC16F648A
; Clock frequency: 4.0MHz
;
R0L EQU 0x020
R0H EQU 0x021
R3L EQU 0x026
R3H EQU 0x027
R4L EQU 0x028
R4H EQU 0x029
R0HL EQU 0x020
R3HL EQU 0x026
R4HL EQU 0x028
ARRARG_0 EQU 0x022
; The address of 'str1' (array 70) (byte) (global) is 0x02B
; The address of 'char' (byte) (global) is 0x024
; The address of 'rxi' (byte) (global) is 0x025
; The address of 'txi' (byte) (global) is 0x023
; The address of 'ix' (byte) (global) is 0x02A
; The address of 'button' (bit) (global) is 0x005,4
; The address of 'led' (bit) (global) is 0x005,1
ORG 0x0000
BCF PCLATH,4
BCF PCLATH,3
GOTO L0006
ORG 0x0004
RETFIE
; User code start
L0006:
; 1: 'PIC 16F648A 4MHz INT NMEA LCD 260316 0900
; 2: Define CONFIG = 0x3f50
; 3: Define CLOCK_FREQUENCY = 4
; 4: AllDigital
MOVLW 0x07
MOVWF CMCON
; 5: 'Define SIMULATION_WAITMS_VALUE = 1 'SIMULATION ONLY
; 6: Define LCD_CHARS = 16
; 7: Define LCD_LINES = 2
; 8: Define LCD_BITS = 4 'allowed values are 4 and 8 - the number of data interface lines
; 9: Define LCD_DREG = PORTB
; 10: Define LCD_DBIT = 4 '0 or 4 for 4-bit interface, ignored for 8-bit interface
; 11: Define LCD_RSREG = PORTA
; 12: Define LCD_RSBIT = 2
; 13: Define LCD_EREG = PORTA
; 14: Define LCD_EBIT = 3
; 15: Define LCD_RWREG = PORTA 'set to 0 if not used, 0 is default
; 16: Define LCD_RWBIT = 5 'set to 0 if not used, 0 is default
; 17: Define LCD_COMMANDUS = 5000 'delay after LCDCMDOUT, default value is 5000
; 18: Define LCD_DATAUS = 100 'delay after LCDOUT, default value is 100
; 19: Define LCD_INITMS = 100 'delay used by LCDINIT, default value is 100
; 20: CMCON = 7
MOVLW 0x07
MOVWF CMCON
; 21: Hseropen 9600
; exact baud rate achieved = 9615.385; bit period = 104µs; baud rate error = .16%
BSF STATUS,RP0
MOVLW 0x19
MOVWF SPBRG
BSF TRISB,1
BSF TRISB,2
MOVLW 0x24
MOVWF TXSTA
BCF STATUS,RP0
MOVLW 0x90
MOVWF RCSTA
; 22: 'PORT A
; 23: TRISA.0 = 0 'Pin 17
BSF STATUS,RP0
BCF TRISA,0
; 24: TRISA.1 = 0 'Pin 18 as LED
BCF TRISA,1
; 25: TRISA.2 = 0 'Pin 1 as LCD RS
BCF TRISA,2
; 26: TRISA.3 = 0 'pin 2 as LCD E
BCF TRISA,3
; 27: TRISA.4 = 1 'Pin 3 as Button
BSF TRISA,4
; 28: TRISA.5 = 0 'Pin 4 as R/W
BCF TRISA,5
; 29: TRISA.6 = 0 'Pin 15
BCF TRISA,6
; 30: TRISA.7 = 0 'Pin 16
BCF TRISA,7
; 31: 'PORT B
; 32: TRISB.0 = 0 'pin 6
BCF TRISB,0
; 33: TRISB.1 = 1 'pin 7 as RX GPS IN
BSF TRISB,1
; 34: TRISB.2 = 1 'pin 8 as TX out (Set as in)
BSF TRISB,2
; 35: TRISB.3 = 0 'pin 9
BCF TRISB,3
; 36: TRISB.4 = 0 'pin 10 as lcd data 4
BCF TRISB,4
; 37: TRISB.5 = 0 'pin 11 as lcd data 4
BCF TRISB,5
; 38: TRISB.6 = 0 'pin 12 as lcd data 4
BCF TRISB,6
; 39: TRISB.7 = 0 'pin 13 as lcd data 4
BCF TRISB,7
BCF STATUS,RP0
; 40: PORTB = 0xff
MOVLW 0xFF
MOVWF PORTB
; 41: Lcdinit
BCF PORTA,3
BCF PORTA,2
BCF PORTA,5
BSF STATUS,RP0
BCF TRISA,3
BCF TRISA,2
BCF TRISA,5
MOVLW 0x0F
ANDWF TRISB,F
BCF STATUS,RP0
MOVLW 0x64
MOVWF R0L
CLRF R0H
CALL W001
MOVLW 0x33
CALL LC00
MOVLW 0xE6
MOVWF R4L
MOVLW 0x03
MOVWF R4H
CALL DL02
MOVLW 0x33
CALL LC00
MOVLW 0x41
MOVWF R4L
CALL DL01
MOVLW 0x33
CALL LC00
MOVLW 0x41
MOVWF R4L
CALL DL01
MOVLW 0x22
CALL LC00
MOVLW 0x41
MOVWF R4L
CALL DL01
MOVLW 0x28
CALL LC02
MOVLW 0x0C
CALL LC02
MOVLW 0x01
CALL LC02
; 42: Dim str1(70) As Byte
; 43: Dim char As Byte
; 44: Dim rxi As Byte
; 45: Dim txi As Byte
; 46: Dim ix As Byte 'NEW
; 47: Symbol button = PORTA.4 'Push for TIME
; 48: Symbol led = PORTA.1
; 49: Lcdcmdout LcdClear
MOVLW 0x01
CALL LC02
; 50: Lcdcmdout LcdLine1Home
MOVLW 0x80
CALL LC02
; 51: Lcdout "READY1 READY1"
MOVLW 0x52
CALL LC01
MOVLW 0x45
CALL LC01
MOVLW 0x41
CALL LC01
MOVLW 0x44
CALL LC01
MOVLW 0x59
CALL LC01
MOVLW 0x31
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x52
CALL LC01
MOVLW 0x45
CALL LC01
MOVLW 0x41
CALL LC01
MOVLW 0x44
CALL LC01
MOVLW 0x59
CALL LC01
MOVLW 0x31
CALL LC01
; 52: Lcdcmdout LcdLine2Home
MOVLW 0xC0
CALL LC02
; 53: Lcdout "READY2 READY2"
MOVLW 0x52
CALL LC01
MOVLW 0x45
CALL LC01
MOVLW 0x41
CALL LC01
MOVLW 0x44
CALL LC01
MOVLW 0x59
CALL LC01
MOVLW 0x32
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x52
CALL LC01
MOVLW 0x45
CALL LC01
MOVLW 0x41
CALL LC01
MOVLW 0x44
CALL LC01
MOVLW 0x59
CALL LC01
MOVLW 0x32
CALL LC01
; 54: get_neo:
L0001:
; 55: If RCSTA.OERR = 1 Then 'if over run error then flush RXD buffer
BTFSS 0x018,1
GOTO L0007
; 56: RCSTA.CREN = 0
BCF RCSTA,4
; 57: RCSTA.CREN = 1
BSF RCSTA,4
; 58: char = RCREG
MOVF RCREG,W
MOVWF 0x024
; 59: char = RCREG
MOVF RCREG,W
MOVWF 0x024
; 60: PIR1.RCIF = 0
BCF PIR1,5
; 61: Endif
L0007:
; 62: sync1: 'wait for a $ start of string
L0002:
; 63: If PIR1.RCIF = 0 Then Goto sync1
BTFSC 0x00C,5
GOTO L0008
GOTO L0002
L0008:
; 64: char = RCREG
MOVF RCREG,W
MOVWF 0x024
; 65: If char <> 0x24 Then Goto sync1 '$'
MOVF 0x024,W
SUBLW 0x24
BTFSC STATUS,Z
GOTO L0009
GOTO L0002
L0009:
; 66: str1(1) = char
MOVF 0x024,W
MOVWF 0x02C
; 67: rxi = 2
MOVLW 0x02
MOVWF 0x025
; 68: getmsg: 'read and save GPGGA msg
L0003:
; 69: If PIR1.RCIF = 0 Then Goto getmsg
BTFSC 0x00C,5
GOTO L0010
GOTO L0003
L0010:
; 70: char = RCREG
MOVF RCREG,W
MOVWF 0x024
; 71: str1(rxi) = char
BCF STATUS,IRP
MOVF 0x025,W
ADDLW 0x2B
MOVWF FSR
MOVF 0x024,W
MOVWF INDF
; 72: rxi = rxi + 1
MOVF 0x025,W
ADDLW 0x01
MOVWF 0x025
; 73: If rxi > 80 Then Goto get_neo 'msg bfr over run
MOVF 0x025,W
SUBLW 0x50
BTFSC STATUS,C
GOTO L0011
GOTO L0001
L0011:
; 74: If char = 0x0a Then Goto eomsg
MOVF 0x024,W
SUBLW 0x0A
BTFSS STATUS,Z
GOTO L0012
GOTO L0004
L0012:
; 75: Goto getmsg
GOTO L0003
; 76: If rxi < 60 Then 'invalid msg
MOVLW 0x3C
SUBWF 0x025,W
BTFSC STATUS,C
GOTO L0013
; 77: Goto get_neo
GOTO L0001
; 78: Endif
L0013:
; 79: eomsg:
L0004:
; 80: If str1(5) = 0x47 Then 'G'
MOVF 0x030,W
SUBLW 0x47
BTFSS STATUS,Z
GOTO L0014
; 81: If button = 0 Then Goto time
BTFSC 0x005,4
GOTO L0015
GOTO L0005
L0015:
; 82: Lcdcmdout LcdClear
MOVLW 0x01
CALL LC02
; 83: Lcdcmdout LcdLine1Home
MOVLW 0x80
CALL LC02
; 84: Lcdout "LA "
MOVLW 0x4C
CALL LC01
MOVLW 0x41
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x20
CALL LC01
; 85: For txi = 18 To 29 'LAT
MOVLW 0x12
MOVWF 0x023
L0016:
MOVF 0x023,W
SUBLW 0x1D
BTFSS STATUS,C
GOTO L0017
; 86: Lcdout str1(txi)
BCF STATUS,IRP
MOVF 0x023,W
ADDLW 0x2B
MOVWF FSR
MOVF INDF,W
CALL LC01
; 87: Next txi
MOVLW 0x01
ADDWF 0x023,F
BTFSS STATUS,C
GOTO L0016
L0017:
; 88: Lcdcmdout LcdLine2Home
MOVLW 0xC0
CALL LC02
; 89: Lcdout "LO "
MOVLW 0x4C
CALL LC01
MOVLW 0x4F
CALL LC01
MOVLW 0x20
CALL LC01
; 90: For txi = 31 To 43 'LON
MOVLW 0x1F
MOVWF 0x023
L0018:
MOVF 0x023,W
SUBLW 0x2B
BTFSS STATUS,C
GOTO L0019
; 91: Lcdout str1(txi)
BCF STATUS,IRP
MOVF 0x023,W
ADDLW 0x2B
MOVWF FSR
MOVF INDF,W
CALL LC01
; 92: Next txi
MOVLW 0x01
ADDWF 0x023,F
BTFSS STATUS,C
GOTO L0018
L0019:
; 93: For ix = 1 To 72
MOVLW 0x01
MOVWF 0x02A
L0020:
MOVF 0x02A,W
SUBLW 0x48
BTFSS STATUS,C
GOTO L0021
; 94: Hserout str1(ix) 'show msg
BCF STATUS,IRP
MOVF 0x02A,W
ADDLW 0x2B
MOVWF FSR
MOVF INDF,W
CALL HS01
; 95: Next ix
MOVLW 0x01
ADDWF 0x02A,F
BTFSS STATUS,C
GOTO L0020
L0021:
; 96: Hserout 0x0d, 0x0a
MOVLW 0x0D
CALL HS01
MOVLW 0x0A
CALL HS01
; 97: Endif
L0014:
; 98: Goto get_neo
GOTO L0001
; 99: time:
L0005:
; 100: Lcdcmdout LcdClear
MOVLW 0x01
CALL LC02
; 101: Lcdcmdout LcdLine1Home
MOVLW 0x80
CALL LC02
; 102: Lcdout "TIME "
MOVLW 0x54
CALL LC01
MOVLW 0x49
CALL LC01
MOVLW 0x4D
CALL LC01
MOVLW 0x45
CALL LC01
MOVLW 0x20
CALL LC01
; 103: For txi = 8 To 13 'TIME
MOVLW 0x08
MOVWF 0x023
L0022:
MOVF 0x023,W
SUBLW 0x0D
BTFSS STATUS,C
GOTO L0023
; 104: Lcdout str1(txi)
BCF STATUS,IRP
MOVF 0x023,W
ADDLW 0x2B
MOVWF FSR
MOVF INDF,W
CALL LC01
; 105: Next txi
MOVLW 0x01
ADDWF 0x023,F
BTFSS STATUS,C
GOTO L0022
L0023:
; 106: Lcdcmdout LcdLine2Home
MOVLW 0xC0
CALL LC02
; 107: Lcdout "ALT "
MOVLW 0x41
CALL LC01
MOVLW 0x4C
CALL LC01
MOVLW 0x54
CALL LC01
MOVLW 0x20
CALL LC01
MOVLW 0x20
CALL LC01
; 108: For txi = 55 To 61 'ALT
MOVLW 0x37
MOVWF 0x023
L0024:
MOVF 0x023,W
SUBLW 0x3D
BTFSS STATUS,C
GOTO L0025
; 109: Lcdout str1(txi)
BCF STATUS,IRP
MOVF 0x023,W
ADDLW 0x2B
MOVWF FSR
MOVF INDF,W
CALL LC01
; 110: Next txi
MOVLW 0x01
ADDWF 0x023,F
BTFSS STATUS,C
GOTO L0024
L0025:
; 111: Goto get_neo
GOTO L0001
; 112: End
L0026: GOTO L0026
; End of user code
L0027: GOTO L0027
;
;
; Delay Routine Byte
; minimal routine execution time: 8µs
; routine execution time step: 3µs
; maximal routine execution time: 770µs
DL01:
DECFSZ R4L,F
GOTO DL01
RETURN
; Delay Routine Word
; minimal routine execution time: 15µs
; routine execution time step: 10µs
; maximal routine execution time: 655365µs
DL02:
MOVLW 0x01
SUBWF R4L,F
CLRW
BTFSS STATUS,C
ADDLW 0x01
SUBWF R4H,F
BTFSS STATUS,C
RETURN
GOTO DL02
; Waitms Routine
W001: MOVLW 0x01
SUBWF R0L,F
CLRW
BTFSS STATUS,C
ADDLW 0x01
SUBWF R0H,F
BTFSS STATUS,C
RETURN
MOVLW 0x61
MOVWF R4L
MOVLW 0x00
MOVWF R4H
CALL DL02
GOTO W001
; Lcdout Routine
LC01:
MOVWF R3L
BSF PORTA,2
BCF PORTA,5
MOVF PORTB,W
MOVWF R3H
CALL LCX6
MOVWF PORTB
CALL LCX1
MOVF PORTB,W
MOVWF R3H
SWAPF R3L,F
CALL LCX6
MOVWF PORTB
CALL LCX1
MOVLW 0x1F
MOVWF R4L
CALL DL01
RETURN
LCX6:
MOVLW 0x0F
ANDWF R3H,F
MOVF R3L,W
ANDLW 0xF0
IORWF R3H,W
RETURN
LCX1:
BSF PORTA,3
NOP
BCF PORTA,3
NOP
RETURN
; Lcdinit Routine
LC00:
BCF PORTA,2
BCF PORTA,5
MOVWF R3L
MOVF PORTB,W
MOVWF R3H
CALL LCX6
MOVWF PORTB
CALL LCX1
RETURN
; Lcdcmdout Routine
LC02:
MOVWF R3L
BCF PORTA,2
BCF PORTA,5
MOVF PORTB,W
MOVWF R3H
CALL LCX6
MOVWF PORTB
CALL LCX1
MOVF PORTB,W
MOVWF R3H
SWAPF R3L,F
CALL LCX6
MOVWF PORTB
CALL LCX1
MOVLW 0xF2
MOVWF R4L
MOVLW 0x01
MOVWF R4H
CALL DL02
RETURN
; Hardware Serial Communication Routines
HS01:
BTFSC PIR1,TXIF
GOTO HS02
GOTO HS01
HS02: MOVWF TXREG
RETURN
HS10:
BTFSC PIR1,RCIF
GOTO HS11
GOTO HS10
HS11: MOVF RCREG,W
RETURN
;
;
; Configuration settings
ORG 0x2007
DW 0x3F50
; End of listing
END
[/code]
 

Attachments

  • 16F648A LCD pinouts.jpg
    16F648A LCD pinouts.jpg
    11.4 KB · Views: 321
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top