Modbus串口通讯协议

物联网现在越来越NB,很多开发者都将物联网与大数据进行一个结合来实现一些适用与未来的应用。在开发的过程之中不可避免需要有一定的分支,在所有的分支中会出现多少多少的模块增加与减少,但是有一个部分是任何物联网系统都不可避免的,那就是底层数据采集。因为在物联网系统之中所有的数据根本上的来源其实都是各个传感器所获得的值,在不考虑硬件提供商已经做好数据协议层的TCP封装情况下那么全世界都会使用同一个通讯协议来完成数据通讯那就是modbus。

在进行协议讲解之前我们先看看什么是串口通讯,在网络化的今天很多应用层开发员无论是哪个平台可能都不会涉及串口通讯的编写,一般来讲估计也就只有一些做底层的,或者是做硬件的高手才会天天面对串口来收发数据。一般来讲串口有两种作用:第一是驱动编写,很多外接的设备基本都是采用串口来进行对硬件的控制,然后再使用其他网络协议进行一个控制SDK的编辑与封装拿给应用层的同学使用,这些设备在我们的日常生活之中都是十分常见的如键盘鼠标U盘等,但是这里我们有一个误区,串口的定义是较大的任何串行数据传输接口算是串口这个定义包含了电脑上的USB接口,COM接口,P/S2接口,SATA接口等等,我们今天所讨论的是一些基本硬件通讯一般来讲都是讲的COM口分为RS232与RS485。第二是硬件通讯,得到硬件的状态,这里我们举一个不太恰当的例子比如说CPU温度数据或者显卡风扇转速等,这一类将数据进行向上传输的东西叫做我们今天把它叫做硬件数据传输。串口出现在以太网以前,当时还没有一个有效的方式让不同硬件进行通讯,那是没有网线这个概念,但是数据或者驱动总需要有当时就延伸出了最早的通讯方式并口,后来由于干扰和空间要求等原因逐渐被串口取代直到今天网络已经普及了但是由于经过一次封装,对底层硬件而言串口的重要性以及不可撼动。

Modbus协议包括RTU、ASCII、TCP。其中MODBUS-RTU最常用,比较简单,在单片机上很容易实现。虽然RTU比较简单,但是看协议资料、手册说得太专业了,起初很多内容都很难理解。
所谓的协议是什么?就是互相之间的约定嘛,如果不让别人知道那就是暗号。现在就来定义一个新的最简单协议。例如,

协议: “A” –“LED灭”
“B” –“报警”
“C” –“LED亮”
单片机接收到“A”控制一个LED灭,单片机接收到“B”控制报警,单片机接收到“A”控制一个LED亮。那么当收到对应的信息就执行相应的动作,这就是协议,很简单吧。

先来简单分析一条MODBUS-RTU报文,例如:01  06  00 01  00 17  98 04
01             06            00 01           00 17          98 04
从机地址        功能号          数据地址          数据         CRC校验

这一串数据的意思是:把数据 0x0017(十进制23) 写入 1号从机地址 0x0001数据地址。

1、报文
一个报文就是一帧数据,一个数据帧就一个报文: 指的是一串完整的指令数据,就像上面的一串数据。

2、CRC校验
意义:例如上面的  98 04  是它前面的数据(01 06 00 01 00 17)通过一算法(见附录2,很简单的)计算出来的结果,其实就像是计算累加和那样。(累加和:就是010600010017加起来的值,然后它的算法就是加法)。
作用:在数据传输过程中可能数据会发生错误,CRC检验检测接收的数据是否正确。比如主机发出01 06 00 01 00 17 98 04,那么从机接收到后要根据01 06 00 01 00 17 再计算CRC校验值,从机判断自己计算出来的CRC校验是否与接收的CRC校验(98 04主机计算的)相等,如果不相等那么说明数据传输有错误这些数据不能要。

3、功能号
意义:modbus 定义。
作用:指示具体的操作。

MODBUS-RTU
一、一个报文分析
先声明下我们的目的,我们是要两个设备通讯,用的是MODBUS协议。上面简单介绍了:“报文”“CRC校验”“功能号”。

在单片机中拿出一部分内存(RAM)进行两个设备通讯,例如:

数组后面的注释,说明
OX[20]   代表是输出线圈,用功能码 0x01,0x05,0x0F 访问, 开头地址是 0 (这个后续说明)
IX[20]    代表是输入线圈,用功能码 0x02 访问,             开头地址是 1 (这个后续说明)
另外两个一样的道理。
注意:所谓的“线圈”“寄存器”就是“位变量”“16位变量”,不要被迷惑。之所以称“线圈”我觉得应该是对于应用的设备,MODBUS协议是专门针对485总线设备(例PLC)开发的。

1、主机对从机写数据操作
如果单片机接收到一个报文那么就对报文进行解析执行相应的处理,如上面报文:
01             06            00 01           00 17          98 04
从机地址        功能号          数据地址          数据         CRC校验

假如本机地址是 1 ,那么单片机接收到这串数据根据数据计算CRC校验判断数据是否正确,如果判断数据无误,则结果是:
HoldDataReg[1]  =  0x0017;
MODBUS主机就完成了一次对从机数据的写操作,实现了通讯。

2、主机对从机读数据操作
主机进行读HoldDataReg[1] 操作,则报文是:
01             03            00 01           00 01          D5 CA
从机地址        功能号          数据地址      读取数据个数       CRC校验
那么单片机接收到这串数据根据数据计算CRC校验判断数据是否正确,如果判断数据无误,则结果是:返回信息给主机,返回的信息也是有格式的:
返回内容:
01         03            02             0017          F8 4A
从机地址   功能号     数据字节个数    两个字节数据    CRC校验
MODBUS主机就完成了一次对从机数据的读操作,实现了通讯。

以上就是一个基础的解释,实际过程使用协议的时候虽然大体的格式是这个样子但是不同的采集卡厂商都有一些魔改,我见过最过分的是北京的一家公司,他们的协议文档上都有很多地方都是错的,通讯方式也改成了TCP,吊的不行。所以还是视具体情况而定。

留下回复