1. 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.
    Dismiss Notice

NMEA reader with Serial out

Discussion in 'Oshonsoft' started by camerart, Mar 26, 2016.

  1. camerart

    camerart Active Member

    Joined:
    Jun 12, 2008
    Messages:
    1,426
    Likes:
    11
    Location:
    Dorset UK.
    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 (bas):

    '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]
     

    Attached Files:

Share This Page