Files
stm32-cnn/HARDWARE/GPS/gps.c
2024-12-19 14:06:05 +08:00

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解析
}