【音频相关】串口通信协议设计(两STM32间温度、湿度、压强传输)

协议帧结构

[帧头][数据长度][命令字][温度数据][湿度数据][压强数据][校验和][帧尾]

详细说明

字段 长度(bytes) 说明 示例值
帧头 2 固定值 0xAA55 0xAA55
数据长度 1 命令字+数据的总长度 0x0C (12字节)
命令字 1 0x01:传感器数据 0x01
温度 4 float类型,单位℃ 25.6℃
湿度 4 float类型,单位%RH 60.5%
压强 4 float类型,单位hPa 1013.25hPa
校验和 1 从命令字到压强数据的累加和取低8位 0xXX
帧尾 2 固定值 0x55AA 0x55AA

STM32发送端代码示例

#include "stm32f1xx_hal.h"
#include <string.h>
#include <math.h>

#pragma pack(push, 1)
typedef struct {
    uint16_t header;      // 0xAA55
    uint8_t length;       // 数据长度
    uint8_t cmd;          // 命令字
    float temperature;    // 温度
    float humidity;       // 湿度
    float pressure;       // 压强
    uint8_t checksum;     // 校验和
    uint16_t footer;      // 0x55AA
} SensorDataFrame;
#pragma pack(pop)

void send_sensor_data(UART_HandleTypeDef *huart, float temp, float humi, float pres) {
    SensorDataFrame frame;
    
    // 填充帧结构
    frame.header = 0xAA55;
    frame.length = sizeof(frame.cmd) + sizeof(frame.temperature) + 
                  sizeof(frame.humidity) + sizeof(frame.pressure);
    frame.cmd = 0x01;
    frame.temperature = temp;
    frame.humidity = humi;
    frame.pressure = pres;
    frame.footer = 0x55AA;
    
    // 计算校验和(命令字+所有数据)
    uint8_t *p = (uint8_t*)&frame.cmd;
    frame.checksum = 0;
    for(int i=0; i<frame.length; i++) {
        frame.checksum += p[i];
    }
    
    // 发送数据
    HAL_UART_Transmit(huart, (uint8_t*)&frame, sizeof(frame), 100);
}

STM32接收端代码示例

#include "stm32f1xx_hal.h"
#include <string.h>

#define MAX_FRAME_SIZE sizeof(SensorDataFrame)

uint8_t rx_buffer[MAX_FRAME_SIZE];
uint8_t rx_index = 0;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    static uint8_t frame_started = 0;
    
    if(rx_index == 0 && rx_buffer[0] == 0xAA && rx_buffer[1] == 0x55) {
        frame_started = 1;
        rx_index = 2;
    } else if(frame_started) {
        rx_index++;
        
        if(rx_index >= MAX_FRAME_SIZE) {
            // 完整帧接收完成
            SensorDataFrame *frame = (SensorDataFrame*)rx_buffer;
            
            // 验证帧尾
            if(frame->footer == 0x55AA) {
                // 计算校验和
                uint8_t checksum = 0;
                uint8_t *p = (uint8_t*)&frame->cmd;
                for(int i=0; i<frame->length; i++) {
                    checksum += p[i];
                }
                
                if(checksum == frame->checksum) {
                    // 数据有效,处理数据
                    float temperature = frame->temperature;
                    float humidity = frame->humidity;
                    float pressure = frame->pressure;
                    
                    // 在这里添加你的数据处理代码...
                }
            }
            
            // 重置接收状态
            rx_index = 0;
            frame_started = 0;
        }
    }
    
    // 继续接收下一个字节
    HAL_UART_Receive_IT(huart, &rx_buffer[rx_index], 1);
}

void init_uart_receiver(UART_HandleTypeDef *huart) {
    HAL_UART_Receive_IT(huart, rx_buffer, 2); // 开始接收帧头
}

使用说明

  1. 初始化:

    • 在发送端和接收端初始化UART外设(如USART1)

    • 波特率建议使用9600、115200等常用值

    • 数据位8位,无校验,停止位1位

  2. 发送数据:

    • 在发送端调用send_sensor_data()函数,传入温度、湿度、压强值

  3. 接收数据:

    • 在接收端调用init_uart_receiver()初始化接收

    • 接收到的有效数据会在回调函数中处理

增强建议

  1. 添加超时机制,防止半帧数据长时间占用缓冲区

  2. 增加重发机制,当校验失败时请求重发

  3. 对于高噪声环境,可以考虑增加CRC校验代替简单校验和

  4. 添加数据加密功能,防止数据被篡改

这个协议设计简单实用,适合STM32之间的传感器数据传输,可根据实际需求进行调整。

 
 
 
 
 
 
posted @ 2025-06-17 22:35  FBshark  阅读(137)  评论(0)    收藏  举报