如何为UART传输设置消息起始字节 实现STM32到Simulink稳定传输
解决方案
核心实现思路
当前问题根源是传输数据流没有明确的帧边界标识,Simulink无法区分每个数据帧的起始位置,才会出现顺序错乱。只需在每次发送有效数据前增加固定的双字节帧头,Simulink侧即可通过识别帧头完成帧同步,保证数据顺序正确。
- 选择两个冲突概率极低的固定值作为帧头,推荐常用的
0xAA、0x55组合 - 定义固定帧结构:[帧头1][帧头2][counter低字节][counter高字节][offset低字节(可选)][offset高字节(可选)]
- streamActive=1时帧长固定为4字节,streamActive=2时帧长固定为6字节,Simulink识别到帧头后按对应长度取数即可
修改后代码示例
// 先定义帧头常量 #define FRAME_HEADER1 0xAA #define FRAME_HEADER2 0x55 // OFFSET_VALUE、MAX_VALUE保留你原有定义即可 //Serial Stream Routine if ((streamActive != 0) && (dataReady == 1)) { uint8_t tx_buf[6]; // 最长帧长6字节,覆盖所有传输场景 do{ uint8_t buf_idx = 0; // 填充帧头 tx_buf[buf_idx++] = FRAME_HEADER1; tx_buf[buf_idx++] = FRAME_HEADER2; // 填充counter的高低字节(小端序,和原有逻辑一致) tx_buf[buf_idx++] = counter & 0xFF; tx_buf[buf_idx++] = (counter >> 8) & 0xFF; if(streamActive == 2){ // 传输offset的场景 uint16_t offset = counter + OFFSET_VALUE; tx_buf[buf_idx++] = offset & 0xFF; tx_buf[buf_idx++] = (offset >> 8) & 0xFF; } // 一次性发送整帧,比多次单字节发送稳定性更高 HAL_UART_Transmit(&huart2, tx_buf, buf_idx, HAL_MAX_DELAY); counter++; dataReady = 0; }while(counter < MAX_VALUE); }
配套注意事项
- Simulink侧配置消息头识别规则为匹配
0xAA 0x55双字节序列,匹配成功后,streamActive=1时取后续2字节解析为counter,streamActive=2时取后续4字节,前2字节为counter、后2字节为offset - 解析uint16变量时注意字节序和发送端一致:当前采用的是小端序(先传低字节、后传高字节),Simulink拼接时要按对应规则组合,避免数值错误
- 如果业务场景中counter和offset可能出现
0xAA 0x55的连续值,可在帧尾增加1字节的和校验,进一步降低识别错误概率:校验值等于counter两个字节加offset两个字节的和对256取余,Simulink解析时做校验对比即可
内容的提问来源于stack exchange,提问作者Giulio
相关产品推荐
相关产品推荐

