GNSS功能应用流程

## 1.模组上电初始化 ```` ^CINIT: 2, 32, 41891 ^CINIT: 8, 2048, 1 ^CINIT: 16, 0, 3276850 ^CINIT: 32, 0, 0 +CREG: 1 +QNITZ:19/8/14,9:0:29+32,0 +CTZV:19/8/14,9:0:29,+32 //模组成功驻网后返回网络时间,可依据这个条件作为驻网成功判断 确认串口正常 AT OK ```` 查询信号值 ```` AT+CSQ +CSQ: 30,0 OK ```` 查询是否成功驻网 ```` AT+CGREG? +CGREG: 0,1 OK ```` ## 2.启动GNSS 启用EPOTM获取EPO数据 ```` AT+AMGNSSEPO=1 OK Downloading EPO… Download EPO ok and save success! //第一次启动模组设备需要获取EPO数据 /****************************** AT+AMGNSSEPO=1 //在EPO保存期间,再次获取会直接返回OK OK ******************************/ ```` 启动GPS功能 ```` AT+AMGNSSC=1 OK 触发EPO,触发需要2~3秒的时间,中间需要等待一下 AT+AMGEPOAID OK ```` ## 3.得到GPS数据 ```` AT+AMGNSSRD? GNGGA,062721.000,3803.57078,N,11430.32845,E,1,05,10.8,77.4,M,-16.0,M,,*6A GNGGA,062721.000,3803.57078,N,11430.32845,E,1,05,10.8,77.4,M,−16.0,M,,∗6AGNGLL,3803.57078,N,11430.32845,E,062721.000,A,A4D GNGSA,A,3,10,13,15,20,27,,,,,,,,11.8,10.8,4.7,1*33 GNGSA,A,3,10,13,15,20,27,,,,,,,,11.8,10.8,4.7,1∗33GNGSA,A,3,11.8,10.8,4.7,436 GPGSV,2,1,08,05,14,107,,10,19,301,29,13,28,050,23,15,61,039,37,0*69 GPGSV,2,1,08,05,14,107,,10,19,301,29,13,28,050,23,15,61,039,37,0∗69GPGSV,2,2,08,20,45,310,38,21,60,269,24,55,159,27,06,313,25,061 BDGSV,1,1,00,0*74 BDGSV,1,1,00,0∗74GNRMC,062721.000,A,3803.57078,N,11430.32845,E,0.00,170.93,231019,A,V04 $GNVTG,170.93,T,M,0.00,N,0.00,K,A2F OK 获取数据函数示例 ********************************************************************************************************* * 函 数 名: gpsGPRMC * 功能说明: 分析0183数据包中的 $GNRMC 命令,结果存放到全局变量 * 形 参: _ucaBuf 收到的数据 * _usLen 数据长度 * 返 回 值: 无 ********************************************************************************************************* */ void gpsGPRMC(uint8_t *_ucaBuf, uint16_t _usLen) { char *p; p = (char *)_ucaBuf; p[_usLen] = 0; /* 字段1 UTC时间,hhmmss.sss格式 */ p = strchr(p, ','); if (p == 0) { return; } p++; g_tGPS.Hour = StrToIntFix(p, 2); p += 2; g_tGPS.Min = StrToIntFix(p, 2); p += 2; g_tGPS.Sec = StrToIntFix(p, 2); p += 3; g_tGPS.mSec = StrToIntFix(p, 3); /* 字段2 状态,A=定位,V=未定位 */ p = strchr(p, ','); if (p == 0) { return; } p++; if (*p != 'A') { /* 未定位则直接返回 */ g_tGPS.PositionOk = 0; return; } g_tGPS.PositionOk = 1; p += 1; /* 字段3 纬度ddmm.mmmm,度分格式(前导位数不足则补0) */ p = strchr(p, ','); if (p == 0) { return; } p++; g_tGPS.WeiDu_Du = StrToIntFix(p, 2); p += 2; g_tGPS.WeiDu_Fen = StrToIntFix(p, 2) * 100000; p += 3; g_tGPS.WeiDu_Fen += StrToIntFix(p, 5); p += 5; /* 字段4 纬度N(北纬)或S(南纬)*/ p = strchr(p, ','); if (p == 0) { return; } p++; if (*p == 'S') { g_tGPS.NS = 'S'; } else if (*p == 'N') { g_tGPS.NS = 'N'; } else { return; } /* 字段5 经度dddmm.mmmm,度分格式(前导位数不足则补0) */ p = strchr(p, ','); if (p == 0) { return; } p++; g_tGPS.JingDu_Du = StrToIntFix(p, 3); p += 3; g_tGPS.JingDu_Fen = StrToIntFix(p, 2) * 100000; p += 3; g_tGPS.JingDu_Fen += StrToIntFix(p, 5); p += 5; /* 字段6:经度E(东经)或W(西经) */ p = strchr(p, ','); if (p == 0) { return; } p++; if (*p == 'E') { g_tGPS.EW = 'E'; } else if (*p == 'W') { g_tGPS.EW = 'W'; } /* 字段7:速度,节,Knots 10.05,*/ p = strchr(p, ','); if (p == 0) { return; } p++; g_tGPS.SpeedKnots = StrToInt(p); /* 字段8:方位角,度 ,324.27 */ p = strchr(p, ','); if (p == 0) { return; } p++; g_tGPS.TrackDegTrue = StrToInt(p); /* 字段9:UTC日期,DDMMYY格式 150706 */ p = strchr(p, ','); if (p == 0) { return; } p++; g_tGPS.Day = StrToIntFix(p, 2); p += 2; g_tGPS.Month = StrToIntFix(p, 2); p += 2; g_tGPS.Year = StrToIntFix(p, 2); p += 2; } ```` 模组得到的GPS经纬度格式如下: 纬度: 38 03.57078 度 分 经度:114 30.32845 度 分 有一些软件地图格式不支持度分格式,只支持度秒格式,度秒格式转换如下:分/60+度.小数点保留后6位四舍五入。 **函数示例:** ********************************************************************************************************* * 函 数 名: gps_FenToDu * 功能说明: 将分转换为度的小数部分,保留6位小数。 将分换算为度。 * 形 参: 无 * 返 回 值: 返回度的小数部分(十进制) ***************************************************************************************************************/ ```` uint32_t gps_FenToDu(uint32_t _fen) { uint32_t du; /* g_tGPS.WeiDu_Fen; 纬度,分. 232475; 小数点后4位 表示 23.2475分 */ du = (_fen * 100) / 60; return du; } ```` 模组得到GPS的UTC时间格式 时间格式: hh mm ss.sss, 时 分 秒 日期格式: dd mm yy 日 月 年 UTC时间与北京时间时差8小时,注意格式转换,UTC时间hh+8=北京时间 (大于24h注意进位) 函数示例: /********************************************************************************************************* 函 数 名: UTCDate * 功能说明: 处理UTC时差 * 形 参: * 返 回 值: **********************************************************************************************************/ ```` void UTCDate(void) { { uint8_t ucaDays[]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (g_tParam.iUTCtime > 0) { g_tGPS.Hour += g_tParam.iUTCtime; if (g_tGPS.Hour > 23) { g_tGPS.Hour = g_tGPS.Hour - 24; g_tGPS.ucDay++; /* 闰年2月份为29天 */ if (IsLeapYear(g_tGPS.usYear)) { ucaDays[1] = 29; } else { ucaDays[1] = 28; } if (g_tGPS.ucDay > ucaDays[g_tGPS.ucMonth - 1]) { g_tGPS.ucDay = 1; g_tGPS.ucMonth++; if (g_tGPS.ucMonth > 12) { g_tGPS.usYear++; } } } } else if (g_tParam.iUTCtime < 0) { int iHour; iHour = g_tGPS.Hour; iHour += g_tParam.iUTCtime; if (iHour < 0) { g_tGPS.Hour = 24 + iHour; if (g_tGPS.ucDay == 1) { if (g_tGPS.ucMonth == 1) { g_tGPS.usYear--; g_tGPS.ucMonth = 12; g_tGPS.ucDay = 31; } else { if (g_tGPS.ucMonth == 3) { g_tGPS.ucMonth = 2; /* 闰年2月份为29天 */ if (IsLeapYear(g_tGPS.usYear)) { g_tGPS.ucDay = 29; } else { g_tGPS.ucDay = 28; } } else { g_tGPS.ucMonth--; g_tGPS.ucDay = ucaDays[g_tGPS.ucMonth]; } } } else { g_tGPS.ucDay--; } } else { g_tGPS.Hour = iHour; } } } #endif } ````