MTK MT33xx型GPS的NMEA协议解析实例
1)解析实现
gps_main.c
#include <nmea/nmea.h> #include <string.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include "nrf_gpio.h" #include "gps_main.h" #include "main.h" #define GPS_PIN 27 static struct gps_t { char buf[100]; uint8_t index; enum gps_state_t { GPS_NULL, START, PAYLOAD, END, } gps_state; } gps; void gps_on(void) { nrf_gpio_cfg_output(GPS_PIN); nrf_gpio_pin_set(GPS_PIN); memset(gps.buf,0,sizeof(char)*100); gps.gps_state = START; gps.index = 0; } void gps_off(void) { nrf_gpio_pin_clear(GPS_PIN); } void gps_buf_fill_data(uint8_t cr) { switch (gps.gps_state) { case START: if(cr == '$') { gps.buf[gps.index++] = cr; gps.gps_state = PAYLOAD; } else gps.gps_state = START; break; case PAYLOAD: if(cr == '\r') { gps.gps_state = END; } gps.buf[gps.index++] = cr; break; case END: if(cr == '\n') { if( xSemaphoreGive( gpsSemaphore ) != pdTRUE ) { } gps.buf[gps.index] = cr; } break; default: break; } } void gps_thread(void * arg) { nmeaINFO info; nmeaPARSER parser; int size_nmeaINFO = sizeof(nmeaINFO); int size_nmeaPARSER = sizeof(nmeaPARSER); nmea_zero_INFO(&info); nmea_parser_init(&parser); static uint8_t gps_nmea_scanning = 0; static int inuse_value = 0; static int inview_value = 0; gps_on(); for (;;) { if( xSemaphoreTake( gpsSemaphore, ( TickType_t ) 0 ) ) { switch (gps_nmea_scanning) { case 0: if(strstr(gps.buf,"$GPRMC")!=NULL) { if ((nmea_parse(&parser, (char*)gps.buf, (int)strlen((char*)gps.buf), &info)) > 0 ) { printf("inuse %d\r\n",inuse_value); printf("inview %d\r\n",inview_value); printf("sig %d\r\n",info.sig); printf("fix %d\r\n",info.fix); printf("year %d\r\n",info.utc.year); printf("mon %d\r\n",info.utc.mon); printf("day %d\r\n",info.utc.day); printf("hour %d\r\n",info.utc.hour); printf("min %d\r\n",info.utc.min); printf("sec %d\r\n",info.utc.sec); printf("lon %.5f\r\n",info.lon); printf("lat %.5f\r\n",info.lat); printf("speed %.2f\r\n",info.speed); } gps_nmea_scanning = 1; } break; case 1: if(strstr(gps.buf,"$GPGGA")!=NULL) { /* MTK的GPS模组GPGGA协议内容是14项,nmealib库是解析的12项,这里手动解算inuse if ((nmea_parse(&parser, (char*)gps.buf, (int)strlen((char*)gps.buf), &info)) > 0 ) */ char inuse_buf[3]; int count = 0, index = 0; for (index = 0; index < strlen(gps.buf); ++index) { if (gps.buf[index] == ',') ++count; if (count == 7) break; } strncpy(inuse_buf, &gps.buf[index+1], 2); int n = atoi(inuse_buf); inuse_value = n; gps_nmea_scanning = 2; } break; case 2: if(strstr(gps.buf,"$GPGSV")!=NULL) { if ((nmea_parse(&parser, (char*)gps.buf, (int)strlen((char*)gps.buf), &info)) > 0 ) { inview_value = info.satinfo.inview; } gps_nmea_scanning = 0; } break; default: break; } memset(gps.buf,0,sizeof(char)*100); gps.index = 0; gps.gps_state = START; } } }
gps_main.h
#ifndef GPS_MAIN_H__ #define GPS_MAIN_H__ #include <stdint.h> void gps_on(void); void gps_off(void); void gps_buf_fill_data(uint8_t cr); void gps_thread(void * arg); #endif
2)在串口接收函数中填充GPS缓存即可
gps_buf_fill_data(cr);
3)附件demo打包下载https://files.cnblogs.com/files/dong1/gps.rar
end