微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > freeModbus代码解读及移植笔记

freeModbus代码解读及移植笔记

时间:11-30 来源:互联网 点击:
freeModbus的代码库还是很好用的,本人在wince和C8051F410下均移植成功(只用到RTU模式)。但freeModbus提供的文档比较少,只能对照着Modbus协议一点点试着读懂源代码。下面是阅读代码期间的跟踪笔记:

1、eMBErrorCode为枚举类型变量,代表错误码,共有8个错误代号。常用的是MB_ENOERR,即没有错误。

2、eMBMode枚举类型变量代表设备的工作模式,分别是MB_RTU、MB_ASCII和MB_TCP。

3、eMBEventType枚举类型变量定义了event的类型,分别是EV_READY,代表Startup启动完成;EV_FRAME_RECEIVED代表接收到帧;EV_EXECUTE代表执行功能函数;EV_FRAME_SENT代表帧已发送。

4、eMBParity枚举类型变量代表奇偶校验选项,分别是MB_PAR_NONE无校验,MB_PAR_ODD奇校验,和MB_PAR_EVEN偶校验。

5、mb.c文件中的静态变量ucMBAddress存储设备地址,此变量在eMBInit函数中初始化。

6、在C51Modbus中将freeModbus库中的源码进行了更改,例如尽量不使用函数指针,而是直接调用相关功能函数,根据eMBCurrentMode中的工作模式,来判断调用哪个函数。在freeModbus库中某些函数声明前加上reentrant,这是Keil编译器特有的关键词。这样做带来的一个不足是:不能动态绑定函数,从而导致库代码失去可移植性。这样做是C51编译器与ANSI标准不兼容的特殊性导致的。

7、ENTER_CRITICAL_SECTION()和EXIT_CRITICAL_SECTION()宏,实际上就是关闭和打开全局中断。

8、带xMBPort前缀的函数都属于port layer层,也就是独立于ModBus协议栈。

9、freeModbus库中函数名称的第一个字母表示返回值类型,例如e表示返回enum枚举类型;v表示void无返回值;x表示BOOL布尔类型。注意这条规则并不是总成立,但主要函数基本上还是符合此规则的。第一个字母后的MB代表是属于ModBus协议栈的函数。

10、port.h文件中宏#define F_MCU 定义了单片机的工作频率。需要用其值计算Uart0定时器和Tick定时器的重装入值。

11、在程序主函数main中,使用协议栈的方法是:

eStatus = eMBInit( MB_RTU, 0x0A, 0, 9600, MB_PAR_EVEN );

/* Enable the Modbus Protocol Stack. */

eStatus = eMBEnable( );

for( ;; )

{

( void )eMBPoll( );

……

}

12、在port layer层的xMBPortSerialInit函数中,需要根据传入的波特率、奇偶校验、数据位长度设置来配置Uart0及其使用的定时器。

13、在port layer层的vMBPortSerialEnable函数中配置接收和发送使能,由于在单片机的寄存器SCON0中只有接收使能控制位REN0,而没有发送使能控制位,所以在portserial.c文件中又定义了一个TxEnable变量,用来表示发送的使能状态。若同时关闭接收和发送,则要关闭Uart0中断,即让ES0 = 0。

14、eMBRTUInit函数中的变量usTimerT35_50us代表如果50us进行一次Tick的话,T35超时的Tick次数。这个公式很重要:

usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate );

函数xMBPortTimersInit要以变量usTimerT35_50us为传入参数,对T35超时定时器进行设置。

15、在mbrtu.c文件中定义了两个状态变量,一个是接收状态变量eRcvState,为eMBRcvState枚举类型,有4个状态,在使能ModBus协议栈后赋予STATE_RX_INIT,即初始状态;另一个是发送状态变量eSndState,为eMBSndState枚举类型,有两个状态,初始化为发送idle状态,即STATE_TX_IDLE。

16、mb.c文件中的eMBState状态变量为枚举类型,代表设备的工作状态,有3种状态,分别是“未初始化”、 “使能”和“禁止”状态。调用完eMBInit 函数后要调用eMBEnable函数来使能ModBus协议栈,在其中将eMBState状态变量从“未初始化状态”变为“使能状态”,然后使能串口和打开T35定时器。

17、如果T35定时器超时并产生中断,则要调用xMBRTUTimerT35Expired函数,其内部是一个状态机转换的switch,根据当前接收状态来通过xMBPortEventPost发送事件通知,然后关闭T35定时器,并将当前接收状态设置为STATE_RX_IDLE。

18、eMBException枚举型变量表示Exception的类型,共有10种Exception,在ModBus协议中有定义。

19、在eMBPoll( )中,首先通过xMBPortEventGet函数取event,如果没有则退出,若有event的话便根据event类型进行相应处理。EV_READY是在协议栈初始化后xMBRTUTimerT35Expired函数发出来的,表示startup完成;EV_FRAME_RECEIVED是xMBRTUTimerT35Expired函数在T35超时后发出的,表示已经收到了一帧,需要进行成帧处理,调用eMBRTUReceive函数;EV_EXECUTE是在处理EV_FRAME_RECE

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top