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
}
```