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的帧结构。

相关推荐
恒锐丰科技林技术员21 小时前
EG27524 双通道栅极驱动芯片:高速功率变换系统的驱动利器
经验分享·嵌入式硬件·硬件工程
蓝天下的守望者21 小时前
ARM CoreLink IP Overview
arm开发
恒锐丰科技林技术员1 天前
EG2003:200V 半桥 MOS/IGBT 栅极驱动芯片解析
经验分享·嵌入式硬件·硬件工程
cnnews1 天前
Ubuntu 编译 postmarketOS
linux·运维·arm开发·ubuntu·github·音视频
LCG元1 天前
STM32 硬件SPI驱动W25Q Flash实战:从CubeMX配置到DMA高速读写
stm32·单片机·嵌入式硬件
HRTOS1 天前
HRTOS应用示例:信号量机制详解
c语言·人工智能·嵌入式硬件·51单片机
从零开始的嵌入式之旅1 天前
day36
linux·c语言·经验分享·笔记·嵌入式硬件
Doraemomo1 天前
硬件基础概念
arm开发
HRTOS1 天前
HRTOS应用示例:Mutex互斥锁机制详解
c语言·单片机·嵌入式硬件·51单片机
铅笔小新z1 天前
【stm32】I2C 阻塞通信实战与 HAL 源码
stm32·单片机·嵌入式硬件