3.5T静默分帧,CRC16校验:Modbus-RTU帧结构解析

短文标题:3.5T静默分帧,CRC16校验:Modbus-RTU帧结构解析

你有没有想过一个问题:Modbus-RTU数据帧没有固定的帧头,接收方怎么知道一帧从哪里开始、到哪里结束?靠"沉默"来分帧。 协议规定:两个字节之间的间隔超过3.5个字符时间,就认为上一帧结束,下一帧开始。

**3.5T(3.5字符时间)怎么算?**以9600bps、8N1(10位/字符,1起始+8数据+1停止)为例:

  • 1位时间 = 1/9600 ≈ 104µs
  • 1字符时间 = 10 × 104µs ≈ 1.04ms
  • 3.5T = 3.5 × 1.04ms ≈ 3.64ms

**IDLE中断检测帧结束,**USART的IDLE标志在总线空闲超过1字符时间时置1,可配合软件定时器测量更精确的3.5T,或直接用IDLE中断触发帧结束标志(工程实践中通常足够)。

void USART2_IRQHandler(void)

{

if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)) {

__HAL_UART_CLEAR_IDLEFLAG(&huart2);

// 帧接收完成

frame_received = 1;

}

}

Modbus-RTU帧结构

  • 地址:从机地址(1~247),0为广播地址
  • 功能码:03读保持寄存器、06写单个寄存器、05写线圈
  • 数据:寄存器地址、数量、写入值
  • CRC16:从地址到数据区末尾,低字节在前

常用功能码

DMA+IDLE接收变长帧

// 配置DMA接收

HAL_UART_Receive_DMA(&huart2, rx_buffer, BUFFER_SIZE);

// IDLE中断中处理

void USART2_IRQHandler(void)

{

if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)) {

__HAL_UART_CLEAR_IDLEFLAG(&huart2);

HAL_UART_DMAStop(&huart2);

uint16_t len = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart2.hdmarx);

// len就是这一帧的长度,处理数据

HAL_UART_Receive_DMA(&huart2, rx_buffer, BUFFER_SIZE);

}

}

这个故事的启示, Modbus-RTU没有帧头,用"静默"分帧------3.5T就是它的"句号"。CRC16保数据完整,一个bit错都不同。学会解析帧结构,Modbus通信不再神秘。写在最后, Modbus-RTU帧结构就四部分:地址区分设备,功能码定操作,数据传内容,CRC保安全。


(本文灵感源于于振南《新概念ARM32单片机》教程第4.16节、第4.17节。)

觉得有用?点赞、转发,让更多人看懂Modbus-RTU的帧结构。

相关推荐
comyccccc23 分钟前
3.3V稳压电源设计与PCB实现学习笔记
单片机·嵌入式硬件
SKH.33 分钟前
ARM-时钟、定时器
arm开发
小程序设计1 小时前
基于STM32森林火灾远程监测模块设计
stm32·单片机·嵌入式硬件
魔猴疯猿1 小时前
香橙派(Orange Pi)入门使用教程:从开箱到跑通第一个项目
单片机·嵌入式硬件·物联网
丸子君君2 小时前
【以麒麟服务器时间为准,定时请求时间同步】
运维·服务器·单片机
沐欣工作室_lvyiyi3 小时前
基于STM32单片机汽车充电桩控制模块设计(论文+源码)
stm32·单片机·汽车·毕业设计
嵌入式-老费3 小时前
esp32开发与应用(用Python+PySide6解决上位机开发)
linux·单片机·嵌入式硬件
平凡灵感码头3 小时前
HNB 加热不燃烧:从加热仓到 MCU,拆一套小型精准热管理系统
单片机·嵌入式硬件
逐梦之程3 小时前
嵌入式固件升级IAP及调试软件
stm32·单片机
XMAIPC_Robot3 小时前
为什么大型储能需要边缘 AI 协调控制器?RK3588+FPGA 高速采集方案
人工智能·嵌入式硬件·fpga开发·arm+fpga·rk3588+fpga·协调控制器