用c语言写一个程序:通过串口UART2从北斗模块接收$GNRMC数据,解析数据并读取其中的年月日和日期信,再转换为北京时间。
时间: 2024-03-15 21:45:21 浏览: 129
好的,下面是一份简单的代码示例,你可以在此基础上进行修改和完善。
```
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
// 串口初始化等操作省略
// 请根据实际情况进行设置
// 定义北斗模块发送的数据缓存大小
#define BUFFER_SIZE 128
// 定义数据解析结果缓存大小
#define RESULT_SIZE 32
// 定义GNRMC数据格式结构体
typedef struct {
char utc_time[10]; // UTC时间,格式为hhmmss.ss
char status; // 状态,A为有效,V为无效
double latitude; // 纬度,格式为ddmm.mmmm
char latitude_dir; // 纬度方向,N为北纬,S为南纬
double longitude; // 经度,格式为dddmm.mmmm
char longitude_dir; // 经度方向,E为东经,W为西经
float speed; // 速度,单位为节
float course; // 航向,单位为度
char date[10]; // 日期,格式为ddmmyy
char mv; // 磁偏角方向,E为东,W为西
float mv_value; // 磁偏角,单位为度
char mv_var; // 磁偏角变化,D为减小,I为增加
char mode; // 模式指示,A为自主定位模式,D为差分GPS模式,E为估算模式
char checksum[4]; // 校验和
} GNRMC_Data;
// 使用正则表达式提取数据并存储到结构体中
int parse_GNRMC(char *buffer, GNRMC_Data *data) {
// 匹配$GNRMC,xxxxxxxxxxxx*hh
char pattern[] = "\\$GNRMC,([0-9.]*),([AV]),([0-9.]*),([NS]),([0-9.]*),([EW]),([0-9.]*)"
",([0-9.]*)\\*([0-9A-F]{2}),([0-9]{6}),([0-9.]*)?([EW])?,?([0-9.]*)?"
",?([DI])?,([ADE])\\r\\n";
regex_t reg;
regmatch_t pmatch[15];
int reti, i;
// 编译正则表达式
reti = regcomp(®, pattern, REG_EXTENDED);
if (reti) {
fprintf(stderr, "Could not compile regex\n");
return -1;
}
// 匹配数据
reti = regexec(®, buffer, 15, pmatch, 0);
if (!reti) {
// 根据匹配结果提取数据
strncpy(data->utc_time, buffer + pmatch[1].rm_so, 9);
data->utc_time[9] = '\0';
data->status = buffer[pmatch[2].rm_so];
data->latitude = atof(strndup(buffer + pmatch[3].rm_so, pmatch[3].rm_eo - pmatch[3].rm_so));
data->latitude_dir = buffer[pmatch[4].rm_so];
data->longitude = atof(strndup(buffer + pmatch[5].rm_so, pmatch[5].rm_eo - pmatch[5].rm_so));
data->longitude_dir = buffer[pmatch[6].rm_so];
data->speed = atof(strndup(buffer + pmatch[7].rm_so, pmatch[7].rm_eo - pmatch[7].rm_so));
data->course = atof(strndup(buffer + pmatch[8].rm_so, pmatch[8].rm_eo - pmatch[8].rm_so));
strncpy(data->checksum, buffer + pmatch[9].rm_so, 4);
data->checksum[4] = '\0';
strncpy(data->date, buffer + pmatch[10].rm_so, 6);
data->date[6] = '\0';
if (pmatch[11].rm_so != -1) {
data->mv = buffer[pmatch[11].rm_so];
data->mv_value = atof(strndup(buffer + pmatch[12].rm_so, pmatch[12].rm_eo - pmatch[12].rm_so));
if (pmatch[13].rm_so != -1) {
data->mv_var = buffer[pmatch[13].rm_so];
}
}
data->mode = buffer[pmatch[14].rm_so];
} else if (reti == REG_NOMATCH) {
fprintf(stderr, "No match\n");
return -1;
} else {
fprintf(stderr, "Regex match failed\n");
return -1;
}
// 释放正则表达式
regfree(®);
return 0;
}
// 将UTC时间和日期转换为北京时间
void utc_to_beijing(char *utc_time, char *date, char *beijing_time, char *beijing_date) {
struct tm t;
time_t utc, beijing;
int year, month, day, hour, minute, second;
// 解析UTC时间和日期
sscanf(utc_time, "%02d%02d%02d", &hour, &minute, &second);
sscanf(date, "%02d%02d%02d", &day, &month, &year);
// 转换为struct tm结构体
t.tm_year = year + 100; // 1900年至今的年数,需要加100
t.tm_mon = month - 1; // 月份从0开始
t.tm_mday = day;
t.tm_hour = hour;
t.tm_min = minute;
t.tm_sec = second;
// 转换为UTC时间戳
utc = mktime(&t);
// 转换为北京时间戳
beijing = utc + 8 * 3600; // 北京时间比UTC时间多8小时
// 格式化输出
strftime(beijing_time, 9, "%H%M%S", localtime(&beijing));
strftime(beijing_date, 7, "%d%m%y", localtime(&beijing));
}
int main() {
char buffer[BUFFER_SIZE];
GNRMC_Data data;
char beijing_time[10], beijing_date[10];
int ret;
while (1) {
// 从串口接收数据
// 请根据实际情况进行操作
ret = receive_uart2(buffer, BUFFER_SIZE);
if (ret < 0) {
fprintf(stderr, "UART receive error\n");
continue;
}
// 解析GNRMC数据
ret = parse_GNRMC(buffer, &data);
if (ret < 0) {
fprintf(stderr, "GNRMC parse error\n");
continue;
}
// 将UTC时间和日期转换为北京时间
utc_to_beijing(data.utc_time, data.date, beijing_time, beijing_date);
// 输出结果
printf("UTC Time: %s\n", data.utc_time);
printf("Status: %c\n", data.status);
printf("Latitude: %f %c\n", data.latitude, data.latitude_dir);
printf("Longitude: %f %c\n", data.longitude, data.longitude_dir);
printf("Speed: %f knots\n", data.speed);
printf("Course: %f degrees\n", data.course);
printf("Date: %s\n", data.date);
printf("Magnetic Variation: %f degrees %c %c\n", data.mv_value, data.mv, data.mv_var);
printf("Mode: %c\n", data.mode);
printf("Beijing Time: %s\n", beijing_time);
printf("Beijing Date: %s\n", beijing_date);
}
return 0;
}
```
注:以上代码仅供参考,可能存在错误和不足之处,请根据实际情况进行修改和完善。
阅读全文