Modbus-RTU协议

1、帧结构

帧结构 = 地址 + 功能码+ 数据 + 校验

那么这一组数据是什么意思呢?

从上面的结构图中,可以看出,主机发送的数据大致是 地址+功能码+数据+校验;

所以解析如下:

发送数据解析

回复数据解析

基本流程就是:

就是这么简单!

2.2 修改功能码0x06

如果我要修改从机的数据呢?那么这个协议有吗?当然有,那就是0x06

1、修改—0x06功能码

诶,看上去怎么一样的啊?是不是错了?答案是这是正确的;

发送数据解析

回复数据解析

0x10—主机发送起始地址+寄存器个数+总字节数+数据,从机返回起始地址+寄存器数量

6 Modbus-ACSII协议

一般只需要了解RTU协议,因为前面有说过,必须要有RTU协议的,所以只需要了解了RTU协议,就可以读出设备信息了,至于ACSII协议,做个大概了解即可。

1.帧形式

对于RTU协议,比如RTU发送一个字节:0x12;ASCII协议则需要发送2个字节:一个字节代表ASCII码1,一个代表ASCII码2,即0x310x32,才能代表0x12。所以,ASCII协议的效率比较低。但是ASCII更符合串口打印查看,因为串口发送的数据一般都是文本模式(ASCII)。

比如用RTU方式,也叫16进制方式,要发0x03数据,RTU方式就发送00000011。用ASCII发送0x03,就要发送0的ASCII码0x30和3的ASCII码0x33,对应到2进制也就是发送0011000000110011。很显然RTU方式只需要发送8位就可以了(加上起始位和停止位就是10位数据)。那么ASCII码方式发送就需要两个8位(每个8位分别加上起始位和停止位就是20位数据)。也就是说ASCII码发送数据量是RTU方式的2倍,所以ASCII码效率更低。

那么ASCII码效率更低,数据发送量大为啥还采用这种方式呢?

因为假如你要发送数据0x03,采用RTU方式(16进制发送),计算机中端设备接收到0x03后是不可以显示的,就是不能把0x03打印出来。因为可见字符的ASCII码是从32—126,不是这个范围以外的显示屏上都看不到,会出现乱码,如果是串口助手的话就会显示□□□□。如果采用ASCII方式(文本模式发送),就不会出现不可显示和乱码的情况,因为文本模式发送0x03,就是发送ASCII码0和ASCII码3,也就是0x300x33,是可以正常显示在计算机中端的。所以现在知道为什么还要使用ASCII效率比较低的方式发送了吧,只是为了方便调试显示而已。

  • 地址: 占用一个字节,范围0-255,其中有效范围是1-247,其他有特殊用途,比如255是广播地址(广播地址就是应答所有地址,正常的需要两个设备的地址一样才能进行查询和回复)。

  • 功能码:占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改数据,所以不同功能码对应不同功能。

  • 数据:根据功能码不同,有不同结构,在下面的实例中有说明。

  • 校验:为了保证数据不错误,增加这个,然后再把前面的数据进行计算看数据是否一致,如果一致,就说明这帧数据是正确的,我再回复;如果不一样,说明你这个数据在传输的时候出了问题,数据不对的,所以就抛弃了。

  • 2、实战

    只谈理论大家可能不太明白,下面举一个例子。Modbus-RTU协议一般我们用的最多功能码就是0306,大部分都是用modbus来查询传感器上的信息用03查询功能码,如果需要修改传感器寄存器的值就用06修改功能码,其他的不需要过多关注,学多了你也记不住,哈哈哈!

    2.1 查询功能码0x03

    功能描述:现在我是主机,我要查询从机地址为01的数据。我现在用电脑的modbus调试助手来代替主机,stm32来代替从机。

    我需要发送以下数据:

  • 主机发送: 01 03 00 00 00 01 84 0A

  • 从机回复: 01 03 02 19 98 B2 7E

  • 编辑
     
  • 01-地址,也就是你传感器的地址

  • 03-功功能码,03代表查询功能,查询传感器的数据

  • 00 00-代表查询的起始寄存器地址.说明从0x0000开始查询。这里需要说明以下,Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据

  • 00 01-代表查询了一个寄存器.结合前面的00 00,意思就是查询从0开始的1个寄存器值

  • 84 0A-循环冗余校验,是modbus的校验公式,从首个字节开始到84前面为止;

  • 编辑
     
  • 01-地址,也就是你传感器的地址

  • 03-功功能码,03代表查询功能,查询传感器的数据。这里要注意的是注意发给从机的功能码是啥,从机就要回复同样的功能码,如果不一样说明这一帧数据有错误

  • 02-代表后面数据的字节数,因为上面说到,一个寄存器有2个字节,所以后面的字节数肯定是2*查询的寄存器个数;

  • 19 98-寄存器的值是19 98,结合发送的数据看出,01这个寄存器的值为19 98

  • B2 7E-循环冗余校验

  • 发送:从机的地址+我要干嘛的功能码+我要查的寄存器的地址+我要查的寄存器地址的个数+校验码

  • 回复:从机的地址+主机发我的功能码+要发送给主机数据的字节数+数据+校验码

  • 主机发送: 01 06 00 00 00 01 48 0A

  • 从机回复: 01 06 00 00 00 01 48 0A

  • 编辑
     
  • 01-主机要查询的从机地址

  • 06-功能码,06代表修改单个寄存器功能,修改有些不同,有修改一个寄存器和修改多个寄存器;

  • 00 00-代表修改的起始寄存器地址.说明从0x0000开始.

  • 00 01-代表修改的值为00 01.结合前面的00 00,意思就是修改0号寄存器值为00 01;

  • 48 0A-循环冗余校验,是modbus的校验公式,从首个字节开始到48前面为止;

  • 编辑
     
  • 01-从机返回给主机自己的地址,说明这就是主机查的从机

  • 06-功能码,代表修改单个寄存器功能,主机发啥功能码,从机就必须回什么功能码;

  • 00 00-代表修改的起始寄存器地址.说明是0x0000.

  • 00 01-代表修改的值为00 01.结合前面的00 00,意思就是修改0号寄存器值为00 01;

  • 48 0A-循环冗余校验,是modbus的校验公式,从首个字节开始到48前面为止;

  • 编辑

    从上面的图中,看出:

    1)比RTU多了起始段:,多个结束符CRLF

    2)地址和功能都变成了2个字节

    3)数据部分更加繁琐,但是更符合人们的查看;

    2.归纳

    由于Modbus-RTU和Modbus-ACSII都是基于232和485链路的,所以其通讯模式半双工,一般是主机和从机的模式。其差别就是其字节的格式不同,一个是16进制的数据,一个是ASCII数据。ASCII多了帧头和帧尾,也就是说可以有用这个头尾判断一帧字节来判断是否结束;而RTU没有帧头和帧尾,所以协议里明确两帧之间要大于3.5个字节时间间隔,作为一帧结束的判断依据。对于RS485来说,总线上一般允许最大32个设备。

    7 备注

    最后再补充点:Modbus从设备的回应数据格式是:1、回应的数据包与主机查询的数据包格式一致。从机正常回应时:功能码与主机发送的功能码一致(1-127) 如果异常回应时:功能码要在收的主机的功能码的基础上加128。不要问为啥加128,你去问造协议的那一帮人吧!

    因为电脑只支持USB,所以我们需要把USB转TTL串口,再转成485接口之后与单片机相连,这是硬件最基本的,但是也需要注意。

    最后修改了一下串口调试助手,加了一个CRC校验的功能。

    如果回复的一样,说明这个数据是修改成功的;如果功能码不是06,而是别的,说明从机回复的数据有误,主机可以做相应的处理。

    2、修改-0x10功能码

    如果我要修改多个寄存器,难道用06发好几次,这样不会太傻了吗?所以Modbus RTU协议包含了修改连续多个寄存器的方法,就是功能码为0x10;这个大家自己去查询,基本和上面的数据格式差不多。

    归纳

    Modbus-RTU协议只需要看懂功能码0x030x060x10这三个基本的就已经足够了,分别回想下其数据域部分:

    0x03—主机需要发送起始地址+寄存器数量,从机回复总字节数+数据

    0x06—主机发送起始地址+数据内容(因为你只需要修改一个,所以起始地址就是所要修改的地址),从机返回起始地址+数据内容(发现居然一样!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值