基于嵌入式STM32的Modbus RTU协议实现(3)
时间:2026-01-15
时间:2026-01-15
2014年第11期仪表技术
Bit字,而PNum是操作的数据。
·35·
如图3所示为ModbusRTU主站程序流程图。为实现ModbusRTU主站协议的功能处理模块,首先需然后根据服要完成串口的初始化和服务函数的构造,
务构造函数构造Modbus请求帧并且调用串口发送命令将请求帧发送出去,如果程序在设定的时间内接收到应答帧,程序将调用对应的应答帧解析函数进行处
图2
系统网络结构
3.1ModbusRTU主站的实现
Modbus主站服务程序的核心模块是功能处理模
理,否则返回应答超时码。同时,解析函数对串口缓冲区内接收到的数据进行分析,若应答帧解析正确,函数将数据装入目标缓冲区,否则返回校验失败码
。
块,包括串口初始化、数据帧的构造和解析以及发送数
据帧等功能。发送数据帧时必须将其封装成标准的Modbus数据帧才能进行发送。在协议帧的组成上,Modbus协议定义了一个与基础通信层无关的简单协议数据单元(PDU),通过在PDU上增加地址域和CRC校验域等附加域定义了应用数据单元(ADU)。CRC码为2个字节,16位的二进制值。由发送设备计算CRC值,并把它附到信息中去。接收设备在接收信息过程中再次计算CRC值并与CRC的实际值进行比较,若两者不一致,即产生一个错误。校验开始,时,把16位寄存器的各位都置为“1”然后把信息中
只的相邻2个8位字节数据放到当前寄存器中处理,
有每个字符的8位数据用于CRC处理,起始位、停止位和校验位不参与CRC计算。
CRC校验时,每个8位数据与该寄存器的内容进行异或运算,然后向最低有效位(LSB)方向移位,用零填入最高有效位(MSB)后,再对LSB检查,若LSB=1,则
不作异或运算。寄存器与预置的固定值异或;若LSB=0,
重复上述处理过程,直至移位8次,最后一次(第
8次)移位后,下一个8位字节数据与寄存器的当前值异或,再重复上述过程。全部处理完信息中的数据字节后,最终得到的寄存器值为CRC值。
CRC值附加到信息时,低位在先,高位在后。为了方便功能参数的获取,定义了一个如下结构体:
typedefstruct{
unsignedcharSlaveID;unsignedcharFunc;intStartAddr;intPNum;}Parameter
图3ModbusRTU主站程序流程图
3.2ModbusRTU从站的实现
ModbusRTU协议是一个一主多从的通信协议,所
以需要对每个从站分配不同的地址。ModbusRTU从
站主要实现数据帧的接收和存储,并且根据接收到的数据帧中的功能代码给出一应答消息作为对主站的回应。ModbusRTU从站的程序设计流程图如图4所示。首先需要对串口初始化,如设置波特率、数据位和奇偶校验位等,然后调用串口接收命令读取主站发送来的数据帧,并判断接收到的数据帧中的地址与本机是否相符,如果不符,直接结束,否则对数据帧进行CRC校验。当校验正确的时候就可以根据相应的功否则向主站能代码调用对应的函数去执行功能操作,
返回一个错误信息的应答帧。下面是功能代码为03时,读保持寄存器的功能函数。
voidreadholdingregister(unsignedchar*Rx){
StartAddr=(*Rx++)<<8;StartAddr+=*Rx++;//起始地址
其中SlaveID是从站地址,一个Modbus网络最多
允许有255个从站。Func是服务功能号的选择。StartAddr是需要操作的设备在从站中的地址,它是16