RS485通信(Modbus)丢包解决经验(基于ARM/Linux和STM32平台)

1. RS485通信属于半双工通信,即发送和接收不能同时进行,需要切换,一般定义一根GPIO做RTS切换。

2. ARM-Linux平台有Linux底层驱动做自动切换,比如应用程序发送完成后,一般会在底层驱动自动切换接收。

3. 但是STM32平台基于UCOS系统,如果发送完数据后,接收切换不及时就会导致接收到的数据不完整,一般是都数据帧前面几个字节。

举例:比如mosbus的链路通信,如果发送数据帧非常短,下位机收到后不需要做过多处理就能回复主机,这个时候由于从机响应过快,即回复数据过快,但是这个时候主机发送完成中断后没有及时切换到RS485的接收状态,那么就会出现上述丢数据问题,特别是一帧数据的头部混乱或丢失。

具体原因是因为从机已经往总线上丢数据,但是主机还未切换接收状态,因此不会接收数据,接收中断不会产生,从而丢数据。当主机切换到接收状态后,主机允许接收数据,并接收到数据后中断产生,但这个时候为时已晚,只能接收到从机部分数据,因为从机已早就开始往总线上丢数据。

解决方案: 基于STM32平台不能做到自动切换,一般需要开启发送完成中断,即发送完,就响应中断函数,然后在中断函数里面马上切换到接收模式,防止从机由于过早回数据,主机还没来得及切换接收模式导致数据丢失的情况。

 但是这样做也有风险,因为主机发送完成后,响应发送中断函数后,也不一定真正发送完成,如果这个时候过早切换到接收模式,有可能导致主机发送数据不完整。所以一般应用都是响应了发送完成中断后,再隔3-5个时钟后切换到接收模式,这样保证了主机发送数据安全性。

如果这个时候主机有接收丢包,那么要求从机适当延时回应,这样才能百分之百保证主从通信稳定。

大部分从机接收到主机数据包后都会经过复杂处理,然后再回应,这样不存在主机接收丢包,但是特殊情况下,主机发送给从机的数据包过于简单,导致从机不需要做过多的处理就可以回应,这种情况就要注意上述讨论的问题。

 

猜你喜欢

转载自blog.csdn.net/fengel_cs/article/details/105855122