浅谈-ModBus-发送报文

来源:互联网 发布:剑三脸型数据非法 编辑:程序博客网 时间:2024/06/01 10:12

ModBus协议是什么,用于什么样的现场这些我就不介绍了,大家自行百度。我对协议本身简单的坐一些解释,可能不专业,也有可能有错误,欢迎大家批评指正大笑

Modbus说是一个标准,不如说是一个框架。因为变化太多,不同的厂家有不同的实现方式再加上编程人员的水平层次不齐,会出现各种各样的奇怪情况。所以可能会导致很多人觉得modbus真没意思,枯燥,解析费劲。我就听过另一个公司的技术抱怨,modbus实在费神。

modbus协议本身其实并不难,很简单,一问一答的方式,难得就是其变化后的数据解析问题。想要一个程序吃掉市面上的所有设备,很难,能吃掉百分之七八十就很不错了,实在变态的可以单独写一个程序解决。这里建议大家写modbus程序尽量是可配的,比如,地址功能码等等,这样灵活性高,容易吃掉多数设备。

说这么多,下面开始介绍modbus吧。首先要知道主从关系,你去读一个设备,也就是你发送报文,设备回复给你,然后你解析数据。这里你就是主设备,仪器就是从设备。也就是说主设备的作用是采集,如果倒过来,你回复报文给别人,那么你就是从设备,也就是转发。这里我们默认是采集,也就是我们是主设备。先讲解发送报文,发送报文比较简单,格式固定。格式如下:

地址 功能码 寄存器地址 寄存器个数 CRC校验

地址:从设备的地址,跟寄存器地址不一样,不要弄混,这是一种外在表现,用来区分设备。存在这样两种情况,从设备都不在同一个总线上,每个从设备都在不同的串口,比如A挂在串口1,B挂在串口2,C在串口3......。这时候并不需要可以区分设备地址,ABC的设备地址都相同也没有关系。另一种情况是,ABC都挂在同一个串口,那么这时候就需要区分设备地址了,不然的话,下面设备并不知道你在跟谁通信。这时候就会导致接收的报文混乱。所以这个时候就需要将ABC设置不同的地址,至于地址怎么设置,看看从设备的文档就知道了。设备地址一般为1个字节,当然如果同一个串口下挂在超过256个设备,那么地址就得用两个字节表示了,以此类推。不过这种情况少见,初期写程序可不做考虑。

功能码:字面意思推断这个码是用来区分功能的,比如读取设备的遥信遥测遥脉,一般来说功能码不一样。对于遥信遥测遥脉还有遥控遥调的含义,大家也需要了解。可以自行百度,这里给大家简单叙述一下,遥信,一般用来表示状态的,而且是一个位表示一个状态,一个字节有8位,那么可以表示八路状态,比如说有没有报警啊,温度高不高,风机有没有转等等。遥测,字面意思,测量值,比如测量的电压电流是多少,一般为浮点数。遥脉:测得总工,总电能多少,一般为整数。这里这么区分是因为数值范围的大小,虽然浮点数(单精度)与整数(int)都为32位,但是其实他们表示的范围不一样,浮点数我们知道,32位中有一些位使用了存小数点的,所以导致表示的范围会小一点。对于总工,总电能这些数据,往往都会特别大,所以用整数来表示会更好。当然更大就牵扯到什么无符号类型了,这里不过多解说。按不规范来说,遥脉放在遥脉里读也是可以的,只要不超过范围就行。(扯得有点远了大笑)继续介绍功能码,这里没法定论,哪个功能码是干嘛,网上所总结的也就是一般情况,但是实际上厂家并不管这么多,我是什么功能码你就得按这个读。这是你就得去厂家的设备手册里找了。所以这也是我建议大家按配置来读,这样的话,程序代码不需要改动,直接弄配置就行。一般来说,功能码字节数为1.

寄存器地址,寄存器个数:准确来说,寄存器地址应该是你要读的寄存器起始地址,比如说A设备,电压,电流,有功,无功,分别放在1、2、3、4的地址。如果你一个一个的去读,那么你的报文就会发送四次,假设设备地址为1,功能码为3,那么你的四帧报文就是这样01 03 00 01 00 01 CRC,01 03 00 02 00 01 CRC,01 03 00 03 00 01 CRC,01 03 00 04 00 01 CRC。如果你一次性读取4个寄存器,那么你的报文会是这样01 03 00 01 00 04 CRC.这里读取多个寄存器,要保证寄存器地址的连续性。这里的连续会牵涉到一些可变性,具体跟寄存器的占用字节数有关系。一般来说,从设备寄存器都是2个字节。后续可能大家会遇到4个字节的情况,不必要担心,实质上还是两个字节,只不过是把两个寄存器合在一起了。所以如果是4字节的情况,那么01 03 05 07这样的寄存器地址,也是连续的。到这可能一些人会说这么麻烦,那我还是一帧一帧读算了,而且解析回复报文的时候还简单点,一下读多个,解析报文的时候还复杂点。但是实际情况并不是这样,如果说,从设备寄存器少还好,数据刷新的还算凑合,对于那种寄存器很多的设备,一个一个的读,然后解析数据并显示,这里的延时会让人受不了,所以程序支持连续读,势在必行。寄存器地址,一般来说两个字节,寄存器个数,也是两个字节。

CRC校验:这个无需多说了,就是为了检验你的数据对不对的,提高通信质量。这里的CRC是根据报文计算出来的,并不是固定的,具体方法百度,网上现成的例子算法很多。一般来说这里CRC校验两个字节。

好了发送报文内容大概就是这些,具体细节还是需要大家去仔细研究,比如说一个字节的情况下,还算好点。两个字节的时候就会存在字节高前低后的问题。在这发送报文中,寄存器地址以及个数,两个字节是高前低后,但是CRC检验,2个字节一般是低前高后,当然高前低后也有,这个就得看具体厂家了。好了,下篇会给大家讲解一下接收报文得到解析,这个就会更复杂一点

原创粉丝点击