无需关心数据是否接收完毕,只要有数据发过来,都收到自己的缓冲区当中。
在应用层,打开一个任务以定期扫描缓冲区中的新数据。 如果有新数据,确定其是否为必需的协议帧。 通过帧头帧尾标识符还有校验等判断接收帧的正确性,如果正确再处理,不正确丢弃。
Modbus没有固定的帧头标记,长度也没有固定。 判断时,首先查找具有正确地址的字符,然后找出后续功能代码是否正确。 根据功能代码,确定后续数据有多长并进行校验。 如果验证正确,则说明帧是正确的。
扩展资料:
举例说明如下:
从站地址03,从0开始读取10个寄存器,则接收到的帧为03 03 00 00 00 0a xx xx,查找从站地址03的字节,找到后,以下功能码为03,符合功能码范围。
该功能码的数据包括固定为8个字节的校验和,然后在其后没有8个字节时,表示其已被没收,然后在关闭后进行判断。 如果正确,则可以在应用层中正确处理该帧。
我做过modbus规约开发。你说的是驱动程序接收数据这一块,这部分无需关心数据是否接收完毕,只要有数据发过来,都收到自己的缓冲区当中。然后在应用层开启个任务定时扫描缓冲区中的新数据,如果有新数据则判断是否是需要的规约帧,通过帧头帧尾标识符还有校验等判断接收帧的正确性,如果正确再处理,不正确丢弃。
对于modbus没有固定的帧头标记,也没有固定长度。判断的时候先寻找地址正确的字符,找到后在判断后面的功能码是否正确,根据功能码判断后面的数据有多长并进行校验,如果校验也都对了那么这个帧就正确了。
例如从站地址03,读从0开始的寄存器10个,则接收到的帧为 03 03 00 00 00 0a xx xx,你寻找从站地址03的字节,找到后,后面的功能码是03,符合功能码范围。这个功能码的数据包括校验固定为8个字节,那么当后面没有8个字节时表示没收完,退出等收完再判断,收完后计算校验与收到的检验码比较,如果正确,则这帧接收正确进入应用层处理即可。
首先,在RTU方式下,MODBUS协议是根据3.5个字符时间内有没有接收数据来判断是否接受完成。
其次,在ASCII方式下,根据回车换行符来作为接受完成的标志。但是ASCII负载是RTU方式的两倍。
由于MODBUS是连续发生一串字符,一个字符中断一次的方法比较危险,很容易丢包,最好启动FIFO之类的硬件资源。如果是三星ARM,建议你用FIFO+DMA方式。
如果你采用ASCII 模式,以回车换行符作为结束符。如果是RTU模式,则是3.5个字符时间,具体时间跟你的波特率有关,自己算一下。不过,最好留点余量。