Nerdegutta's logo

nerdegutta.no

Read the GPRMC sentence

26.12.23

Embedded

How to read the RMC sentence from a gps.

This litte program reads the GPRMC sentence from a GPS module, and display it on a screen.

// INCLUDE LIBRARIES
#include
#include
#include
#include
#include

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF       // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = OFF         // Low-Voltage Programming Enable bit (RB4/PGM pin has PGM function, low-voltage programming enabled)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// DEFINITIONS
#define _XTAL_FREQ 16000000

// VARIABLES
unsigned char ch, i;
bool getchar_active = false;
char buffer[16];
char tmp_buffer[7];
char gprmc_header[]="GPRMC,";
unsigned char gps_rmc[60];

// FUNCTION PROTOTYPE
void uart_init();
void putch (char byte);
char getche(void);
char getch();
void __interrupt() tc_int (void);

// Function to initialize the uart port
void uart_init() {
    TXSTAbits.BRGH  = 1;    // High baud select bit, 1=high, 0=low
    TXSTAbits.SYNC  = 0;    // USART mode selection bit, 1=sync mode, 0=async mode
    TXSTAbits.TX9   = 0;    // 9-bit selection bit, 1=9-bit transmission, 0=8-bit transmission
    RCSTAbits.CREN  = 1;    // Continous receive enable bit, 1=enable continous receive

    /*
     * 16MHz
     * 16000000 / 9600 = 1666.666666
     * 1666.6666 / 16 = 104.1666
     * 104.1666 - 1 = 103
     */     

    SPBRG = 103;            // 9600-n-8-1   

    PIE1bits.RCIE   = 1;    // USART receive interrupt enable bit, 1=enable
    RCSTAbits.SPEN  = 1;    // Serial port enable bit, 1=enable
    TXSTAbits.TXEN  = 1;    // Transmit enable bit, 1=transmit enable
    return;

// Function to send a char to the usart port
void putch (char byte) {
    while (!TXSTAbits.TRMT);
    TXREG = byte;
    return;
}

// 
char getche(void) {
    unsigned char c;
    putch(c=getch());
    return c;
}

// Function to read a char from the uart port
char getch() {
    getchar_active = true;
    while (getchar_active)
        continue;
    return RCREG;
}

// interrupt function, get called on each received char
void __interrupt() tc_int (void) {
    if (RCIE && RCIF) {
        getchar_active = false;   
        *buffer=RCREG;
        //printf(buffer);           // Debug purpose only
    }
    return;
}

void main() {
    CMCON = 0x07;           // Turn Comparator Control register off  

    TRISA = 0b00000000;     // TRISA set to output
    PORTA = 0b00000000;     // PORTA set to low   

    TRISB = 0b00000110;     // RX & TX set to input
    PORTB = 0b00000000;     // PORTB set to low
    
    INTCONbits.PEIE = 1;    // Peripheral interrupt enable bit
    INTCONbits.GIE = 1;     // Global interrup enable bit 

    uart_init();            // Initialize the uart port

    while (1) {
        ch = getch();               // Assign  value to getch => Readthe uart port
        if (ch == '$'){             // Check if we have a $ sign
            for (i=0;i<6;i++) {     // Read the first 6 chars "GPRMC,"
                ch = getch();       // Read one char
                tmp_buffer[i] = ch; // Put char in array
            }

            if (strcmp(tmp_buffer, gprmc_header)==0) {  // Check if tmp_buffer == gprmc_buffer
                // Read the whole gprmc sentence
                for (i=0;i<61;i++) {
                    ch = getch();
                    gps_rmc[i] = ch;
                } // End for loop                

                putch(36); // Printing $-sign

                // Print the gprmc_header
                for (i=0;i<6;i++) {
                    putch(gprmc_header[i]);
                }

                // Print the rest of the sentence.
                for (i=0;i<61;i++) {
                    putch(gps_rmc[i]);
                }                
            } // End if
        } // End if
    } // End while
    return;
}

PIN 7 - RB1 is connected to a GPS module. Cheapest I could frin on Ebay.

PIN 8 - RB2 is connected to a TTL to USB converter and to the computer.

This is what the output looks like: