《FreeModbus笔记.docx》由会员分享,可在线阅读,更多相关《FreeModbus笔记.docx(4页珍藏版)》请在优知文库上搜索。
1、FreeModbus笔记ModbUS-RTU是基于485总线基础上一个主从协议,主站主动发起通信,从站接收主站的消息并响应主站的指令。这里主要探讨FreeModbus中的RTU从站协议的实现。从站的串口每次接收一个字节数据,并产生串口中断(中断打开那么串口中传过来的一个个字节如何组成一个VOdbUS的数据帧呢?这是通过一个重要的参数T3.5来进行推断的。T3.5就是串口传递3.5个字符的时间,这个时间和波特率相关,不同波特率下,T3.5时间不等。3.5个字符时间区分不同的顿,即接收到的两个字符之间时间问隔小于3.5个字符时间时认为是同一个顿的,假如间隔大于3.5个字符时间则认为是不同顿的,在一
2、般的串口通信中,发送I个字符须要:T位起始位,8位数据位,1位校验位(可无),1位停止位,总共1+8+1+1=11位,3.5个字符时间就是3.5*11=38.5位,假如波特率是9600,那么传谕1位的时间是1000/9600=0.10416667(ms),这样,3.5个字符时间就大约是4ms,即定时器须要的中断时间也就是串口在静钛了T3.5秒以后收到的第一个字节作为一个Modbus数据帧的首字节,然后收到的字符间隔只要不超出T3.5的时间间隔,都作为这一帧数据来处理。当串口在T3.5没有收到数据时,则认为当前主站Modbus发送完了一个数据帧。可以进行后面的Modbus数据帧处理了。再收到的数
3、据回作为下一个Modbus数据帧的首字节。接收一个字节,是由串口中断来进行完成的,推断是否超时是由定时器中断来完成的。因此以上看是很清晰的一个协议流程须要串口和定时器协作共同完成。所以在看RTU实现协议时肯定要记住这点。从站主要是接收,被动响应,所以先分析接收机的状态:接收状态机接收状态包含以下几种:STATE_RX_INIT,/*!接收机在初始态*/STATE_RXD1.E,/*!接收机在空闲态*/STATE_RX_RCV,/*!接收到一帧数据*/STATERXERROR/*!错误数据帧*/状态机转换图:状态机的转换不是由一个函数来确定的,是由多个函数共同作用的结果。主要要T3.5的定时中断
4、和串口的接收中断。所以在程序一起先要对串口和定时器进行正确的设置。当时始化完毕后,接收状态机初始态是STATE_RX_INIT,同时T3.5定时器启动。假如在T3.5定时到来之前,串口收到了一个字节,则认为是还没打算好的状况下,总线发起的一次ModbUS传输,此时这帧数据是不处理的,所以,要等到这一帧数据传送完(T3.5超时)。当发生T3.5超时事务时,说明总线上的数据帧已经传完,处于空闲状态,为发起下一帧数据传输做好了打算。所以接收状态机转换为STATE_RX_ID1.E,同时发送一个EV_READY事务,告知Modbus以及打算好接收数据了。同时关闭T3.5定时。在STATE_RXD1.E
5、状态下,只会接收串口数据来触发状态转换(定时被关闭)。当接收到一个字节时,认为总线起先了一个新的数据帧的传输,把这个字节保存在ModbUS数据缓冲区,并将缓冲区指针加1,并将接收状态机转换为STATE_RX_RCV0在STATE凌_RCV状态下,接收到一个新字节,将该字节保存在缓冲区,并将缓冲区指针加1,推断接收的字节总长是否最大帧长,假如不大于,接着保持STATE_RX_RCV状态,等待接收下一个字节或超时(接收完成当大于最大帧长,说明接收到了错误帧。状态转到STATE_RX_ERROR.在STATE_RX_RCV状态下,产生了一个T3.5超时,此时认为总线已经发送完成一个Modbus数据帧
6、,将状态转换到STATE_RXD1.E,等待下一个数据帧到来。同时触发EV_FRAME_RECEIVED事务,告知ModbusPol1已经胜利接收一帧数据,可以解析并处理了。在STATE_RXRROR状态下,接收到再多的字节都认为是错误的,所以始终停留在借误态,直到来了一个T3.5超时事务,此时认为总线上错误的数据帧发送完毕,总线静默,为下一个数据帧打算好!接收状态机转换为STATE_RX_ID1.EOModbus的初始化流程:以下是FreeModbus的各个功能函数解析:1、/初始化Modbus协,议eMBInit(MB_RTU,Slave_Adress,0,115200,MB_PAR_NONE):CMBRTUInit(UCHARUcSlaveAddress,UCHARucPort,U1.ONGUlBaudRate,eMBParityeParity)至此,Modbus的初始化工作完成。串口中断被打开,超时定时器配置好。CMBEnable()当串口接收到数据时发生中断,由串口中断程序处理USART1.IRQHandlerOModbus的主查询函数eMBPol1O