Modbus的RTU

目录

1.modbus的应用

2.modbus-rtu的硬件层

3.modbus-rtu软件实现层

4.应用举例

1、modbus的应用

         在工业控制领域,我们经常要通过读取一些传感器设备的数据,进行控制判断,从而达到闭环控制的要求。随着iot时代的到来,我们更多的设备接入,我们需要更多设备信息,比如:温度传感器、测距传感器、电池电量、模拟量等,因为modbus工业协议的存在,更多设备能够遵循modbus协议。

2、modbus-rtu的硬件层

        我们在工业控制通常在开发产品过程中,碰到很多协议,canopen、modbus-rtu、modbus-tcp、EtherCat...,通常我们都是基于硬件来看,然后再软件层面进行编程开发。我们首先来看看modbus-rtu的硬件,modbus-rtu在串口(主要是RS-485总线)的基础上,进行软件协议的规定。

3、modbus-rtu软件实现层

        首先我们来看看modbus-rtu软件层面的协议规定:

modbus一般资料格式的顺序为:

读取:站号、功能码、设备寄存器位置、读取数量、CRC1、CRC2

写入:站号、功能码、设备寄存器位置、写入数量、写入数值、CRC1、CRC2

常见的功能码及读写协议说明:

读取功能码:

一、读取线圈状态取得一组逻辑线圈的当前状态(ON/OFF)0x01;

二、读取输入状态取得一组开关输入的当前状态(ON/OFF)  :0x02;

三、读取保持寄存器 在一个或多个保持寄存器中取得当前的二进制值 :0x03;

四、读取输入寄存器在一个或多个输入寄存器中取得当前的二进制值  :0x04;

五、强置单线圈强置一个逻辑线圈的通断状态:0x05;

六、预置单寄存器把具体二进值装入一个保持寄存器:0x06;

七、读取异常状态取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定,用户逻辑可以将这些线圈定义,以说明从机状态,短报文适宜于迅速读取状态 : 0x07;

八、强置多线圈强置一串连续逻辑线圈的通断:0x0F

九、控询(只用于484)可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送:0x10

十、报告从机标识 可使主机判断编址从机的类型及该从机运行指示灯的状态 :0x17

发送读取线圈状态: 0x01

发送读取线圈状态协议说明
0x010x010xXX0x000x010xXXCRC1、2
设备站号功能码线圈位置H线圈位置L线圈数量H线圈数量L校验码

接收读取线圈状态:0x01

接收读取线圈状态协议说明
0x010x010x010xX01CRC1、2
设备站号功能码线圈数量线圈状态校验码

发送读取输入线圈状态:0x02

发送读取输入线圈状态协议说明
0x010x020x000x000x000x01CRC1、2
设备站号功能码线圈位置H线圈位置L线圈数量H线圈数量L校验码

接收读取输入线圈状态:0x02

接收读取输入线圈状态协议说明
0x010x020x010x01CRC1、2
设备站号功能码线圈数量线圈状态校验码

发送读取保持寄存器状态:0x03

发送读取保持寄存器状态协议说明
0x010x030x000x000x000x01CRC1、2
设备站号功能码寄存器位置H寄存器位置L寄存器数量H寄存器数量L校验码

接收读取保持寄存器状态:0x03

接收读取保持寄存器状态协议说明
0x010x030x020x000x00CRC1、2
设备站号功能码读取数量读取内容读取内容校验码

发送读取输入寄存器状态:0x04

发送读取输入寄存器状态及协议说明
0x010x040x100x000x000x01CRC1、2
设备站号功能码寄存器位置H寄存器位置L寄存器数量H寄存器数量L校验码

接收读取输入寄存器状态:0x04

接收读取输入寄存器状态协议说明
0x010x040x020x000x00CRC1、2
设备站号功能码读取数量读取内容H读取内容L校验码

发送写入强置单线圈:0x05

发送写入强置单线圈状态协议说明
0x010x050x000x000x000x01CRC1、2
设备站号功能码线圈位置H线圈位置L写入内容H写入内容L校验码

接收写入强置单线圈:0x05

接收写入强置单线圈状态协议说明
0x010x050x000x000x000x01CRC1、2
设备站号功能码线圈位置H线圈位置L写入内容H写入内容L校验码

发送预置单寄存器:0x06

发送写入寄存器态协议说明
0x010x060x200x000x000x01CRC1、2
设备站号功能码线圈位置H线圈位置L写入内容H写入内容L校验码

接收预置单寄存器:0x06

接收预置单寄存器状态协议说明
0x010x060x200x000x000x01CRC1、2
设备站号功能码寄存器地址H寄存器位置L写入内容H写入内容L校验码

发送写多个保持寄存器状态:0x10

发送预置单寄存器状态协议
0x010x100x200x000x000x010x020xFF0xFFCRC1、2
设备站号功能码写入寄寄存器地址H写入寄寄存器地址L写入数量写入数量写入数量写入数量写入内容校验码

接收写多个保持寄存器状态:0x10

接收写寄存器状态协议
0x010x100x200x000x000x01CRC1、2
设备站号功能码寄存器地址H寄存器位置L写入内容H写入内容L校验码

发送报告从机标识状态:0x17

发送写寄存器状态协议
0x010x170x100x000x000x010x200x000x000x010x020xff0xffCRC1、2
设备站号功能码读取地址H读取地址L写入位置H写入位置L写入数量H写入数量L写入数量H写入数量L写入数量写入内容H

写入内容

L

校验码

接收报告从机标识状态:0x17

接收写寄存器状态协议
0x010x170x020x000x00CRC1、2
设备站号功能码读取寄存器数量读取内容H读取内容L校验码

4、应用举例

一、使用libmodbus库进行程序编写。

首先我们可以通过github下载libmodbus的库,因为提供源码,我们直接可以将源码下载下来加入到我们的工程中,然后自己的工程编译即可使用libmodbus提供的现成代码。官方使用说明github地址,以及使用说明。

对常用的modbus库的函数与对应的功能码进行对应:

0x01:读取线圈状态取得一组逻辑线圈的当前状态(ON/OFF)  
/* Reads the boolean status of bits and sets the array elements 
in the destination to TRUE or FALSE (single bits). */
​​​​​​​int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)

 

0x02: 读取输入状态 取得一组开关输入的当前状态(ON/OFF) 

/* Same as modbus_read_bits but reads the remote device input table */

int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)

0x03:读取保持寄存器 在一个或多个保持寄存器中取得当前的二进制值  

/* Reads the holding registers of remote device and put the data into 
an array */
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)

0x04:读取输入寄存器 在一个或多个输入寄存器中取得当前的二进制值  

/* Reads the input registers of remote device and put the data into an array */

int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)

0x05:强置单线圈 强置一个逻辑线圈的通断状态 

/* Turns ON or OFF a single bit of the remote device */

int modbus_write_bit(modbus_t *ctx, int addr, int status)
0x06:预置单寄存器 把具体二进值装入一个保持寄存器
/* Writes a value in one register of the remote device */

​​​​​​​int modbus_write_register(modbus_t *ctx, int addr, int value)
0x0F:强置多线圈 强置一串连续逻辑线圈的通断

/* Write the bits of the array in the remote device */

int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
0x10:控询(只用于484) 可使主机与一台正在执行长程序任务从机通信,探询该从机是否已完成其操作任务,仅在含有功能码9的报文发送后,本功能码才发送
/* Write the values from the array to the registers of the remote device */

int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)

0x17:报告从机标识 可使主机判断编址从机的类型及该从机运行指示灯的状态

/* Write multiple registers from src array to remote device and read multiple
registers from remote device to dest array. */
int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb, 
const uint16_t *src, int read_addr, int read_nb, uint16_t *dest)

二、使用串口助手进行程序发送指令验证。

我们在用串口助手进行验证过程中,需要计算CRC值,可以通过在线的CRC计算器进行计算,以此来验证自己程序是否正确(在线CRC校验计算器),可以直接使用串口助手进行验证自己的程序是否正确。

参考一下博客:

https://mp-new.csdn.net/mp_blog/creation/editor/117441226

https://www.it610.com/article/1289192766110244864.htm

https://www.cnblogs.com/ioufev/articles/10830028.html

https://libmodbus.org/docs/v3.1.4/

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值