AM21E GNSS功能应用流程

## 1.模组上电初始化 ```` ^CINIT: 2, 32, 41891 ^CINIT: 8, 2048, 1 ^CINIT: 16, 0, 3276850 ^CINIT: 32, 0, 0 +CEREG: 1 +QNITZ:19/8/14,9:0:29+32,0 +CTZV:19/8/14,9:0:29,+32 //模组成功驻网后返回网络时间,可依据这个条件作为驻网成功判断 +CALV: 9 +CALV: 9 确认串口正常 AT OK 查询信号值 AT+CSQ +CSQ: 30,0 OK 查询是否成功驻网 AT+CGREG? +CGREG: 0,1 OK ```` ## 2.启动GNSS ```` 启动GPS功能 AT+AMGNSSC=1 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 $GNGLL,3803.57078,N,11430.32845,E,062721.000,A,A*4D $GNGSA,A,3,10,13,15,20,27,,,,,,,,11.8,10.8,4.7,1*33 $GNGSA,A,3,,,,,,,,,,,,,11.8,10.8,4.7,4*36 $GPGSV,2,1,08,05,14,107,,10,19,301,29,13,28,050,23,15,61,039,37,0*69 $GPGSV,2,2,08,20,45,310,38,21,60,269,,24,55,159,,27,06,313,25,0*61 $BDGSV,1,1,00,0*74 $GNRMC,062721.000,A,3803.57078,N,11430.32845,E,0.00,170.93,231019,,,A,V*04 $GNVTG,170.93,T,,M,0.00,N,0.00,K,A*2F OK ```` 获取数据函数示例 ```language ********************************************************************************************************* * 函 数 名: 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位四舍五入。 函数示例: ```language ********************************************************************************************************* * 函 数 名: 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注意进位) 函数示例: ```language /* ********************************************************************************************************* 函 数 名: 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 } ```