Files
2023-07-22 10:37:20 +08:00

119 lines
4.2 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
了解GPS相关知识
$GPRMC协议格式
  例:$GPRMC, 024813.640, A, 3158.4608, N, 11848.3737, E, 10.05, 324.27, 150706, , , A * 50
  字段0:$GPRMC,语句ID,表明该语句为Recommended Minimum Specific GPS / TRANSIT Data(RMC)推荐最小定位信息
  字段1:UTC时间,hhmmss.sss格式(UTC时间是世界统一时间,中国的时间是UTC + 8,比如:上面的时间是02 : 48 : 13而中国的时间是10 : 48 : 13)
  字段2:状态,A = 定位,V = 未定位
  字段3:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
  字段4:纬度N(北纬)或S(南纬)
  字段5:经度dddmm.mmmm,度分格式(前导位数不足则补0)
  字段6:经度E(东经)或W(西经)
  字段7:速度,节,Knots
  字段8:方位角,度
  字段9:UTC日期,DDMMYY格式
  字段10:磁偏角,(000 - 180)度(前导位数不足则补0)
  字段11:磁偏角方向,E = 东W = 西
  字段16:校验值
【提示】利用strtok切割、sscanf或者strncpy、atoi、atof
*/
#include <stdio.h>
#include <string.h>
typedef struct
{
char time[10]; // UTC时间,格式为hhmmss.sss
char status; // 状态,A表示定位,V表示未定位
double latitude; // 纬度,格式为ddmm.mmmm
char latitude_dir; // 纬度半球,N表示北半球,S表示南半球
double longitude; // 经度,格式为dddmm.mmmm
char longitude_dir; // 经度半球,E表示东经,W表示西经
double speed; // 速度,以节为单位
double course; // 方位角,以度为单位
char date[7]; // UTC日期,格式为DDMMYY
double declination; // 磁偏角,以度为单位
char declination_dir; // 磁偏角方向,E表示东偏,W表示西偏
} gprmc_t;
int parse_gprmc(const char *str, gprmc_t *gprmc)
{
char *token;
int i = 0;
token = strtok((char *)str, ",");
while (token != NULL)
{
switch (i)
{
case 0:
if (strcmp(token, "$GPRMC") != 0)
{
return -1;
}
break;
case 1:
sscanf(token, "%2s", gprmc->time);
sscanf(token + 2, "%2lf%lf", &gprmc->time[2], &gprmc->time[4]);
sscanf(token + 4, "%lf", &gprmc->time[6]);
break;
case 2:
gprmc->status = *token;
break;
case 3:
sscanf(token, "%lf", &gprmc->latitude);
sscanf(token + 2, "%lf", &gprmc->latitude);
break;
case 4:
gprmc->latitude_dir = *token;
break;
case 5:
sscanf(token, "%lf", &gprmc->longitude);
sscanf(token + 3, "%lf", &gprmc->longitude);
break;
case 6:
gprmc->longitude_dir = *token;
break;
case 7:
sscanf(token, "%lf", &gprmc->speed);
break;
case 8:
sscanf(token, "%lf", &gprmc->course);
break;
case 9:
sscanf(token, "%2s", gprmc->date);
sscanf(token + 2, "%2lf%lf", &gprmc->date[2], &gprmc->date[4]);
sscanf(token + 4, "%lf", &gprmc->date[6]);
break;
case 10:
sscanf(token, "%lf", &gprmc->declination);
break;
case 11:
gprmc->declination_dir = *token;
break;
default:
break;
}
token = strtok(NULL, ",");
i++;
}
return 0;
}
int main()
{
const char *str = "$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50";
gprmc_t gprmc;
if (parse_gprmc(str, &gprmc) == 0)
{
printf("UTC时间:%s\n", gprmc.time);
printf("状态:%c\n", gprmc.status);
printf("纬度:%lf %c\n", gprmc.latitude, gprmc.latitude_dir);
printf("经度:%lf %c\n", gprmc.longitude, gprmc.longitude_dir);
printf("速度:%lf\n", gprmc.speed);
printf("方位角:%lf\n", gprmc.course);
printf("UTC日期:%s\n", gprmc.date);
printf("磁偏角:%lf %c\n", gprmc.declination, gprmc.declination_dir);
}
return 0;
}