添加nmea0183协议解析
authorSnickerSun <snickersun@163.com>
Sun, 22 Dec 2024 14:00:32 +0000 (22:00 +0800)
committerSnickerSun <snickersun@163.com>
Sun, 22 Dec 2024 14:00:32 +0000 (22:00 +0800)
code/sdk/zhihui/services/gnss/CMakeLists.txt
code/sdk/zhihui/services/gnss/inc/NMEA0183.h [new file with mode: 0644]
code/sdk/zhihui/services/gnss/sample/gnss_sample/gnss_sample.c
code/sdk/zhihui/services/gnss/src/NMEA0183.c
code/sdk/zhihui/services/gnss/src/NMEA0183.h [deleted file]
code/sdk/zhihui/services/gnss/src/decodenmea.c [new file with mode: 0644]

index 35b4049..8516172 100644 (file)
@@ -11,6 +11,7 @@ set(SOURCES
     # ${CMAKE_CURRENT_SOURCE_DIR}/gnss_config_array.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/uart_gnss.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/gnss_ctl.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/NMEA0183.c
     ${TIOT_SRC_LIST}
 )
 set(PUBLIC_HEADER
@@ -23,7 +24,7 @@ set(PUBLIC_DEFINES
     CONFIG_GNSS_WAKEUP_TYPE_UART=1
     CONFIG_GNSS_TCXO_FREQ_26M=1
     CONFIG_GNSS_UART_BAUDRATE=115200
-    CONFIG_GNSS_UART_WITH_FLOWCTRL
+    # CONFIG_GNSS_UART_WITH_FLOWCTRL
     CONFIG_FILE_BY_ARRAY=1
     CONFIG_FIRMWARE_CFG_HANDLE_PRIV=1
     CONFIG_FIRMWARE_FILE_READ_BUF_LEN=1029
diff --git a/code/sdk/zhihui/services/gnss/inc/NMEA0183.h b/code/sdk/zhihui/services/gnss/inc/NMEA0183.h
new file mode 100644 (file)
index 0000000..17febca
--- /dev/null
@@ -0,0 +1,234 @@
+/*\r
+*                              GPS NMEA0183协议简要解析框架 \r
+*      \r
+*      支持解析 RMC、GGA、VTG、HDT等消息字段信息,由于解析框架比较明了,\r
+*   移植源码者可自行考虑添加新的解析代码。\r
+*   解析方式采用逐个字段解析的方式,能很大程度上节省消耗内存空间。 \r
+*   重新编写数据转换函数,不依赖外部库,移植时一般只需包含NMEA0183.h\r
+*   文件即可。 \r
+*\r
+*   代码示例:\r
+*      \r
+               char nmea[] = \\r
+               "$GNRMC,102219.00,A,2239.11578,N,11406.59325,E,0.009,,291018,,,D*62\r\n"\\r
+               "$GNVTG,,T,,M,0.009,N,0.017,K,D*37\r\n"\\r
+               "$GNGGA,102220.00,2239.11583,N,11406.59338,E,2,09,1.30,112.7,M,-2.3,M,,0000*52\r\n";\r
+               \r
+$GPGGA,,,,,,0,,,,,,,,*66\r
+\r
+$GPGLL,,,,,,V,N*64\r
+\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+\r
+$GPRMC,,V,,,,,,,,,E,N,V*6C\r
+\r
+$GPVTG,,T,,M,,N,,K,N*2C\r
+\r
+$GPZDA,,,,,00,00*48\r
+\r
+$PNTH000,13,,-87,0,,,,,1,1*22\r
+\r
+$PNTH001,0.000000,0.00,0.00,300000.00,1,0,0*1D\r
+\r
+$PNTH002,,T,0.000000,0,200,0.000000,3,0.000000*4B\r
+\r
+\r
+               gps_nmea gps_nmea_temp;   /// 定义解析时用到的暂存状态数据,只供解析时使用 \r
+               gps_data gps_data1;       /// GPS解析得到的最终数据,用户可使用 \r
+               unsigned int index = 0;\r
+               \r
+               for(index=0; index<sizeof(nmea); ++index)\r
+               {\r
+                       if(nmea_decode(&gps_nmea_temp, &gps_data1, nmea[index])) ///调用解析函数\r
+                       {\r
+                               /// 解析消息段成功 \r
+                               ... \r
+                       } \r
+               } \r
+               \r
+*   NMEA0183解析代码思想来源于开源飞控代码(Ardupilot),所以该份代码开源,可免费使用。\r
+*   ( 如有Bug,望能反馈 ! QQ: 2281280195 ) \r
+*       \r
+*   作者: ouyanglei        时间:2018-11-16\r
+*/\r
+\r
+\r
+#ifndef NMEA0183_H\r
+#define NMEA0183_H\r
+\r
+/*************** 宏定义  *******************/ \r
+#define current_time_ms() 1\r
+\r
+#define GPS_LEAPSECONDS_MILLIS 18000UL\r
+#define AP_SEC_PER_WEEK   (7UL * 86400UL)\r
+\r
+/* 检查字符串是否为数字0-9 */ \r
+#define IS_DIGITAL(x) ( ((x)>='0'&&(x)<='9')||(x)=='-'||(x)=='.' )\r
+#define CHAR_TO_DIGITAL(x) ((x)-'0')\r
+#define DIGITAL_TO_CHAR(x) ( (x)+'0' )\r
+\r
+/**************** 枚举量定义 ***************/\r
+    typedef enum _sentence_types \r
+       {   /* 每个枚举量表示该字段的起始位置,有些特殊字段需要10个字段域 */ \r
+        GPS_SENTENCE_RMC = 32,     /* RMC字段 推荐的最少专用导航数据。*/\r
+        GPS_SENTENCE_GGA = (32*2),             /* GGA字段 接收机定位数据。*/\r
+        GPS_SENTENCE_GSV = (32*3),             /* GSV字段 可见卫星数据。*/\r
+        GPS_SENTENCE_GSA = (32*4),             /* GSA字段 有效卫星与精度因子数据。*/\r
+        GPS_SENTENCE_GLL = (32*5),             /* GLL字段 接收机地理位置数据。*/\r
+        GPS_SENTENCE_VTG = (32*6),             /* VTG字段 对地速度与航向数据。*/\r
+        // GPS_SENTENCE_HDT = (32*7),    /* HDT字段 */\r
+        GPS_SENTENCE_ZDA = (32*7),             /* ZDA字段 时间与日期数据。*/\r
+               GPS_SENTENCE_TH000 = (32*8),    /* 接收机前端增益信息。*/\r
+               GPS_SENTENCE_TH001 = (32*9),    /* 接收机定位质量信息。*/\r
+               GPS_SENTENCE_TH002 = (32*10),   /* 接收机功耗模式信息。*/\r
+        GPS_SENTENCE_OTHER = 0     /* 默认没有字段 */\r
+    }sentence_types;\r
+\r
+/**************** 结构体定义 ***************/    \r
+    /* GPS定位状态枚举量 */ \r
+    typedef enum _gps_status\r
+       {\r
+        NO_GPS = 0,              /* 无GPS */\r
+        NO_FIX,                  /* 接收到GPS信息,但没有定位 */\r
+        GPS_OK_FIX_2D,           /* 2D定位 */\r
+        GPS_OK_FIX_3D,           /* 3D定位 */ \r
+        GPS_OK_FIX_3D_DGPS,      /* 优于3D定位 */ \r
+        GPS_OK_FIX_3D_RTK_FLOAT, /* RTK浮点解状态 */ \r
+        GPS_OK_FIX_3D_RTK_FIXED, /* RTK固定解状态 */\r
+    }gps_status;\r
+    \r
+\r
+/**\r
+ * \r
+BDS, //        GB\r
+GPS, //        GP\r
+Galileo,//     GA\r
+GLONASS,//     GL\r
+QZSS,//        GQ\r
+\r
+signal                         systemID                signalID\r
+GPS L1C/A              1                               1 \r
+GLONASS L1OF   2                               1 \r
+Galileo E1C    3                               7 \r
+BDS B1i                        4                               1 \r
+QZSS L1C/A             5                               1\r
+\r
+卫星编号\r
+\r
+GNSS                   "NMEA svid range" "GNSS PRN range" "PRN to svid"\r
+GPS L1C/A              1~32                          1~32                  PRN+0\r
+GLONASS L1OF   65~88                                 1~24                  PRN+64\r
+Galileo E1C    1~36                          1~36                  PRN+0\r
+BDS B1i                1~50                          1~50                  PRN+0\r
+QZSS L1C/A             1~4                           193~196               PRN-192\r
+\r
+*/\r
+       typedef enum _location_system\r
+       {\r
+               GNSS,                   //GN\r
+               GPS_L1C_A=1,    //GP\r
+               GLONASS_L1OF,   //GL\r
+               Galileo_E1C,    //GA\r
+               BDS_Bli,                //GB\r
+               QZSS_L1C_A,     //GQ\r
+               MAX_LOCATION_SYSTEM\r
+       } location_system_t;\r
+\r
+       typedef struct _start\r
+       {\r
+               unsigned char starID;\r
+               unsigned char snr;\r
+       }start_stat_t;\r
+\r
+    /* GPS点位置 */ \r
+    typedef struct _location \r
+       {\r
+           int alt:24;         /* 海拔高度 meters * 100  单位为厘米 */\r
+           float lat;            /* 纬度 *  暂时不乘以10**7,原始保存*/\r
+           float lng;            /* 精度 *  暂时不乘以10**7,原始保存*/\r
+       }Location;\r
+    \r
+    /* 数据解析状态结构体定义 */\r
+    typedef struct _gps_nmea\r
+    {\r
+       /* 数据解析状态 */ \r
+       unsigned char parity;                      /* 校验计算和 */ \r
+       unsigned char is_checksum_term;    /* 当前字段域为校验字 */\r
+       char term[15];                             /* 当前字段域缓冲区,','为字段域分割符 */\r
+               unsigned char location_system;          /* 字段类别,location_system_t gps_type, 北斗,GPS,GNSS,GLONASS 等*/\r
+       unsigned char term_number;         /* 当前字段域序号 */\r
+       unsigned char term_offset;         /* 字段域数据偏移量 */\r
+       unsigned char gps_data_good;       /* GPS数据有效状态 */\r
+       unsigned int  sentence_type;       /* 字段类别,见枚举 sentence_types*/\r
+       /* 数据解析结果 */\r
+       unsigned int new_time;                  /* UTC时间 */\r
+       unsigned int new_date;                  /* UTC日期 */\r
+       float new_latitude;                             /* 纬度 */\r
+       float new_longitude;                            /* 经度 */\r
+       int new_altitude;                               /* 海拔高度 cm*/\r
+       float new_speed;                                /* 地速 km/h */\r
+       float new_course;                               /* RMC、VTG字段磁偏角信息*/\r
+       float new_gps_yaw;                              /* HDT航向信息 */\r
+       unsigned short new_hdop;                /* 水平精度 *100 */\r
+       unsigned char new_satellite_count;      /* 当前使用卫星的颗数 */\r
+       unsigned char new_quality_indicator;    /* 定位状态 */\r
+       unsigned int last_RMC_ms;                   /* 最后更新字段时间 */\r
+       unsigned int last_GGA_ms;\r
+       unsigned int last_VTG_ms;\r
+               unsigned int last_HDT_ms;\r
+               unsigned int last_GSV_ms;\r
+               unsigned int last_GSA_ms;\r
+               unsigned int last_GLL_ms;\r
+               unsigned int last_ZDA_ms;\r
+               start_stat_t starts[20];\r
+               unsigned int gsvpagecount;\r
+               unsigned int gsvpage;\r
+               unsigned int startnum;\r
+       }gps_nmea;\r
+       \r
+       /* 时间结构体 */ \r
+       typedef struct _time\r
+       {\r
+               unsigned char year;\r
+               unsigned short int month : 4;\r
+               unsigned short int  : 4;\r
+               unsigned short int day : 5;\r
+               unsigned short int week : 3;\r
+       }DateTime;\r
+       \r
+       /* GPS数据区域,供上层应用调用 */ \r
+       typedef struct _gps_data {\r
+        unsigned char instance;                   /* GPS实例个数 */ \r
+        gps_status status;                 /* GPS定位状态 */\r
+        Location location;                 /* GPS定位到的当前位置 */\r
+        DateTime date_time; \r
+               start_stat_t starts[20];\r
+               unsigned int startnum;\r
+        float ground_speed;                /* 地速  m/s */\r
+        float ground_course;               /* 地速航向  度  顺时针 0-360 */ \r
+        float gps_yaw;                     /* GPHDT字段航向信息 一般用于双天线测向 */\r
+        unsigned short hdop;               /* 水平精度  cm */\r
+        unsigned short vdop;               /* 垂直精度  cm */\r
+        unsigned char num_sats;            /* 可见卫星颗数 */\r
+        unsigned char have_gps_yaw;        /* GPHDT航向字段有效 */\r
+        unsigned int last_gps_time_ms;     /* 最后获取GPS信息时的时间  ms */\r
+    }gps_data;\r
+    \r
+    /* NMEA0183结构体对象 */\r
+    typedef struct _nmea0183\r
+       {\r
+               gps_nmea gpsParse;\r
+               gps_data gpsData;\r
+               unsigned char (*nmea_decode)(struct _nmea0183* pnmea, char c);          \r
+       }NMEA0183; \r
+    \r
+/**************** 函数定义 ***************/\r
+\r
+unsigned char nmea_decode(NMEA0183* pnmea, char c);\r
+char* get_gps_status_str(gps_status status);\r
+char* get_gps_sentence_type_str(sentence_types sentencetype);\r
+void dump_location_data(gps_data *locationdata);\r
+\r
+#endif\r
+\r
+\r
index 18e1d8a..b2ee187 100644 (file)
@@ -109,7 +109,7 @@ static int32_t QryVersion(tiot_handle handle)
 \r
 static const GnssSamplesCfgTable g_gnssSamplesCfg[] = {\r
     {COLDSTART_FIXMODEGPS_NMEAALL_SAMPLE,        CfgColdStartFixModeGpsNmeaAll},\r
-    {AUTOSTART_FIXMODEALL_NMEADEF_SAMPLE,        CfgAutoStartFixModeAllNmeaDefault}\r
+    // {AUTOSTART_FIXMODEALL_NMEADEF_SAMPLE,        CfgAutoStartFixModeAllNmeaDefault}\r
 };\r
 \r
 static int32_t StartGnss(tiot_handle handle)\r
@@ -139,6 +139,27 @@ static int32_t StopGnss(tiot_handle handle)
     return 1;\r
 }\r
 \r
+#include "NMEA0183.h"\r
+NMEA0183 g_nmeadata={0};\r
+gps_data g_global_gpsData={0};\r
+static int decode_nmea(char c)\r
+{\r
+    int ret=0;\r
+    if(nmea_decode(&g_nmeadata,c) ) ///调用解析函数\r
+    {\r
+        // dump_nmea_str(&(g_nmeadata.gpsParse));\r
+        if (g_nmeadata.gpsParse.sentence_type == GPS_SENTENCE_TH002)\r
+        {\r
+            //一组数据最后一条\r
+            memcpy_s(&g_global_gpsData,sizeof(gps_data),&(g_nmeadata.gpsData),sizeof(gps_data));\r
+            ret = 1;\r
+            memset(&g_nmeadata,0,sizeof(g_nmeadata));\r
+        }\r
+    } \r
+\r
+    return ret;\r
+}\r
+\r
 static void ListenGnssData(tiot_handle handle)\r
 {\r
     int32_t i = 0;\r
@@ -150,8 +171,16 @@ static void ListenGnssData(tiot_handle handle)
             uint16_t *type = (uint16_t *)g_gnssServiceBuff;\r
             if (type[0] == MSG_TYPE_ASCII) {\r
                 g_gnssServiceBuff[ret] = '\0';\r
-                printf("%s\n", (char *)&g_gnssServiceBuff[MSG_CONTENT_IDX]);\r
-                fprintf(g_gnssLogFp, "%s\n", (char *)&g_gnssServiceBuff[MSG_CONTENT_IDX]);\r
+                char* pbuf=(char *)&g_gnssServiceBuff[MSG_CONTENT_IDX];\r
+                printf("%s\n", pbuf);\r
+                fprintf(g_gnssLogFp, "%s\n", pbuf);\r
+                for (int index=0;index < ret ;index++)\r
+                {\r
+                    if (decode_nmea(pbuf[index]))\r
+                    {\r
+                        dump_location_data(&g_global_gpsData);\r
+                    }\r
+                }\r
             }\r
             i++;\r
         }\r
index 959db44..b772c41 100644 (file)
@@ -1,6 +1,6 @@
 \r
 #include "NMEA0183.h"\r
-\r
+#include <stdio.h>\r
 static short int from_hex(char a);\r
 static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata);\r
 static int sring_to_int(const char* pstr, unsigned char* b);\r
@@ -12,7 +12,7 @@ static double string_to_float(const char* pstr, unsigned char* b);
 static int sring_to_int(const char* pstr, unsigned char* b); \r
 static int make_date_time(gps_data* pdata, unsigned int date, unsigned int time);\r
 \r
-/* GPSÊý¾Ý½âÎö */ \r
+/* GPS数据解析 */ \r
 unsigned char nmea_decode(NMEA0183* nmea, char c)\r
 {\r
     unsigned char valid_sentence = 0;\r
@@ -21,7 +21,7 @@ unsigned char nmea_decode(NMEA0183* nmea, char c)
 \r
     switch (c) \r
        {\r
-           case ',':  /* ×Ö¶ÎÓò·Ö¸î·ûºÅ */ \r
+           case ',':  /* 字段域分割符号 */ \r
                nmea->gpsParse.parity ^= c;\r
                /* no break */\r
            case '\r':\r
@@ -34,10 +34,10 @@ unsigned char nmea_decode(NMEA0183* nmea, char c)
                }\r
                ++nmea->gpsParse.term_number;\r
                nmea->gpsParse.term_offset = 0;\r
-               nmea->gpsParse.is_checksum_term = (c == '*');   /* ºóÃæÁ½¸ö×Ö½ÚΪУÑé×ֶΠ*/ \r
+               nmea->gpsParse.is_checksum_term = (c == '*');   /* 后面两个字节为校验字段 */ \r
                return valid_sentence;\r
        \r
-           case '$': /* ×Ö¶ÎÐÅÏ¢¿ªÊ¼ */ \r
+           case '$': /* 字段信息开始 */ \r
                nmea->gpsParse.term_number = nmea->gpsParse.term_offset = 0;\r
                nmea->gpsParse.parity = 0;\r
                nmea->gpsParse.sentence_type = GPS_SENTENCE_OTHER;\r
@@ -46,7 +46,7 @@ unsigned char nmea_decode(NMEA0183* nmea, char c)
                return valid_sentence;\r
     }\r
 \r
-    /* ±£´æ×Ö¶ÎÓòÊý¾Ý */\r
+    /* 保存字段域数据 */\r
     if (nmea->gpsParse.term_offset < sizeof(nmea->gpsParse.term) - 1)\r
         nmea->gpsParse.term[nmea->gpsParse.term_offset++] = c;\r
     if (!nmea->gpsParse.is_checksum_term)\r
@@ -55,7 +55,7 @@ unsigned char nmea_decode(NMEA0183* nmea, char c)
     return valid_sentence;\r
 }\r
 \r
-/* µ¥¸öÊ®Áù½øÖÆ×Ö·ûת»»ÎªÊ®½øÖÆ */\r
+/* 单个十六进制字符转换为十进制 */\r
 static short int from_hex(char a)\r
 {\r
     if (a >= 'A' && a <= 'F')\r
@@ -66,7 +66,7 @@ static short int from_hex(char a)
         return a - '0';\r
 }\r
 \r
-/* ´¦Àíµ¥¸ö×Ö¶ÎÓòÊý¾Ý */\r
+/* 处理单个字段域数据 */\r
 static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata)\r
 {\r
        if((void*)0==pnmea || (void*)0==pdata) return 0;\r
@@ -75,7 +75,7 @@ static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata)
        {\r
         unsigned char checksum = 16 * from_hex(pnmea->term[0]) + from_hex(pnmea->term[1]);\r
         \r
-        /* ¼ìÑéÐÅÏ¢¶ÎÊÇ·ñÍêÕûÎÞ´í£¬Èç¹ûУÑéͨ¹ý£¬Ôò½«½âÎöµÃµ½µÄÊý¾Ý±£´æ£¬²¢Ìṩ¸øÓû§µ÷ÓÃ*/\r
+        /* 检验信息段是否完整无错,如果校验通过,则将解析得到的数据保存,并提供给用户调用*/\r
         if (checksum == pnmea->parity) \r
                {\r
             if (pnmea->gps_data_good) \r
@@ -138,11 +138,38 @@ static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata)
 \r
                            // VTG has no fix indicator, can't change fix status\r
                            break;\r
-                       case GPS_SENTENCE_HDT:\r
-                                                pnmea->last_HDT_ms = now;\r
-//                                              pdata->gps_yaw = wrap_360(pnmea->new_gps_yaw*0.01f);\r
-                                                pdata->have_gps_yaw = 1;\r
-                                                break;\r
+//                     case GPS_SENTENCE_HDT:\r
+//                                              pnmea->last_HDT_ms = now;\r
+// //                                           pdata->gps_yaw = wrap_360(pnmea->new_gps_yaw*0.01f);\r
+//                                              pdata->have_gps_yaw = 1;\r
+//                                              break;\r
+                                       case GPS_SENTENCE_GSA:\r
+                           pnmea->last_GSA_ms = now;\r
+                           //time                        = _new_time;\r
+                           //date                        = _new_date;\r
+                           // pdata->location.lat     = pnmea->new_latitude;\r
+                           // pdata->location.lng     = pnmea->new_longitude;\r
+                           // pdata->ground_speed     = pnmea->new_speed;\r
+                           // pdata->ground_course    = pnmea->new_course;\r
+                                               // make_date_time(pdata, pnmea->new_date, pnmea->new_time);\r
+                           // pdata->last_gps_time_ms = now;\r
+                                               break;\r
+                                       case GPS_SENTENCE_GSV:\r
+                           pnmea->last_GSV_ms = now;\r
+                                               for (int j=0;j<20;j++)\r
+                                               {\r
+                                                       pdata->starts[j].snr=pnmea->starts[j].snr;\r
+                                                       pdata->starts[j].starID=pnmea->starts[j].starID;\r
+                                               }\r
+                                               pdata->startnum = pnmea->startnum;\r
+                                               printf("gsv startnum copy to pdata %d\r\n",pdata->startnum );\r
+                                               break;\r
+                                       case GPS_SENTENCE_GLL:\r
+                           pnmea->last_GLL_ms = now;\r
+                                               break;\r
+                                       case GPS_SENTENCE_ZDA:\r
+                           pnmea->last_ZDA_ms = now;\r
+                                               break;\r
                 }\r
             } else {\r
                 switch (pnmea->sentence_type) {\r
@@ -173,15 +200,52 @@ static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata)
             pnmea->sentence_type = GPS_SENTENCE_OTHER;\r
             return 0;\r
         }\r
+               switch(pnmea->term[1])\r
+               {\r
+                       case 'B':\r
+                               pnmea->location_system = BDS_Bli;\r
+                               break;\r
+                       case 'L':\r
+                               pnmea->location_system = GLONASS_L1OF;\r
+                               break;\r
+                       case 'P':\r
+                               pnmea->location_system = GPS_L1C_A;\r
+                               break;\r
+                       case 'Q':\r
+                               pnmea->location_system = QZSS_L1C_A;\r
+                               break;\r
+                       case 'A':\r
+                               pnmea->location_system = Galileo_E1C;\r
+                               break;\r
+                       case 'N':\r
+                               pnmea->location_system = GNSS;\r
+                               break;\r
+                       default:\r
+                               pnmea->location_system = MAX_LOCATION_SYSTEM;\r
+                               break;\r
+               }\r
+\r
+\r
         const char *term_type = &pnmea->term[2];\r
         if (strcmp(term_type, "RMC") == 0) {\r
             pnmea->sentence_type = GPS_SENTENCE_RMC;\r
         } else if (strcmp(term_type, "GGA") == 0) {;\r
             pnmea->sentence_type = GPS_SENTENCE_GGA;\r
-        }else if (strcmp(term_type, "HDT") == 0) {\r
-            pnmea->sentence_type = GPS_SENTENCE_HDT;\r
-            // HDT doesn't have a data qualifier\r
-            pnmea->gps_data_good = 1;\r
+        } else if (strcmp(term_type, "GSV") == 0) {;\r
+            pnmea->sentence_type = GPS_SENTENCE_GSV;\r
+        } else if (strcmp(term_type, "GSA") == 0) {;\r
+            pnmea->sentence_type = GPS_SENTENCE_GSA;\r
+        } else if (strcmp(term_type, "GLL") == 0) {;\r
+            pnmea->sentence_type = GPS_SENTENCE_GLL;\r
+        } else if (strcmp(term_type, "ZDA") == 0) {;\r
+            pnmea->sentence_type = GPS_SENTENCE_ZDA;\r
+        } else if (strcmp(term_type, "TH000") == 0) {;\r
+            pnmea->sentence_type = GPS_SENTENCE_TH000;\r
+        } else if (strcmp(term_type, "TH001") == 0) {;\r
+            pnmea->sentence_type = GPS_SENTENCE_TH001;\r
+        } else if (strcmp(term_type, "TH002") == 0) {;\r
+            pnmea->sentence_type = GPS_SENTENCE_TH002;\r
+        \r
         }else if (strcmp(term_type, "VTG") == 0) {\r
             pnmea->sentence_type = GPS_SENTENCE_VTG;\r
             // VTG may not contain a data qualifier, presume the solution is good\r
@@ -192,7 +256,9 @@ static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata)
         }\r
         return 0;\r
     }\r
-\r
+       \r
+       \r
+       unsigned char startindex;\r
     // 32 = RMC, 64 = GGA, 96 = VTG\r
     if (pnmea->sentence_type != GPS_SENTENCE_OTHER && pnmea->term[0]) {\r
         switch (pnmea->sentence_type + pnmea->term_number) {\r
@@ -214,7 +280,67 @@ static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata)
         case GPS_SENTENCE_GGA + 8: // HDOP (GGA)\r
             pnmea->new_hdop = (unsigned short)(string_to_float((const char*)pnmea->term, (void*)0)*100);\r
             break;\r
-\r
+               case GPS_SENTENCE_GSV + 1: // GSV numMsg 2 GSV 语句总数。\r
+                       pnmea->gsvpagecount =  (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv pagecount %d\r\n",pnmea->gsvpagecount );\r
+                       pnmea->gps_data_good=1;\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 2: // GSV msgNo GSV 语句编号。\r
+                       pnmea->gsvpage =  (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv gsvpage %d\r\n",pnmea->gsvpage );\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 3: // GSV numSV 可见卫星总数。\r
+                       pnmea->startnum =  (unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startnum %d\r\n",pnmea->startnum );\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 4: // GSV svid  卫星编号\r
+                       startindex=4*(pnmea->gsvpage-1);\r
+                       if (startindex>=pnmea->startnum) break;\r
+                       pnmea->starts[startindex].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startindex %d startid %d\r\n",startindex ,pnmea->starts[startindex].starID);\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 7: // GSV cn0 载噪比:0~99,无效时为空\r
+                       startindex=4*(pnmea->gsvpage-1);\r
+                       if (startindex>=pnmea->startnum) break;\r
+                       pnmea->starts[startindex].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startindex %d snr %d\r\n",startindex ,pnmea->starts[startindex].snr);\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 8: // GSV svid  卫星编号 N*4\r
+                       startindex=4*(pnmea->gsvpage-1)+1;\r
+                       if (startindex>=pnmea->startnum) break;\r
+                       pnmea->starts[startindex].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startindex %d startid %d\r\n",startindex ,pnmea->starts[startindex].starID);\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 11: // GSV cn0 载噪比:0~99,无效时为空\r
+                       startindex=4*(pnmea->gsvpage-1)+1;\r
+                       if (startindex>=pnmea->startnum) break;\r
+                       pnmea->starts[startindex].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startindex %d snr %d\r\n",startindex ,pnmea->starts[startindex].snr);\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 12: // GSV svid  卫星编号\r
+                       startindex=4*(pnmea->gsvpage-1)+2;\r
+                       if (startindex>=pnmea->startnum) break;\r
+                       pnmea->starts[startindex].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startindex %d startid %d\r\n",startindex ,pnmea->starts[startindex].starID);\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 15: // GSV cn0 载噪比:0~99,无效时为空\r
+                       startindex=4*(pnmea->gsvpage-1)+2;\r
+                       if (startindex>=pnmea->startnum) break;\r
+                       pnmea->starts[startindex].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startindex %d snr %d\r\n",startindex ,pnmea->starts[startindex].snr);\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 16: // GSV svid  卫星编号\r
+                       startindex=4*(pnmea->gsvpage-1)+3;\r
+                       if (startindex>=pnmea->startnum) break;\r
+                       pnmea->starts[startindex].starID=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startindex %d startid %d\r\n",startindex ,pnmea->starts[startindex].starID);\r
+                       break;\r
+               case GPS_SENTENCE_GSV + 19: // GSV cn0 载噪比:0~99,无效时为空\r
+                       startindex=4*(pnmea->gsvpage-1)+3;\r
+                       if (startindex>=pnmea->startnum) break;\r
+                       pnmea->starts[startindex].snr=(unsigned char)sring_to_int((const char*)pnmea->term, (void*)0);\r
+                       printf("gsv startindex %d snr %d\r\n",startindex ,pnmea->starts[startindex].snr);\r
+                       break;\r
         // time and date\r
         //\r
         case GPS_SENTENCE_RMC + 1: // Time (RMC)\r
@@ -262,9 +388,9 @@ static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata)
                pnmea->new_speed = string_to_float((const char*)pnmea->term, (void*)0);       //km/h\r
            break;\r
         \r
-        case GPS_SENTENCE_HDT + 1: // Course (HDT)\r
-                        pnmea->new_gps_yaw = string_to_float((const char*)pnmea->term, (void*)0);\r
-                        break;\r
+        // case GPS_SENTENCE_HDT + 1: // Course (HDT)\r
+               //       pnmea->new_gps_yaw = string_to_float((const char*)pnmea->term, (void*)0);\r
+               //       break;\r
         case GPS_SENTENCE_RMC + 8: // Course (GPRMC)\r
         case GPS_SENTENCE_VTG + 1: // Course (VTG)\r
             pnmea->new_course = string_to_float((const char*)pnmea->term, (void*)0);\r
@@ -275,7 +401,7 @@ static unsigned char nmea_term_complete(gps_nmea* pnmea, gps_data* pdata)
     return 0;\r
 }\r
 \r
-/* ¶à´Î·½ */\r
+/* 多次方 */\r
 static int int_pow(int value, unsigned int count)\r
 {\r
        int v = 1;\r
@@ -294,7 +420,7 @@ static double double_pow(double value, unsigned int count)
        return v;\r
 }\r
 \r
-/* ¼ì²é×Ö·û´®ÊÇ·ñΪÊý×Ö×Ö·û´®£¬ÊÇ·µ»Ø1£¬·ñÔò·µ»Ø0 */ \r
+/* 检查字符串是否为数字字符串,是返回1,否则返回0 */ \r
 static unsigned char string_check_digital(const char* pc)\r
 {\r
        const char* p;\r
@@ -309,13 +435,13 @@ static unsigned char string_check_digital(const char* pc)
        return 1;       \r
 } \r
 \r
-/* Êý×Ö×Ö·û´®´¦Àíº¯Êý,ʶ±ð·ûºÅ²¢ÇÒ²»¼ì²éÒç³ö\r
-*  Èç¹ûÊÇСÊý£¬ÔòÖ»·µ»ØÕûÊý²¿·Ö,Èç¹ûת»»³ö´í£¬·µ»Ø0 \r
-*  ´«Èë²ÎÊý£º Ô­Ê¼×Ö·û´®£¬ ×ª»»³É¹¦±êÖ¾ 0-´íÎó  1-ÕýÈ· \r
+/* 数字字符串处理函数,识别符号并且不检查溢出\r
+*  如果是小数,则只返回整数部分,如果转换出错,返回0 \r
+*  传入参数: 原始字符串, 转换成功标志 0-错误  1-正确 \r
 */\r
 static int sring_to_int(const char* pstr, unsigned char* b)\r
 {\r
-       char nega = 1;    /* ¸ºÊýΪ1£¬ ÕýÊýΪ1 */ \r
+       char nega = 1;    /* 负数为1, 正数为1 */ \r
        const char* psrc = (void*)0;\r
        int value = 0;\r
        \r
@@ -332,7 +458,7 @@ static int sring_to_int(const char* pstr, unsigned char* b)
        }\r
        \r
        psrc = pstr;\r
-       if('-'==*psrc)  /* ·ûºÅλ */ \r
+       if('-'==*psrc)  /* 符号位 */ \r
        {\r
                nega = -1;\r
                ++psrc;\r
@@ -350,14 +476,14 @@ static int sring_to_int(const char* pstr, unsigned char* b)
        return value;\r
 } \r
 \r
-/* ×Ö·û´®×ª»»³ÉСÊý */\r
+/* 字符串转换成小数 */\r
 static double string_to_float(const char* pstr, unsigned char* b) \r
 {\r
-       char nega = 1;    /* ¸ºÊýΪ1£¬ ÕýÊýΪ1 */ \r
+       char nega = 1;    /* 负数为1, 正数为1 */ \r
        const char* psrc = (void*)0;\r
        double value = 0.0;\r
-       double lvalue = 0.0; /* Ð¡ÊýµãºóÃæÊý×Ö */ \r
-       unsigned char dotflag = 0;  /* Ð¡Êýµã±ê¼Ç  1Ϊ֮ǰ³öÏÖ¹ýСÊýµã */ \r
+       double lvalue = 0.0; /* 小数点后面数字 */ \r
+       unsigned char dotflag = 0;  /* 小数点标记  1为之前出现过小数点 */ \r
        unsigned char j = 0;\r
        \r
        if( (void*)0==pstr ) \r
@@ -373,7 +499,7 @@ static double string_to_float(const char* pstr, unsigned char* b)
                return 0;\r
        }\r
        \r
-       if('-'==*psrc)  /* ·ûºÅλ */ \r
+       if('-'==*psrc)  /* 符号位 */ \r
        {\r
                nega = -1;\r
                ++psrc;\r
@@ -406,9 +532,9 @@ static double string_to_float(const char* pstr, unsigned char* b)
        return value;\r
 }\r
 \r
-/* ¸¡µãÊýת»»Îª×Ö·û´®£¬°üÀ¨ÕûÊýת»»Îª×Ö·û´® \r
-*  intgrÖ¸¶¨ÕûÊýλ¸öÊý£¬decÖ¸¶¨Ð¡Êýλ¸öÊý \r
-*  ×Ô¶¯È¥³ýÇ°ÃæµÄ0£¬Ð¡ÊýµãºóÃæµÄ0²»»áÉáÈ¥ \r
+/* 浮点数转换为字符串,包括整数转换为字符串 \r
+*  intgr指定整数位个数,dec指定小数位个数 \r
+*  自动去除前面的0,小数点后面的0不会舍去 \r
 */ \r
 static unsigned char float_to_string(double value, char* pdest, unsigned int intgr, unsigned int dec)\r
 {\r
@@ -456,7 +582,7 @@ static unsigned char float_to_string(double value, char* pdest, unsigned int int
        if( !zeroflag ) *pstr++ = '0';\r
                \r
                \r
-       /* Èç¹ûСÊýλÊýΪ0£¬Ôò·µ»ØÕûÊý²¿·Ö */\r
+       /* 如果小数位数为0,则返回整数部分 */\r
        if(0==dec)\r
        {\r
                *pstr = '\0';\r
@@ -479,13 +605,13 @@ static unsigned char float_to_string(double value, char* pdest, unsigned int int
 } \r
 \r
 \r
-/* ÕûÊýת»»³É×Ö·û´®£¬ÄÚ²¿Æäʵµ÷ÓÃÁË float_to_string */\r
+/* 整数转换成字符串,内部其实调用了 float_to_string */\r
 static unsigned char int_to_string(int value, char* pdest, unsigned int intgr) \r
 {\r
        return float_to_string((double)value, pdest, intgr,0);\r
 }\r
 \r
-/* Ê±¼ä´¦Àí  ´«Èë²ÎÊýΪÈÕÔÂÄêºÍºÁÃë*/ \r
+/* 时间处理  传入参数为日月年和毫秒*/ \r
 static int make_date_time(gps_data* pdata, unsigned int date, unsigned int time)\r
 {\r
        \r
@@ -531,4 +657,155 @@ static int make_date_time(gps_data* pdata, unsigned int date, unsigned int time)
     \r
     return 1;\r
 } \r
+char* get_gps_status_str(gps_status status)\r
+{\r
+       char* ret="NO_GPS";\r
+       switch(status)\r
+       {\r
+               case NO_GPS:\r
+                       ret = "无卫星";\r
+                       break;\r
+               case NO_FIX:\r
+                       ret = "接收到GPS信息,但没有定位";\r
+                       break;\r
+               case GPS_OK_FIX_2D:\r
+                       ret = "2D定位";\r
+                       break;\r
+               case GPS_OK_FIX_3D:\r
+                       ret = "3D定位";\r
+                       break;\r
+               case GPS_OK_FIX_3D_DGPS:\r
+                       ret = "优于3D定位";\r
+                       break;\r
+               case GPS_OK_FIX_3D_RTK_FLOAT:\r
+                       ret = "RTK浮点解状态";\r
+                       break;\r
+               case GPS_OK_FIX_3D_RTK_FIXED:\r
+                       ret = "RTK固定解状态";\r
+                       break;\r
+               \r
+               default:\r
+                       ret = "未知卫星状态";\r
+       }\r
+       return ret;\r
+}\r
+\r
+char* get_gps_sentence_type_str(sentence_types sentencetype)\r
+{\r
+   switch(sentencetype)\r
+   {\r
+               case GPS_SENTENCE_RMC:\r
+                       return "RMC字段 推荐的最少专用导航数据。";\r
+               case GPS_SENTENCE_GGA:\r
+                       return "GGA字段 接收机定位数据。";\r
+               case GPS_SENTENCE_GSV:\r
+                       return "GSV字段 可见卫星数据。";\r
+               case GPS_SENTENCE_GSA:\r
+                       return "GSA字段 有效卫星与精度因子数据。";\r
+               case GPS_SENTENCE_GLL:\r
+                       return "GLL字段 接收机地理位置数据。";\r
+               case GPS_SENTENCE_VTG:\r
+                       return "VTG字段 对地速度与航向数据。";\r
+               // case GPS_SENTENCE_HDT:\r
+               //      return "HDT字段";\r
+               case GPS_SENTENCE_ZDA:\r
+                       return "ZDA字段 时间与日期数据";\r
+               case GPS_SENTENCE_TH000:\r
+                       return "接收机前端增益信息。";\r
+               case GPS_SENTENCE_TH001:\r
+                       return "接收机定位质量信息。";\r
+               case GPS_SENTENCE_TH002:\r
+                       return "接收机功耗模式信息。";\r
+               case GPS_SENTENCE_OTHER:\r
+                       return "其他字段";\r
+               default:\r
+                       return "unknown_type";\r
+   } \r
+}\r
+char* get_gps_location_system_str(location_system_t lsystem)\r
+{\r
+switch(lsystem)\r
+   {\r
+               case GNSS:\r
+                       return "全球导航卫星系统";\r
+               case GPS_L1C_A:\r
+                       return "全球定位系统";\r
+               case GLONASS_L1OF:\r
+                       return "全球导航卫星系统(俄)";\r
+               case Galileo_E1C:\r
+                       return "伽利略卫星定位系统";\r
+               case BDS_Bli:\r
+                       return "北斗卫星导航系统";\r
+               case QZSS_L1C_A:\r
+                       return "准天顶卫星系统";\r
+               default:\r
+                       return "未知定位系统或自定义系统指令";\r
+   } \r
+}\r
+\r
+void dump_nmea_str(gps_nmea *nmeadata)\r
+{\r
+\r
+       printf("\r\n");\r
+       printf("%s\r\n",get_gps_location_system_str(nmeadata->location_system));\r
+       printf("%s\r\n",get_gps_sentence_type_str(nmeadata->sentence_type));\r
+       printf("\r\n");\r
+}\r
+void dump_location_data(gps_data*locationdata)\r
+{\r
+\r
+       printf("\r\n");\r
+       printf("20%02d-%02d-%02d,\r\n定位状态(%s)\r\n",\r
+    locationdata->date_time.year,\r
+    locationdata->date_time.month,\r
+    locationdata->date_time.day,\r
+    get_gps_status_str(locationdata->status)\r
+    );\r
+       printf("可见卫星颗数(%d),\r\n坐标(%f,%f,%d),\r\nhdop(%d),vdop(%d)\r\n",\r
+       locationdata->num_sats,\r
+    locationdata->location.lat,\r
+    locationdata->location.lng,\r
+    locationdata->location.alt,\r
+       locationdata->hdop,\r
+       locationdata->vdop\r
+    );\r
+       if (locationdata->startnum>0)\r
+       {\r
+               printf("卫星数[%d]",locationdata->startnum);\r
+               for(int i=0;i<20;i++)\r
+               {\r
+                       if (i< locationdata->startnum)\r
+                       {\r
+                               printf(",(%d,%d)",\r
+                                       locationdata->starts[i].starID,\r
+                                       locationdata->starts[i].snr);\r
+\r
+                       }\r
+               }\r
+               printf("\r\n");\r
+       }else{\r
+               printf("无卫星数据\r\n");\r
+       }\r
+       printf("\r\n");\r
+}\r
+\r
+\r
+\r
+// NMEA0183 g_nmeadata={0};\r
+\r
+// int decode_nmea(char c)\r
+// {\r
+//     if(nmea_decode(&g_nmeadata,c) ) ///调用解析函数\r
+//     {\r
+//         dump_nmea_str(&(g_nmeadata.gpsParse));\r
+//         if (g_nmeadata.gpsParse.sentence_type == GPS_SENTENCE_TH002)\r
+//         {\r
+//             //一组数据最后一条\r
+//             dump_location_data(&(g_nmeadata.gpsData));\r
+//             memset(&g_nmeadata,0,sizeof(g_nmeadata));\r
+//         }\r
+//     } \r
+\r
 \r
+//     return 0;\r
+// }\r
diff --git a/code/sdk/zhihui/services/gnss/src/NMEA0183.h b/code/sdk/zhihui/services/gnss/src/NMEA0183.h
deleted file mode 100644 (file)
index 9a48388..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*\r
-*                              GPS NMEA0183ЭÒé¼òÒª½âÎö¿ò¼Ü \r
-*      \r
-*      Ö§³Ö½âÎö RMC¡¢GGA¡¢VTG¡¢HDTµÈÏûÏ¢×Ö¶ÎÐÅÏ¢£¬ÓÉÓÚ½âÎö¿ò¼Ü±È½ÏÃ÷ÁË£¬\r
-*   ÒÆÖ²Ô´ÂëÕß¿É×ÔÐп¼ÂÇÌí¼ÓеĽâÎö´úÂë¡£\r
-*   ½âÎö·½Ê½²ÉÓÃÖð¸ö×ֶνâÎöµÄ·½Ê½£¬Äܴܺó³Ì¶ÈÉϽÚÊ¡ÏûºÄÄÚ´æ¿Õ¼ä¡£ \r
-*   ÖØÐ±àдÊý¾Ýת»»º¯Êý£¬²»ÒÀÀµÍⲿ¿â£¬ÒÆÖ²Ê±Ò»°ãÖ»Ðè°üº¬NMEA0183.h\r
-*   Îļþ¼´¿É¡£ \r
-*\r
-*   ´úÂëʾÀý£º\r
-*      \r
-               char nmea[] = \\r
-               "$GNRMC,102219.00,A,2239.11578,N,11406.59325,E,0.009,,291018,,,D*62\r\n"\\r
-               "$GNVTG,,T,,M,0.009,N,0.017,K,D*37\r\n"\\r
-               "$GNGGA,102220.00,2239.11583,N,11406.59338,E,2,09,1.30,112.7,M,-2.3,M,,0000*52\r\n";\r
-               \r
-               gps_nmea gps_nmea_temp;   /// ¶¨Òå½âÎöʱÓõ½µÄÔÝ´æ×´Ì¬Êý¾Ý,Ö»¹©½âÎöʱʹÓà\r
-               gps_data gps_data1;       /// GPS½âÎöµÃµ½µÄ×îÖÕÊý¾Ý£¬Óû§¿ÉʹÓà\r
-               unsigned int index = 0;\r
-               \r
-               for(index=0; index<sizeof(nmea); ++index)\r
-               {\r
-                       if(nmea_decode(&gps_nmea_temp, &gps_data1, nmea[index])) ///µ÷ÓýâÎöº¯Êý\r
-                       {\r
-                               /// ½âÎöÏûÏ¢¶Î³É¹¦ \r
-                               ... \r
-                       } \r
-               } \r
-               \r
-*   NMEA0183½âÎö´úÂë˼ÏëÀ´Ô´ÓÚ¿ªÔ´·É¿Ø´úÂë(Ardupilot)£¬ËùÒԸ÷ݴúÂ뿪Դ£¬¿ÉÃâ·ÑʹÓá£\r
-*   ( ÈçÓÐBug£¬ÍûÄÜ·´À¡ ! QQ: 2281280195 ) \r
-*       \r
-*   ×÷Õߣº ouyanglei           Ê±¼ä£º2018-11-16\r
-*/\r
-\r
-\r
-#ifndef NMEA0183_H\r
-#define NMEA0183_H\r
-\r
-/*************** ºê¶¨Òå  *******************/ \r
-#define current_time_ms() 1\r
-\r
-#define GPS_LEAPSECONDS_MILLIS 18000UL\r
-#define AP_SEC_PER_WEEK   (7UL * 86400UL)\r
-\r
-/* ¼ì²é×Ö·û´®ÊÇ·ñΪÊý×Ö0-9 */ \r
-#define IS_DIGITAL(x) ( ((x)>='0'&&(x)<='9')||(x)=='-'||(x)=='.' )\r
-#define CHAR_TO_DIGITAL(x) ((x)-'0')\r
-#define DIGITAL_TO_CHAR(x) ( (x)+'0' )\r
-\r
-/**************** Ã¶¾ÙÁ¿¶¨Òå ***************/\r
-       /* ½âÎö×Ö¶Îö¾ÙÁ¿ */ \r
-    typedef enum _sentence_types \r
-       {   /* Ã¿¸öö¾ÙÁ¿±íʾ¸Ã×Ö¶ÎµÄÆðʼλÖã¬ÓÐÐ©ÌØÊâ×Ö¶ÎÐèÒª10¸ö×Ö¶ÎÓò */ \r
-        GPS_SENTENCE_RMC = 32,     /* RMC×ֶΠ*/\r
-        GPS_SENTENCE_GGA = 64,         /* GGA×ֶΠ*/\r
-        GPS_SENTENCE_VTG = 96,         /* VTG×ֶΠ*/\r
-        GPS_SENTENCE_HDT = 128,    /* HDT×ֶΠ*/\r
-        GPS_SENTENCE_OTHER = 0     /* Ä¬ÈÏûÓÐ×ֶΠ*/\r
-    }sentence_types;\r
-\r
-/**************** ½á¹¹Ì嶨Òå ***************/    \r
-    /* GPS¶¨Î»×´Ì¬Ã¶¾ÙÁ¿ */ \r
-    typedef enum _gps_status\r
-       {\r
-        NO_GPS = 0,              /* ÎÞGPS */\r
-        NO_FIX,                  /* ½ÓÊÕµ½GPSÐÅÏ¢£¬µ«Ã»Óж¨Î» */\r
-        GPS_OK_FIX_2D,           /* 2D¶¨Î» */\r
-        GPS_OK_FIX_3D,           /* 3D¶¨Î» */ \r
-        GPS_OK_FIX_3D_DGPS,      /* ÓÅÓÚ3D¶¨Î» */ \r
-        GPS_OK_FIX_3D_RTK_FLOAT, /* RTK¸¡µã½â״̬ */ \r
-        GPS_OK_FIX_3D_RTK_FIXED, /* RTK¹Ì¶¨½â״̬ */\r
-    }gps_status;\r
-    \r
-    /* GPSµãλÖà*/ \r
-    typedef struct _location \r
-       {\r
-           int alt:24;         /* º£°Î¸ß¶È meters * 100  µ¥Î»ÎªÀåÃ× */\r
-           float lat;            /* Î³¶È *  ÔÝʱ²»³ËÒÔ10**7£¬Ô­Ê¼±£´æ*/\r
-           float lng;            /* ¾«¶È *  ÔÝʱ²»³ËÒÔ10**7£¬Ô­Ê¼±£´æ*/\r
-       }Location;\r
-    \r
-    /* Êý¾Ý½âÎö״̬½á¹¹Ì嶨Òå */\r
-    typedef struct _gps_nmea\r
-    {\r
-       /* Êý¾Ý½âÎö״̬ */ \r
-       unsigned char parity;                      /* Ð£Ñ鼯ËãºÍ */ \r
-       unsigned char is_checksum_term;    /* µ±Ç°×Ö¶ÎÓòΪУÑé×Ö */\r
-       char term[15];                             /* µ±Ç°×Ö¶ÎÓò»º³åÇø£¬','Ϊ×Ö¶ÎÓò·Ö¸î·û */\r
-       unsigned char sentence_type;       /* ×Ö¶ÎÀà±ð£¬¼ûö¾Ù sentence_types*/\r
-       unsigned char term_number;         /* µ±Ç°×Ö¶ÎÓòÐòºÅ */\r
-       unsigned char term_offset;         /* ×Ö¶ÎÓòÊý¾ÝÆ«ÒÆÁ¿ */\r
-       unsigned char gps_data_good;       /* GPSÊý¾ÝÓÐЧ״̬ */\r
-       \r
-       /* Êý¾Ý½âÎö½á¹û */\r
-       unsigned int new_time;                  /* UTCʱ¼ä */\r
-       unsigned int new_date;                  /* UTCÈÕÆÚ */\r
-       float new_latitude;                             /* Î³¶È */\r
-       float new_longitude;                            /* ¾­¶È */\r
-       int new_altitude;                               /* º£°Î¸ß¶È cm*/\r
-       float new_speed;                                /* µØËÙ km/h */\r
-       float new_course;                               /* RMC¡¢VTG×Ö¶Î´ÅÆ«½ÇÐÅÏ¢*/\r
-       float new_gps_yaw;                              /* HDTº½ÏòÐÅÏ¢ */\r
-       unsigned short new_hdop;                /* Ë®Æ½¾«¶È *100 */\r
-       unsigned char new_satellite_count;      /* µ±Ç°Ê¹ÓÃÎÀÐǵĿÅÊý */\r
-       unsigned char new_quality_indicator;    /* ¶¨Î»×´Ì¬ */\r
-\r
-       unsigned int last_RMC_ms;                   /* ×îºó¸üÐÂ×Ö¶Îʱ¼ä */\r
-       unsigned int last_GGA_ms;\r
-       unsigned int last_VTG_ms;\r
-               unsigned int last_HDT_ms;\r
-       }gps_nmea;\r
-       \r
-       /* Ê±¼ä½á¹¹Ìå */ \r
-       typedef struct _time\r
-       {\r
-               unsigned char year;\r
-               unsigned short int month : 4;\r
-               unsigned short int  : 4;\r
-               unsigned short int day : 5;\r
-               unsigned short int week : 3;\r
-       }DateTime;\r
-       \r
-       /* GPSÊý¾ÝÇøÓò£¬¹©ÉϲãÓ¦Óõ÷Óà*/ \r
-       typedef struct _gps_data {\r
-        unsigned char instance;                   /* GPSʵÀý¸öÊý */ \r
-        gps_status status;                 /* GPS¶¨Î»×´Ì¬ */\r
-        Location location;                 /* GPS¶¨Î»µ½µÄµ±Ç°Î»Öà*/\r
-        DateTime date_time; \r
-        float ground_speed;                /* µØËÙ  m/s */\r
-        float ground_course;               /* µØËÙº½Ïò  ¶È  Ë³Ê±Õë 0-360 */ \r
-        float gps_yaw;                     /* GPHDT×ֶκ½ÏòÐÅÏ¢ Ò»°ãÓÃÓÚË«ÌìÏß²âÏò */\r
-        unsigned short hdop;               /* Ë®Æ½¾«¶È  cm */\r
-        unsigned short vdop;               /* ´¹Ö±¾«¶È  cm */\r
-        unsigned char num_sats;            /* ¿É¼ûÎÀÐÇ¿ÅÊý */\r
-        unsigned char have_gps_yaw;        /* GPHDTº½Ïò×Ö¶ÎÓÐЧ */\r
-        unsigned int last_gps_time_ms;     /* ×îºó»ñÈ¡GPSÐÅϢʱµÄʱ¼ä  ms */\r
-    }gps_data;\r
-    \r
-    /* NMEA0183½á¹¹Ìå¶ÔÏó */\r
-    typedef struct _nmea0183\r
-       {\r
-               gps_nmea gpsParse;\r
-               gps_data gpsData;\r
-               unsigned char (*nmea_decode)(struct _nmea0183* pnmea, char c);          \r
-       }NMEA0183; \r
-    \r
-/**************** º¯Êý¶¨Òå ***************/\r
-\r
-unsigned char nmea_decode(NMEA0183* pnmea, char c);\r
-\r
-#endif\r
-\r
-\r
diff --git a/code/sdk/zhihui/services/gnss/src/decodenmea.c b/code/sdk/zhihui/services/gnss/src/decodenmea.c
new file mode 100644 (file)
index 0000000..dbbaec4
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * 
+ * 
+$GPGGA,,,,,,0,,,,,,,,*66
+
+$GPGLL,,,,,,V,N*64
+
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+
+$GPRMC,,V,,,,,,,,,E,N,V*6C
+
+$GPVTG,,T,,M,,N,,K,N*2C
+
+$GPZDA,,,,,00,00*48
+
+$PNTH000,13,,-87,0,,,,,1,1*22
+
+$PNTH001,0.000000,0.00,0.00,300000.00,1,0,0*1D
+
+$PNTH002,,T,0.000000,0,200,0.000000,3,0.000000*4B
+*/
+
+
+#include "NMEA0183.h"
+#include <string.h>
+#include <stdio.h>
+
+char* nmealines[]={
+    "$GPGGA,,,,,,0,,,,,,,,*66\r\n",
+    "$GPGLL,,,,,,V,N*64\r\n",
+    "$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r\n",
+    "$GPRMC,,V,,,,,,,,,E,N,V*6C\r\n",
+    "$GPVTG,,T,,M,,N,,K,N*2C\r\n",
+    "$GPZDA,,,,,00,00*48\r\n",
+    "$PNTH000,13,,-87,0,,,,,1,1*22\r\n",
+    "$PNTH001,0.000000,0.00,0.00,300000.00,1,0,0*1D\r\n",
+    "$PNTH002,,T,0.000000,0,200,0.000000,3,0.000000*4B\r\n"
+};
+char nmealines1[]={
+    "$GBGSV,3,1,11,07,75,129,27,08,68,213,28,10,88,303,26,11,58,322,26,1*7D\r\n"\
+    "$GBGSV,3,2,11,13,51,216,31,25,43,237,33,34,62,011,26,38,81,201,30,1*75\r\n"\
+    "$GBGSV,3,3,11,40,64,107,30,42,17,157,29,43,38,289,27,1*47\r\n"\
+    "$GNGSA,A,3,7,8,10,11,13,25,34,38,40,42,43,,1.5,0.8,1.2,4*39\r\n"\
+    "$GNRMC,102219.00,A,2239.11578,N,11406.59325,E,0.009,,291018,,,D*62\r\n"\
+    "$GNVTG,,T,,M,0.009,N,0.017,K,D*37\r\n"\
+    "$GNGLL,3412.433366,N,10852.420048,E,094345.00,A,A*7F\r\n"\
+    "$GNZDA,094343.00,24,03,2022,00,00*76\r\n"\
+    "$GNGGA,094343.00,3412.431698,N,10852.419449,E,1,22,0.8,378.8,M,,M,,0000*67\r\n"\
+    "$PNTH000,13,,-87,0,,,,,1,1*22\r\n"\
+    "$PNTH001,0.000000,0.00,0.00,300000.00,1,0,0*1D\r\n"\
+    "$PNTH002,,T,0.000000,0,200,0.000000,3,0.000000*4B\r\n"
+};
+
+
+NMEA0183 g_nmeadata={0};
+
+int decode_nmea(char c)
+{
+    if(nmea_decode(&g_nmeadata,c) ) ///调用解析函数
+    {
+        dump_nmea_str(&(g_nmeadata.gpsParse));
+        if (g_nmeadata.gpsParse.sentence_type == GPS_SENTENCE_TH002)
+        {
+            //一组数据最后一条
+            dump_location_data(&(g_nmeadata.gpsData));
+            memset(&g_nmeadata,0,sizeof(g_nmeadata));
+        }
+    } 
+
+
+    return 0;
+}
+
+int main1(int argc, char** argv)
+{
+
+    char tmpc=0;
+    FILE *fp = NULL;
+   fp = fopen("nmealist.txt", "r");
+   while (fread(&tmpc, 1,1, (FILE*)fp))
+        decode_nmea(tmpc);
+   fclose(fp);
+    
+}
+
+int main(int argc, char** argv)
+{
+
+    for(int i=0; i<sizeof(nmealines1); ++i)
+    {
+        decode_nmea(nmealines1[i]);
+    } 
+    
+    return 0;
+}
\ No newline at end of file