文档介绍:Modbus 通讯协议及 C51 程序 Modbus 通讯协议 Modbus 协议最初由 Modicon 公司开发出来,在 1979 年末该公司成为施耐德自动化(Schneider Automation) 部门的一部分,现在 Modbu s 已经是工业领域全球最流行的协议。此协议支持传统的 RS-232 、 RS-422 、 RS-485 和以太网设备。许多工业设备,包括 PLC , DCS ,智能仪表等都在使用 Modbus 协议作为他们之间的通讯标准。有了它, 不同厂商生产的控制设备可以连成工业网络,进行集中监控。当在网络上通信时, Modbus 协议决定了每个控制器须要知道它们的设备地址, 识别按地址发来的消息, 决定要产生何种行动。如果需要回应,控制器将生成应答并使用 Modbus 协议发送给询问方。 Modbus 协议包括 ASCII 、 RTU 、 TCP 等,并没有规定物理层。此协议定义了控制器能够认识和使用的消息结构, 而不管它们是经过何种网络进行通信的。标准的 Modicon 控制器使用 RS232C 实现串行的 Modbus 。 Modbus 的 ASCII 、 RTU 协议规定了消息、数据的结构、命令和就答的方式,数据通讯采用 Maser/Slave 方式, Master 端发出数据请求消息, Slave 端接收到正确消息后就可以发送数据到 Maste r 端以响应请求; Master 端也可以直接发消息修改 Slave 端的数据, 实现双向读写。 Modbus 协议需要对数据进行校验,串行协议中除有奇偶校验外, ASCII 模式采用 LRC 校验, RTU 模式采用 16位 CRC 校验,但 TCP 模式没有额外规定校验, 因为 TCP 协议是一个面向连接的可靠协议。另外, Modbus 采用主从方式定时收发数据,在实际使用中如果某 Slave 站点断开后(如故障或关机), Master 端可以诊断出来,而当故障修复后,网络又可自动接通。因此, Modbus 协议的可靠性较好。下面我来简单的给大家介绍一下, 对于 Modbus 的 ASCII 、 RTU 和 TCP 协议来说, 其中 TCP 和 RTU 协议非常类似, 我们只要把 RTU 协议的两个字节的校验码去掉, 然后在 RTU 协议的开始加上 5个0 和一个 6并通过 TCP/IP 网络协议发送出去即可。所以在这里我仅介绍一下 Modbus 的 ASCII 和 RTU 协议。下表是 ASCII 协议和 RTU 协议进行的比较: 协议开始标记结束标记校验传输效率程序处理 ASCII : (冒号) CR,LF LRC 低直观,简单,易调试 RTU 无无 CRC 高不直观,稍复杂通过比较可以看到, ASCI I 协议和 RTU 协议相比拥有开始和结束标记, 因此在进行程序处理时能更加方便,而且由于传输的都是可见的 ASCII 字符, 所以进行调试时就更加的直观, 另外它的 LRC 校验也比较容易。但是因为它传输的都是可见的 ASCII 字符, RTU 传输的数据每一个字节 ASCII 都要用两个字节来传输, 比如 RTU 传输一个十六进制数 0xF9,ASCII 就需要传输’F ’’ 9’的 ASCII 码 0x39 和 0x46 两个字节, 这样它的传输的效率就比较低。所以一般来说, 如果所需要传输的数据量较小可以考虑使用 ASCII 协议, 如果所需传输的数据量比较大,最好能使用 RTU 协议。下面对两种协议的校验进行一下介绍。 1、 LRC 校验 LRC 域是一个包含一个 8 位二进制值的字节。 LRC 值由传输设备来计算并放到消息帧中, 接收设备在接收消息的过程中计算 LRC , 并将它和接收到消息中 LRC 域中的值比较,如果两值不等,说明有错误。 LRC 校验比较简单, 它在 ASCII 协议中使用, 检测了消息域中除开始的冒号及结束的回车换行号外的内容。它仅仅是把每一个需要传输的数据按字节叠加后取反加 1 即可。下面是它的 VC 代码: BYTE GetCheckCode(const char * pSendBuf, int nEnd)// 获得校验码{ BYTE byLrc = 0; char pBuf[4]; int nData = 0; for(i=1; i<end; i+=2) //i 初始为 1 ,避开“开始标记”冒号{ // 每两个需要发送的 ASCII 码转化为一个十六进制数 pBuf [0] = pSendBuf ; pBuf [1] = pSendBuf [i+1]; pBuf [2] = '\0'; sscanf(pBuf,"%x",& nData); byLrc += nData; } byLrc =~ byLrc;