120 lines
2.9 KiB
C
120 lines
2.9 KiB
C
#include "gps.h"
|
|
#include "stdio.h"
|
|
#include "string.h"
|
|
#include "math.h"
|
|
|
|
uint32_t UTC;
|
|
char SetTimeZone[25] = {0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xf1, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};
|
|
|
|
u8 NMEA_Comma_Pos(u8 *buf, u8 cx)
|
|
{
|
|
u8 *p = buf;
|
|
while (cx)
|
|
{
|
|
if (*buf == '*' || *buf < ' ' || *buf > 'z')
|
|
return 0XFF; // 遇到'*'或者非法字符,则不存在第cx个逗号
|
|
if (*buf == ',')
|
|
cx--;
|
|
buf++;
|
|
}
|
|
return buf - p;
|
|
}
|
|
|
|
u32 NMEA_Pow(u8 m, u8 n)
|
|
{
|
|
u32 result = 1;
|
|
while (n--)
|
|
result *= m;
|
|
return result;
|
|
}
|
|
|
|
int NMEA_Str2num(u8 *buf, u8 *dx)
|
|
{
|
|
u8 *p = buf;
|
|
u32 ires = 0, fres = 0;
|
|
u8 ilen = 0, flen = 0, i;
|
|
u8 mask = 0;
|
|
int res;
|
|
while (1) // 得到整数和小数的长度
|
|
{
|
|
if (*p == '-')
|
|
{
|
|
mask |= 0X02;
|
|
p++;
|
|
} // 是负数
|
|
if (*p == ',' || (*p == '*'))
|
|
break; // 遇到结束了
|
|
if (*p == '.')
|
|
{
|
|
mask |= 0X01;
|
|
p++;
|
|
} // 遇到小数点了
|
|
else if (*p > '9' || (*p < '0')) // 有非法字符
|
|
{
|
|
ilen = 0;
|
|
flen = 0;
|
|
break;
|
|
}
|
|
if (mask & 0X01)
|
|
flen++;
|
|
else
|
|
ilen++;
|
|
p++;
|
|
}
|
|
if (mask & 0X02)
|
|
buf++; // 去掉负号
|
|
for (i = 0; i < ilen; i++) // 得到整数部分数据
|
|
{
|
|
ires += NMEA_Pow(10, ilen - 1 - i) * (buf[i] - '0');
|
|
}
|
|
if (flen > 5)
|
|
flen = 5; // 最多取5位小数
|
|
*dx = flen; // 小数点位数
|
|
for (i = 0; i < flen; i++) // 得到小数部分数据
|
|
{
|
|
fres += NMEA_Pow(10, flen - 1 - i) * (buf[ilen + 1 + i] - '0');
|
|
}
|
|
res = ires * NMEA_Pow(10, flen) + fres;
|
|
if (mask & 0X02)
|
|
res = -res;
|
|
return res;
|
|
}
|
|
|
|
// 分析GPRMC信息
|
|
// gpsx: nmea信息结构体
|
|
// buf: 接收到的GPS数据缓冲区首地址
|
|
void NMEA_GPRMC_Analysis(nmea_msg *gpsx, u8 *buf)
|
|
{
|
|
u8 *p1, dx;
|
|
u8 posx;
|
|
u32 temp;
|
|
p1 = (u8 *)strstr((const char *)buf, "RMC"); // "$GPRMC", 经常有&和GPRMC分开的情况, 故只判断GPRMC.
|
|
posx = NMEA_Comma_Pos(p1, 1); // 得到UTC时间
|
|
if (posx != 0XFF)
|
|
{
|
|
UTC = NMEA_Str2num(p1 + posx, &dx) / NMEA_Pow(10, dx);
|
|
temp = (NMEA_Str2num(p1 + posx, &dx) / NMEA_Pow(10, dx)); // 得到UTC时间, 去掉ms
|
|
|
|
gpsx->utc.hour = temp / 10000 + 8; // UTC时间加上时区差
|
|
gpsx->utc.min = (temp / 100) % 100;
|
|
gpsx->utc.sec = temp % 100;
|
|
}
|
|
|
|
posx = NMEA_Comma_Pos(p1, 9); // 得到UTC日期
|
|
if (posx != 0XFF)
|
|
{
|
|
temp = NMEA_Str2num(p1 + posx, &dx); // 得到UTC日期
|
|
gpsx->utc.date = temp / 10000;
|
|
gpsx->utc.month = (temp / 100) % 100;
|
|
gpsx->utc.year = 2000 + temp % 100;
|
|
}
|
|
}
|
|
|
|
// 提取NMEA-0183信息
|
|
// gpsx: nmea信息结构体
|
|
// buf: 接收到的GPS数据缓冲区首地址
|
|
void GPS_Analysis(nmea_msg *gpsx, u8 *buf)
|
|
{
|
|
NMEA_GPRMC_Analysis(gpsx, buf); // GPRMC解析
|
|
}
|