早在2008年左右,我就在设计的产品中使用Modbus协议与其它设备进行通信。
记得第一款是智能马达保护器,其作为Modbus从,与Modbus主设备进行通信。
这么多年来,一直都没有使用开源的Modbus协议代码,
而在在不断在自己编写的Modbus协议代码上进行优化,发现问题并解决。
自己写的代码用起来比较得心应用可以针对不同的平台进行优化,将处理器的性能发挥到极致。
在此期间,也踩过一些坑,现在做一些总结:
如上图所示的Td,按照Modbus协议的规定,接收完数据之后,必须要间隔3.5个字符对应的时间才能发送。
如果是9600bps的波特率,8位数据位,1位起始位,1位停止位,无奇偶校验位,则1个字符为10个 bit,对应1.04ms,3.5个字符对应3.5ms。
考虑到总线上的电容对传输延时的影响,建议在发送完数据1.7个字符的时间之后再使能接收。
对于这个时间,可能会犯一些错误,比如:
因此,
Modbus是问答式的通信,主设备发送完数据之后,从设备会做出响应。
按照Modbus协议规定,从设备3.5个字符时间之后做出响应都是合法的。
不同的传感器应答响应时间各不相同。
有些差的传感器可能到几十ms才响应,有些3.5ms左右就立即响应了。
有些甚至没有按照Modbus的协议出牌,还没有到3.5ms左右的时间就响应了。
这就要求主设备在将RS485接收使能之后,立即进行接收状态。
如果是用串口中断进行接收,则应该注意在主程序中是否有关中断的操作,关中断的操作是否影响接收。
Modbus根据数据之间的时间间隔来判断一桢消息的结束,需要保证一桢消息内的前后数据之间的间隔不超过3.5个字符。
而数据一般在发送中断中发送,有些人为了保证数据完整性,保证数据访问的互斥,很喜欢关中断来保护现场。
这种做法一不小心就会使发送两个数据的间隔超过3.5个字符。
特别是当波特率比较高时,更容易出现这种情况。
比如,当波特率为38400时,3.5 个字符仅为850us左右,在发送串口数据的时间内,中断关闭850us,Modbus通信就嗝屁了。
如果MCU支持DMA,建议使用DMA+定时器进行数据收发。
按照Modbus协议要求,3.5个字符之后就可以应答。
有些Modbus主设备可以是为了保证实时性,对这个应答时间要求比较苛刻。
比如我们前一段时间跟西门子的工控屏对接时,就碰到过这样的问题,
总线的波特率为19200bps,我们的设备在收到西门子的命令之后大概在5ms左右做出了应答。
但是西门子工控屏却判为错误。
之后,我们将应答时间缩短到2ms左右,与西门子的通信才变得正常(这个问题接下来还会再深入研究,可能还有其它原因)。
建议在3.5个字符之后,立即应答。
页面更新:2024-03-14
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号