基于GD32F4XX串口环形缓冲区,北斗2.1协议,RD模块数据解析代码

以下是基于GD32F4XX串口,使用sscanf函数、strstrstrcmp,并结合环形缓冲区在中断中写数据,主函数处理发送接收的代码示例:

串口初始化与环形缓冲区定义

c 复制代码
#include <gd32f4xx.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUF_SIZE 256 // 环形缓冲区大小

// 环形缓冲区结构体
typedef struct {
    uint8_t buffer[BUF_SIZE];
    uint16_t write_idx;
    uint16_t read_idx;
} RingBuffer;

RingBuffer rx_ring_buf;

// 初始化串口
void usart_init(uint32_t baudrate) {
    rcu_periph_clock_enable(RCU_USART0);
    rcu_periph_clock_enable(RCU_GPIOA);

    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);

    usart_deinit(USART0);
    usart_baudrate_config(USART0, baudrate);
    usart_word_length_config(USART0, USART_WL_8BIT);
    usart_stop_bit_config(USART0, USART_SBT_1BIT);
    usart_parity_config(USART0, USART_PM_NONE);
    usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
    usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);

    // 开启中断
    usart_interrupt_enable(USART0, USART_INT_RBNE);
    nvic_priority_group_config(NVIC_PRIORITY_GROUP_2);
    nvic_irq_enable(USART0_IRQn, 0, 0);
}

// 初始化环形缓冲区
void ring_buffer_init(RingBuffer *ring_buf) {
    ring_buf->write_idx = 0;
    ring_buf->read_idx = 0;
}

// 写入环形缓冲区
void ring_buffer_write(RingBuffer *ring_buf, uint8_t data) {
    ring_buf->buffer[ring_buf->write_idx] = data;
    ring_buf->write_idx = (ring_buf->write_idx + 1) % BUF_SIZE;
}

// 从环形缓冲区读取数据
uint8_t ring_buffer_read(RingBuffer *ring_buf) {
    uint8_t data = ring_buf->buffer[ring_buf->read_idx];
    ring_buf->read_idx = (ring_buf->read_idx + 1) % BUF_SIZE;
    return data;
}

// 环形缓冲区是否为空
uint8_t ring_buffer_is_empty(RingBuffer *ring_buf) {
    return (ring_buf->read_idx == ring_buf->write_idx);
}

串口接收中断处理

c 复制代码
// 串口中断服务函数
void USART0_IRQHandler(void) {
    if (usart_flag_get(USART0, USART_FLAG_RBNE) != RESET) {
        uint8_t received_data = usart_data_receive(USART0);
        ring_buffer_write(&rx_ring_buf, received_data);
    }
}

北斗协议解析与发送

c 复制代码
// 北斗协议解析函数
void parse_bds_sentence() {
    static char sentence_buf[256];
    static uint8_t sentence_idx = 0;
    char *token;

    while (!ring_buffer_is_empty(&rx_ring_buf)) {
        uint8_t data = ring_buffer_read(&rx_ring_buf);
        sentence_buf[sentence_idx++] = data;

        if (data == '\n' || sentence_idx >= sizeof(sentence_buf)) {
            sentence_buf[sentence_idx] = '\0';
            sentence_idx = 0;

            // 找到开头的$符号
            char *start_pos = strstr(sentence_buf, "$");
            if (start_pos) {
                // 提取指令关键字
                char command[16];
                sscanf(start_pos, "$%[^,*]", command);

                // 判断指令类型并进行解析
                if (strcmp(command, "BDICI") == 0) {
                    parse_bds_card(start_pos);
                } else if (strcmp(command, "BDBSI") == 0) {
                    parse_bds_signal(start_pos);
                } else if (strcmp(command, "BDDWR") == 0) {
                    parse_bds_position(start_pos);
                } else if (strcmp(command, "BDTXR") == 0) {
                    parse_bds_message(start_pos);
                }
            }
        }
    }
}

// 解析北斗卡号
void parse_bds_card(char *sentence) {
    char card_number[16];
    sscanf(sentence, "$BDICI,%[^,]", card_number);
    printf("Beidou Card Number: %s\n", card_number);
}

// 解析信号状态
void parse_bds_signal(char *sentence) {
    char signal_values[50];
    sscanf(sentence, "$BDBSI,%4s,%4s,%[^,*]", NULL, NULL, signal_values);
    printf("Signal Values: %s\n", signal_values);
}

// 解析定位信息
void parse_bds_position(char *sentence) {
    char time[16], latitude[16], longitude[16], altitude[16];
    sscanf(sentence, "$BDDWR,%*[^\r\n],%[^,],%[^,],%[^,],%[^,],%[^,],", time, latitude, longitude, altitude);
    printf("Position - Time: %s, Latitude: %s, Longitude: %s, Altitude: %s\n", time, latitude, longitude, altitude);
}

// 解析接收到的消息
void parse_bds_message(char *sentence) {
    char message_content[100];
    sscanf(sentence, "$BDTXR,%*[^,],%*[^,],%[^,]", message_content);
    printf("Received Message: %s\n", message_content);
}

主函数与发送功能

c 复制代码
//送 发北斗指令
void send_bds_sentence(const char *sentence) {
    uint8_t len = strlen(sentence);
    for (uint8_t i = 0; i < len; i++) {
        usart_data_transmit(USART0, sentence[i]);
        while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET);
    }
}

// 主函数
int main(void) {
    rcu_clock_prescale_config(RCU_APB2_RTCPrescale, 1);
    rcu_clock_configuration();
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_AF);

    // 初始化串口
    usart_init(9600);

    // 初始化环形缓冲区
    ring_buffer_init(&rx_ring_buf);

    while (1) {
        // 解析接收到的数据
        parse_bds_sentence();

        // 发送北斗指令示例
        static uint8_t send_flag = 0;
        send_flag++;
        if (send_flag > 100) { // 模拟发送频率控制
            send_flag = 0;
            // 发送读取卡号指令
            send_bds_sentence("$CCICA,0,00*7B\r\n");
            delay_1ms(100); // 简单延时函数
        }
    }
}

异或校验字节计算

c 复制代码
// 计算异或校验字节
char calculate_checksum(const char *sentence) {
    char *start = strstr(sentence, "$") + 1;
    char *end = strstr(start, "*");
    if (!end) return 0x00;

    uint8_t checksum = 0;
    while (start < end) {
        checksum ^= *start++;
    }
    return checksum;
}

说明

  1. 本代码示例适用于GD32F4XX系列MCU,需要根据具体型号调整引脚和时钟配置。
  2. 环形缓冲区大小可以根据实际应用需求调整。
  3. sscanf函数用于解析北斗协议中的字段,strstrstrcmp用于指令识别。
  4. 在实际应用中,需要添加有效的延时函数delay_1ms和错误处理机制。
  5. 异或校验字节在发送指令时需要正确计算,可调用calculate_checksum函数。
  6. 根据需求,可以扩展解析和发送更多类型的北斗短报文协议指令。
相关推荐
学不动CV了4 分钟前
C语言(FreeRTOS)中堆内存管理分析Heap_1、Heap_2、Heap_4、Heap_5详细分析与解析(二)
linux·c语言·arm开发·stm32·单片机·51单片机
拉姆哥的小屋8 分钟前
突破传统!基于SAM架构的双模态图像分割:让AI“看见“红外与可见光的完美融合
人工智能·架构
做运维的阿瑞12 分钟前
Python核心架构深度解析:从解释器原理到GIL机制全面剖析
开发语言·python·架构·系统架构
软件算法开发15 分钟前
基于黑翅鸢优化的LSTM深度学习网络模型(BKA-LSTM)的一维时间序列预测算法matlab仿真
深度学习·算法·lstm·时间序列预测·黑翅鸢优化·bka-lstm
小南家的青蛙16 分钟前
LeetCode第79题 - 单词搜索
算法·leetcode·职场和发展
PAK向日葵20 分钟前
【算法导论】PDD 0928 笔试题解
算法·面试
我爱计算机视觉2 小时前
ICCV 2025 (Highlight) Being-VL:师夷长技,用NLP的BPE算法统一视觉语言模型
人工智能·算法·语言模型·自然语言处理
头发还没掉光光5 小时前
C++STL之list
c语言·数据结构·c++·list
virtual_k1smet8 小时前
#等价于e * d ≡ 1 mod φ(n) #模逆元详解
人工智能·算法·机器学习
transuperb8 小时前
51单片机红外遥控
单片机·嵌入式硬件