gd32解析nema协议代码
时间: 2023-07-23 07:20:30 浏览: 160
以下是一份简单的GD32解析NEMA协议的代码示例:
```c
#include "gd32f30x.h"
#include <stdio.h>
#include <string.h>
/* 定义串口接收缓冲区大小 */
#define RX_BUF_SIZE 128
/* 定义NEMA协议消息类型枚举 */
typedef enum {
NEMA_MSG_GPGGA, // GGA消息
NEMA_MSG_GPVTG, // VTG消息
NEMA_MSG_GPGSA, // GSA消息
NEMA_MSG_GPGSV, // GSV消息
NEMA_MSG_UNKNOWN, // 未知消息
} nema_msg_type_t;
/* 定义NEMA协议消息结构体 */
typedef struct {
nema_msg_type_t type; // 消息类型
uint32_t time; // 时间
float latitude; // 纬度
float longitude; // 经度
float altitude; // 海拔高度
float speed; // 速度
float course; // 航向
uint8_t num_satellites; // 卫星数
} nema_msg_t;
/* 定义全局变量 */
static uint8_t rx_buf[RX_BUF_SIZE];
static uint8_t rx_index = 0;
static nema_msg_t nema_msg;
/* 串口接收中断处理函数 */
void USART0_IRQHandler(void)
{
if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) {
/* 读取接收数据寄存器 */
uint8_t data = usart_data_receive(USART0);
/* 判断是否接收到换行符 */
if (data == '\n') {
/* 解析NEMA协议消息 */
if (0 == strncmp((const char *)rx_buf, "$GPGGA,", 7)) {
/* GGA消息 */
nema_msg.type = NEMA_MSG_GPGGA;
/* 解析消息体 */
sscanf((const char *)rx_buf, "$GPGGA,%lu,%f,%c,%f,%c,%d,%d,%f,%f,M,%f,M,,",
&nema_msg.time, &nema_msg.latitude, &latitude_dir, &nema_msg.longitude,
&longitude_dir, &nema_msg.fix_quality, &nema_msg.num_satellites,
&nema_msg.hdop, &nema_msg.altitude, &nema_msg.geoid_sep);
} else if (0 == strncmp((const char *)rx_buf, "$GPVTG,", 7)) {
/* VTG消息 */
nema_msg.type = NEMA_MSG_GPVTG;
/* 解析消息体 */
sscanf((const char *)rx_buf, "$GPVTG,%f,T,%f,M,%f,N,%f,K",
&nema_msg.course, &nema_msg.course_true, &nema_msg.speed, &nema_msg.speed_knots);
} else if (0 == strncmp((const char *)rx_buf, "$GPGSA,", 7)) {
/* GSA消息 */
nema_msg.type = NEMA_MSG_GPGSA;
/* 解析消息体 */
sscanf((const char *)rx_buf, "$GPGSA,%c,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f",
&nema_msg.fix_mode, &nema_msg.fix_type, &nema_msg.sat1, &nema_msg.sat2,
&nema_msg.sat3, &nema_msg.sat4, &nema_msg.sat5, &nema_msg.sat6,
&nema_msg.sat7, &nema_msg.pdop, &nema_msg.hdop, &nema_msg.vdop);
} else if (0 == strncmp((const char *)rx_buf, "$GPGSV,", 7)) {
/* GSV消息 */
nema_msg.type = NEMA_MSG_GPGSV;
/* 解析消息体 */
sscanf((const char *)rx_buf, "$GPGSV,%d,%d,%d",
&nema_msg.num_msgs, &nema_msg.msg_num, &nema_msg.num_sats);
} else {
/* 未知消息 */
nema_msg.type = NEMA_MSG_UNKNOWN;
}
/* 清空接收缓冲区 */
memset(rx_buf, 0, sizeof(rx_buf));
rx_index = 0;
} else {
/* 累加接收缓冲区 */
rx_buf[rx_index++] = data;
}
}
}
int main(void)
{
/* 配置串口通信参数 */
usart_deinit(USART0);
usart_baudrate_set(USART0, 9600);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_interrupt_enable(USART0, USART_INT_RBNE);
nvic_enable_irq(NVIC_USART0_IRQ);
usart_enable(USART0);
/* 解析NEMA协议消息 */
while (1) {
if (nema_msg.type != NEMA_MSG_UNKNOWN) {
/* 处理解析出来的数据 */
// ...
/* 清空消息结构体 */
memset(&nema_msg, 0, sizeof(nema_msg));
}
}
}
```
在该示例代码中,我们首先配置了串口通信参数,然后启用了串口接收中断,并在中断处理函数中对接收缓冲区进行处理。当接收到完整的NEMA协议消息后,通过解析消息头和消息体来提取需要的数据,最后对解析出来的数据进行处理或者存储。
需要注意的是,该示例代码只是一个简单的示例,实际应用中需要根据实际情况进行修改和调试。
阅读全文