UIFLOW ModbusMaster介绍及实例测试
本帖最后由 MASH1R0 于 2021-8-23 16:49 编辑UIFLOW Modbus Master
1.Modbus Rtu和RS-485
简介
MODBUS是一种串行的通信协议,是工业电子设备之间常用的连接方式。modbus协议包括modbus RTU、modbus ASCII和modbus TCP,其中以为modbusRTU的成本低于modbustcp和传输效率高于modbusASCII使其更为常用。Modbus是一种通信协议,相当于只是约定好了收发两端通信的格式,实现数据的传输还需要传输的媒介。RS485采用半双工工作方式,支持多点数据通信。传输距离长、多节点和传输线成本低,多优点集于一身的rs485在自动化领域应用广泛,所以软件协议的modbusRTU也经常和硬件总线的rs485搭配在一起使用。
ModbusRTU协议
地址区功能码数据CRC16
1字节(8位)1字节(8位)N字节(N×8位)2字节(16位)
(1)地址区:
信息帧的地址区在帧开的始部分,由8位组成,主机把从机地址放入信息帧的地址区,并向从机寻址。从机响应时,把自己的地址放入响应信息的地址区,让主机识别已作出响应的从机地址。地址0为广播地址,所有从机均能识别。当Modbus协议用于高级网络时,则不允许广播或其它方式替代。
(2)功能码:
代码名称功能
0x01读取线圈状态读取一路或多路线圈的开闭状态
0x02读取输入状态读取一路或多路线圈当前的输入状态
0x03读取保持寄存器读取一个或多个保持寄存器(可读写)中的数据
0x04读取输入寄存器读取一个或多个输入寄存器(只读)中的数据
0x05写单个线圈强制单个线圈的开闭状态
0x06写单个保持寄存器把一个值预置到一个保持寄存器中
0x0f写多个线圈按线圈的顺序强制各线圈开闭状态
0x10写多个保持寄存器把数据按顺序预置到各寄存器中
(3)数据:
根据功能码的不同,在数据区填入的数据也会不同。(以从机17(0x11)为例)
0x01和0x02:
从机id功能数据CRC16
0x110x01或0x02起始地址高位起始地址低位读取个数高位读取个数低位CRC高位CRC低位
例:主机 0x11 0x01 0x00 0x00 0x00 0x06 + CRC16(Hi) + CRC16(Lo)
从机 0x11 0x01 0x01 0x1a + CRC16(Hi) + CRC(Lo)
“指令为从00开始读6个线圈的状态,从机返回的0x01表示返回的数据位为1字节,0x2a转换为2进制为00011010,表示01和03和04处的状态为1”
0x03和0x04:
从机id功能数据CRC16
0x110x03或0x04寄存器起始地址高位寄存器起始地址低位读取寄存器高位读取寄存器低位CRC高位CRC低位
例:主机 0x11 0x03 0x00 0x02 0x00 0x03 + CRC16(Hi) + CRC16(Lo)
从机 0x11 0x03 0x06 0x0A 0x01 0x0A 0x02 0x0A 0X03 +CRC16(Hi) + CRC16(Lo)
“指令为从寄存器0002开始读3个寄存器中的数据,从从机返回的报文中可以看到返回了6(0x06)个字节的数据,其中0002中的数据为0A01,0003的是0A02,0004的是0A03”
03和04的报文的格式相同,但面向的寄存器不同。(保持寄存器可读写,输入寄存器只读)
0x05:
从机id功能数据CRC16
0x110x05线圈地址高位线圈地址低位写入状态高位写入状态低位CRC高位CRC低位
例:主机 0x11 0x05 0x00 0x02 0xFF 0x00 + CRC16(Hi) + CRC16(Lo)
从机 与主机报文一致
“指令为闭合02线圈,主从报文格式一致,从机在响应后发送报文”
0xFF00为闭合指令0x0000为开指令
0x06:
从机id功能数据CRC16
0x110x06寄存器地址高位寄存器地址低位写入数据高位写入数据低位CRC高位CRC低位
例:主机 0x11 0x06 0x00 0x01 0x0A 0x00 + CRC16(Hi) + CRC16(Lo)
从机 与主机报文一致
“指令为写入0A00到0001寄存器中”
0x0f:
例:
从机ID功能线圈开始地址线圈个数写入字节数写入的数据CRC16
0x110x0f0x00 0x010x00 0x090x020x68 0x01
“指令为从线圈01开始写9个线圈状态,0x68(0110 1000)表示将04、06、07线圈置1,0x01(0000 0001)表示将09置1”
0x10:例:
从机ID功能寄存器地址寄存器个数写入字节数写入的数据CRC16
0x110x100x00 0x010x00 0x020x040x00 0xAA 0x00 0xBB
“指令为向0001和0002寄存器分别写入0x00AA和0x00BB”
(4)CRC校验:
在数据传输的过程中有时会因为噪声或其他干扰的影响而发生错误,将主机要发送的数据后面加上CRC校验,从机接收到数据后将数据再进行一次CRC校验,将得出的结果与接收到数据的后两位CRC校验位相比,若计算结果与接收结果相同则证明数据正确,反之则舍弃这次数据。
2.UIFLOW Modbus Master API
READ:
.读取1路或多路线圈状态(01)
参数:
slave address(从机地址)
starting address(线圈起始地址)
coil qty(线圈个数)
.读取一路或多路线圈输入状态(02)
参数:
slave address (从机地址)
starting address(输入起始地址)
input qty(输入个数)
.读取保持寄存器(03)
参数:
slave address(从机地址)
starting address(保持寄存器起始地址)
register qty(寄存器个数)
signed(接收的数据是否有符号位)
.读取输入寄存器(04)
参数:
slave address(从机地址)
starting address(输入寄存器起始地址)
register qty(寄存器个数)
signed(接收的数据是否有符号)
WRITE:
.写单个线圈状态(05)
参数:
slave address(从机地址)
output address(线圈地址)
output value(线圈状态)
.写单个寄存器状态(06)
参数:
slave address(从机地址)
register address(寄存器地址)
register value(写入内容)
signed(是否有符号)
.写多个线圈状态(0f)
参数:
slave address(从机地址)
starting address(线圈起始地址)
output value(线圈状态)
Tips:可用数组设定多个线圈的状态。
.写多个寄存器状态(10)
参数:
slave address(从机地址)
starting address(线圈起始地址)
register value(写入内容)
Tips:可用数组设定多个寄存器中的内容。
以上函数会完成发送和接收两个步骤,在接收到从机的报文后将数据(不包括从机地址、功能码、字节数和CRC校验位)作为函数的返回值。
3.应用实例
8路485开关量采集模块:
硬件:开关量采集模块、M5STACK(主控)、M5-UNIT-485(串口转485模块)
代码:
配置串口后,在循环中调用modbus库中02功能(Read discrete inputs)的API,默认从机地址为1,起始输入地址为0,往后读8个输入,将返回值写入“READ”中。
模拟量转485模块:
硬件:模拟量转485模块(0-5v/4-20mA)、M5STACK(主控)、M5-UNIT-RS485 (串口转485模块)
代码:
初始化串口后,在循环中调用03功能(Read holding registers)的api。查看模块说明书,两个模拟量输入转换的数据保存在0x0000和0x0001中,将起始地址设为0x0000,读取的寄存器个数为2,完成读取报文的设定。模块返回的值被保存到“READ”中,其第一第二个元素分别对应IN0、IN1的数据。
0-5V模拟量转换
1.3V
读数:IN1:1066
2.7V
读数:IN1:2215
3.5V
读数:IN1:2870
4-20mA模拟量转换
8mA
读数:1204
14mA
读数:2177
18mA
读数:2770
2路485继电器模块:
硬件:2路485继电器模块、M5STACK(主控)、M5-UNIT-RS485(串口转485模块)
代码:
设置好串口后就可以开始进行modbus通信了,该继电器模块中继电器1的地址为0,继电器2的地址为1,控制线圈闭合即打开继电器只需向其地址输入0xFF00,反之则输入0x0000。为展示功能码01和0f的用法,将两继电器状态按下表设定,可根据实际情况选用合适的功能码。
STATERELAY1RELAY2
000
101
211
310
状态1
状态2
状态3
4.UIFLOW MODBUS MASTER测试
8路485开关量采集模块
模拟量转485模块
2路485继电器模块
更新频率:
将函数执行前后时间记录下来后,用串口打印出时间的间隔,各个模块均采样了180次。
更新时间与主机从机的响应都有关系,从图表中可以看出这几个实例中的更新时间是比较稳定的。ADC(I)和ADC(V)的实例中采用同一份代码,在两个从机不同的情况下仍然保持相近的更新频率;在485继电器实例中有意用0x05的功能码和0X0F功能码分开处理两个继电器。可以发现在处理多个线圈或寄存器时,两个0x05功能码的效率是远远不及一个0x0F功能码的高,在处理多个线圈或寄存器时应优先考虑0x0F和0x10功能。
稳定性:
在采集数据的过程及其之后的时间内均没有因“CRC错误”或“接收不到从机报文”而使得代码无法运行的情况。
5.总结
UIFLOW的modbus库稳定性和实时性均能满足大部分需求,按照常用的功能码进行分类,只需了解基础的modbus原理便能灵活应用。UIFLOW直观、简洁和便利,无论是用于做测试或做工程均能有效缩短研发周期提升效率。
页:
[1]