【音频相关】串口通信协议设计(两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); // 开始接收帧头
}
使用说明
-
初始化:
-
在发送端和接收端初始化UART外设(如USART1)
-
波特率建议使用9600、115200等常用值
-
数据位8位,无校验,停止位1位
-
-
发送数据:
-
在发送端调用
send_sensor_data()函数,传入温度、湿度、压强值
-
-
接收数据:
-
在接收端调用
init_uart_receiver()初始化接收 -
接收到的有效数据会在回调函数中处理
-
增强建议
-
添加超时机制,防止半帧数据长时间占用缓冲区
-
增加重发机制,当校验失败时请求重发
-
对于高噪声环境,可以考虑增加CRC校验代替简单校验和
-
添加数据加密功能,防止数据被篡改
这个协议设计简单实用,适合STM32之间的传感器数据传输,可根据实际需求进行调整。

浙公网安备 33010602011771号