Modbus-RTU:开放、简单、可靠,有爱,没有恨

已锁定

yanxiao

版主

  • 帖子

    11948
  • 精华

    43
  • 被关注

    154

论坛等级:至圣

注册时间:2003-06-06

钻石 钻石 如何晋级?

Modbus-RTU:开放、简单、可靠,有爱,没有恨

2717

5

2015-03-24 23:27:15

modbus-RTU:开放、简单、可靠,有爱,没有恨

modbus-rtu是我目前了解最透彻的协议。
但是,modbus的接触与入门,也有一段被“逼”的故事,现在想想,要谢谢当年给予我压力的人和事。

我使用S7200在国内应该算是比较早的,但也没见过比现行版的体积大40%的上一代产品,使用的是编程软件也已从MicroDOS进化到MicroWin。经过几个月的学习与偿试,S7200开始应用于本公司自产的空调主机上。那时,空调主机基本自成系统,很少有联网的需求(做中央监控的自己布传感器采集数据),若想要在上位计算机系统中监控主机的状态,也是使用Siemens自家的组态软件如Protool/pro,走的是PPI协议,不需要用户编程。

终于有一个业主在供货技术协议中提出要求,空调主机必须与上位机联网,使用modbus-rtu协议,空调主机为从站。我只听说过modbus,从没用过,甚至没有正儿八经研究过任何一种通讯协议。此时的Microwin还没有指令库可用。在完整版软件的光盘里,有许多应用的例程,叫做S7-200 Tips,其中Tip41就是modbus 例程(现在做成modbus库看不到源程序了),程序是旧版project格式,不是现在的mwp,不能直接打开的,但是附有完整的源程序文档S7241e.doc,工作做得相当到位。此文档现在很难找了,载图和下载到S7200版区找 S7-200 Tips No.41:modbus RTU Slave for S7-200

这例程是基于旧版CPU 21x写的,采用SMB2字符中断接收方式。例程要移值到我的程序里,是要作较大改动的,如果没有弄明白协议本身,直接读程序,我那时的水平,还是行不通的。

好在互联网已经有了,上网搜资料,工具有yahoo和google(百度还没有呢),全球中英文资料都能找,中文资料很少,有也是科普性的,写给明白人看的,不明白的看了还是一头雾水,尤其没有CRC16的计算过程;英文资料中,从modicon网官上下载到PI-MBUS-300.pdf(Modicon modbus Protocol Reference Guide),这个才是真正的好东西,通读两遍后,modbus协议的脉络就理清了,最惊喜的,文档后面附有CRC16的类C语言计算程序,比任何解释文字都要强。

业主的技术协议中没有具体写modbus要传哪些数据,我就自作主张,把本地人机上可以读到的数据、可设定的参数,都放在保持寄存器(holding registers)里,供上位机读取和改写。没有线圈(coils)、触点(contacts)、输入寄存器(input registers)这类数据,所以,仅需要功能3(读保持寄存器)、功能6(写单个保持寄存器)、功能16(写多个保持寄存器)三个功能就行了,程序量约在1K左右。当时的水平很次,写程序信马由缰,224的8K程序空间早就捉襟见肘,若写全例程中的8个功能,估计光是modbus程序就要得占2K以上了。

改写并精简后的modbus-rtu从站程序,放弃了SMB2字符中断接收方式,改用RCV指令,并在SMB/SMW相关的寄存器中设置好帧间隔时间、起始/结束条件,开启相关中断,RCV就可以自动接收了,相比SMB2,程序可以大为简化。

在办公室,用串口调试器把modbus调通,但这个串口调试器没有CRC计算功能(那时也不知道是否有modscan这样的工具),用VB写了一个CRC计算器,调试工作才得以进行。

业主是一家位于海边的热电厂,我们的设备是两套热泵机组,通讯是个附加的功能,设备安装好后,通讯调试要等系统集成商通知。上位系统是honeywell的,我不知道honeywell是否内置modbus,还是由集成商自己写驱动。调试那天,上位系统收不到我们设备的数据!我不管他的系统怎么回事,把通讯线接到我的笔记本,祭起串口调试工具,当场演示:发一帧请求下去,就上来一帧数据,次次成功;然后再用串口调试器监控他的发送请求帧数据,没有任何反应,原来是他的系统没有发出请求数据帧,当然modbus从站不会上传数据,集成商又搞了几个小时,还是不成功,就提出要求:要我们的设备主动上传数据!这就乱了,技术协议明写设备为modbus从站,怎么能主动上传数据。请出承建单位某火电公司仲裁,居然集成商胜出。也是,我们是供应设备的,得听集成商统筹安排,原技术协议可以不算数。

回到办公室开始改程序,发现modbus主站程序比从站简单,尤其只对一个站点,没有多站点的轮询,又是周期性地主动上传数据。你想,周期性地主动上传,就是盲传啊,都不用考虑对方在不在线,有没有正确接收,反正隔几秒就传一次数据,不理会对方的返回信息。所以,程序只要把数据按modbus的格式,填入XMT要求的表中,作CRC16计算,然后定期发XMT指令把数据传出去,就OK了。

再次现场调试,对方的honeywell系统还是收不到数据。这次我就不客气了,直接在他们的电脑中运行串口调试程序,成功收到了设备传来的数据(当然,主动发上来的,只要线路不出问题,怎么会收不到呢)。我向火电建设方解释,数据可以传至他们的电脑,我的任务就完了,至于honeywell是怎么回事,我帮不上忙的。

事情就这么过去了。后来,在空闲的时候,我把modbus程序作了整理,写了完整8个功能的从站程序;又仿NETR/NETW的指令格式,把modbus的主站程序也作了改进,用在与EDA模块(电力参数计量模块)通讯上,运行稳定。

再后来,有了instruction liberary指令库。我把自己的程序打包成库,和siemens的库比较,我的体积小速度快。因为我是用STL写的,而且此时我已比较注重指令的编译效率和运行效率(但源程序的可读性就比较差了)。

现在,modbus-rtu协议在S7200、VB、单机片机上均写过了;通讯介质用过有线、以太网、GPRS无线。我还是很喜欢这个协议的,开放、简单、可靠。我写几条供网友参考:

1、帧间隔
协议规定通讯线上没有信号传送达到3.5个字符时长就认为是帧间隔,它既是前一帧结束的条件,也是下一帧开始的条件,所以发送方延时帧间隔时间后就可以启动新一帧的传输,接收方侦测到帧间隔后就可以启动新一帧的接收。如果设备真的这么着急发送新的数据,对S7200是个挑战。9600bps发送1个字符约1ms,也就是帧间隔仅有3.5ms,S7200最小定时分辨率是1ms,定时误差就去掉1ms,留给S7200处理时间只有2.5ms,即便收发程序全用中断做,也是很难应付的(且不能有别的中断来干扰)。所以,我一般延时10ms之后才启动新数据发送,留给对方足够的处理时间。

2、超时
modbus-ascii协议规定1s的超时时间,而modbus-rtu则没有规定。这个有时不好处理,多久才算超时?
modbus协议很简单,就是一问一答,从站收到主站的请求数据帧,校验无误后,必须及时回应。modbus没有等待这一说,也等不起,因为它是单线程的,一条线路上每次只向一个站点问一个问题,只有这个问题处理结束,才能向下一个站点发东西。
我认为,从站如果在100ms内没有发出第一个字节,就可以断定此从站不再有回应,主站可以开始下一个请求帧的发送。S7200的RCV指令没有给出是否已经在开始接收数据,所以,这个超时时间再加上一帧数据的接收时间。

3、校验
modbus-rtu是CRC16校验,比“和校验”的可靠性高几个数量级。PPI是和校验,也已经很可靠了。所以modbus-rtu是一个很可靠的协议。

4、以太网
以太网的数据包大小可达1.5K字节,而modbus-rtu的数据帧最大不超过一页(256字节),所以modbus数据帧打包为以太网数据包,一个包就装下了,不会被拆分。虚拟串口程序或串口服务器,接收串口数据流,侦测到停顿,就立即把收到的数据打包,通过以太网传出去了,另一端的虚拟串口程序或串口服务器收到数据包后,立即传数据给串口设备,这个时间特性很符合modbus的要求。甚至数据包可以上互联网传输,只是互联网的延时有时很厉害,这个事先考虑进去。
如果自己写以太网的modbus应用程序,网络连接选UDP,比TCP好用。
Modbus-RTU:开放、简单、可靠,有爱,没有恨 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

SIMATIC S7-200

共有33778条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

top
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。