MODBUS 总结
- 格式:doc
- 大小:2.05 MB
- 文档页数:14
MODBUS总结
这几天终于可以暂时的放松一下,说实话做技术有时真的很累,而有事也很清闲,当项目下来的时候也就是忙碌的开始,当项目验收成功后那种久违的满足兴奋感着实让人舒服、向往。其实做技术也挺有趣我喜欢那种“过关斩将”的感觉。但是技术真的需要不断的充电,因为更新实在太快了干本赶不上当今潮流。做技术一定要抓住技术的实质,这样才能灵活运用,正所谓万变不离其宗。
做MODBUS通讯协议已经有一段时间了,回头看看这段漫长的路其中充满了一次一次的失望又一次有一次的喜悦,感觉很开心。
想当初第一次接触MODBUS时,感觉没有什么难得不就是一个串口通信么?但是自己太过清高了,其实任何一项技术如果要真真正正的掌握不下一番功夫,不经过一次次失败是不可能。
关于MODBUS TCP协议我不做讲解,这个我没有做。至于MODBUS RTU 与MODBUS ASCII协议的格式我也不再多说,这些网上太多了,我只想把我自己遇到的问题以及很多容易忽略的细节做一下阐述(下文主要是从从机的角度考虑):
1 通信速率
如果我们用单片机做MODUS通讯,一定要注意单片机的晶振。很多人不要不在意,这是最为关键的硬件部分,如果晶振不正常或者选型不匹配,那么一切都是扯淡。不怕大家笑话,我在用51单片机做MODUBS RTU通讯实验时,为了查看单片机发送的命令字节,我用八个LED灯作为每个字节的显示,可是我发现单片机只能正确的接收若干个字节的数据,而其他的都是错误的,起初我总怀疑是自己的软件设计有问题,可是改了很多遍也没有解决,很是郁闷啊。可是我相信做技术的都有这样的经历,当你快要放弃的时候突然来了灵感,问题被很干脆的解决。我暂时放系软件去做别的事情,因为高技术最忌钻牛角尖,当遇到困难时要跳出来再跳进去。呵呵,引用我们领到的一句话,感觉说的很对很好。接下来的日子里,偶尔的一天我在焊接硬件电路时,突然眼睛定格在晶振上,一下子我全明白了,原来自己的晶振用错了(原本是11.0592M,自己用成了12M),随即换上问题不复存在。可是你们知道么就这样一个个小小的疏忽将近花费了经耗费了我一个星期的时间。
当然晶振没有问题时并不能保障你能够正确的接收信息,如果你的主从机波特率设置不同那出错也是在所难免的。
2 A B端接反
这也是很多人在不经意的时候犯下的小错误,一般很容易发现,但是不排除马大哈。
3 MODBUS协议属于典型的主从问答式协议,只有在主机发送命令后,从机正确接收后才能响应主机命令,决不能主动上传。
4 编写程序时必须严格的按照MODBUSRTU/ASCII通讯协议的格式发送数据特别要注意CRC/LRC校验码高位在先,低位在后。
5 CRC校验码的的获得常见的有两种方式一是通过查表法,二是计算法。查表法速度更快,但是占用较大内存;计算法速度稍慢但是程序代码简洁。
6 如果我们物理层上走的是232电路,数据的方向无需控制额外控制,但是如果我么采用485电路,那么这时候由于多了一个数据方向控制端口,请务必留意控制信号要和当前的数据流向一致,避免数据冲突。(这也是初学者容易犯错的地方)。
7 还有一个奇怪的现象,比如主机发送功能码03 ,当需要读取的字节很少时,从机很正常的回复,但是当数据超过一定数量后我们会发现出现了通讯超时的现象。后经分析发现是定义的发送缓冲区太小了。在C语言中经常建议我们在定义数组时确定数组的大小,即使不确定数组大小(多维除外)系统也能识别。有些时候我们忽略了数组的大小而去引用数组边界的数组元素(这样说不太恰当)举个例子:
int table[10]={0}; //定义了一个含有10个元素的整型数组
int a1; //定义了一个整型变量a1
a1=table[10]; //对a1赋值
其中对a1赋值这一语句在编译器中是不会报错的,尽管有些时候我们没有发现程序有错误,但是在默写情况下会引起某些不必要变量值的改变,从而引起系统崩溃。
在程序中引用越界数组元素是一个很大的漏洞,会给程序稳定性留下很大
的隐患,而且一般这类问题不易察觉。
8要善于总结规律,细心发现。
比如:在MODBUS RTU协议中主机发送功能码01 02 03 04 05 06时,其发送一帧数据的长度是固定的(8个),即使功能码15 16我们也可以找到规律。这为我们编写程序提供了某些方便。我们可以根据从机接收的字节个数来判断主机命令帧是否结束,因此在网上我们会发现有相当一部分程序中从机是通过该方法判断主机命令帧结束的。但是我建议大家不要这样用,如果应用不好会带来很多麻烦很多问题,接下来我将重点讨论这点。
9 如何判断一帧数据是否接收完毕?
在说明之前我先叙述一下我的经历:原本我是拿着自己编写的程序加载的实验板上和某公司生产的采集模块的MODBUS RTU通讯比较试验效果,我采用的正是依据个数来判断一帧数据结束,我惊奇的发现我的通信灯闪烁的频率远比它的快(通过通信灯可以查看通信速率),这下我高兴坏了,感觉他们编写的程序也不过如此,现在想起来真是好笑,自己太肤浅了。首先人家模块里不单单只是MODBUS通讯一个任务,还有SPI通讯,继电器状态判断等多个任务,而我的程序只有一个任务,根本没有可比性嘛。再者人家是一个成型的产品,性能不好能占领那么大的市场么,哎太大言不惭了,羞愧难当啊!
我在做实验时,主机只连接一个从机模块,效果相当好,正当我满怀信心的向领导汇报时问题来了,来的真打击人。当主机只连接一个模块确实相当给力,没有出现任何错误,领导也确实很满意,但是紧接着领导说,你多给几个模块通讯,看看是不是正常毕竟MOBUS是一主机多从机的通讯模式。
当时的我当然不怕了,很快的连接上两个模块正准备看到那可爱的小精灵闪烁时,等了好久也没有见到,等来的却是触摸屏上显示的”Timeout error”.通讯根本不正常,一点都通不上,当时真是失望到了极点,我苦苦努力地几个月就这样流产了吗,我不甘心。于是开始查找问题,首先从硬件入手,我怀疑是我的485芯片的问题,因为我用一个自己的模块和人家公司生产的模块同主机通讯时,尽管也出现了通讯超时,但是至少偶尔也能成功,于是我把人家的485芯片拆下来换到我的模块上实验,结果又一次让我失望,非常失望,还是一点都通讯不上。当我排出了硬件上可能存在的问题发现效果如初。看来问题不在硬件上,还是软件的问题,可是问题究竟出在哪个地方呢?由于第一次做MODBUS通讯,自己