您的位置 首页 芯闻

freeModbus代码解读及移植笔记

freeModbus的代码库还是很好用的,本人在wince和C8051F410下均移植成功(只用到RTU模式)。但freeModbus提供的文档比较少,只能对照着Modbu

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_RECEIVED过程中最终一步,假如此帧的地址契合本机地址,则宣布EV_EXECUTE事情,进行应用层的处理。

  20、在eMBRTUReceive函数中首要检查帧巨细是否契合要求,然后进行CRC校验。此函数的原型是:

  eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )

  榜首个参数是为了回来帧中的地址,也便是帧中榜首个字节;第二个传入的参数今后要作为数组来运用,所以用了指针的指针类型;第三个参数表明PDU的长度,也便是帧中除掉地址字节和CRC校验字节后的长度。

  21、在eMBPoll( )中处理EV_EXECUTE事情,首要从PDU中提取出FunctionCode,然后依据FunctionCode找到相应的处理函数。xMBFunctionHandler结构体类型变量xFuncHandlers中界说了各个FunctionCode对应的处理函数pxHandler,函数的榜首个参数ucMBFrame是PDU的存储地址,第二个参数usLength回来PDU的长度。假如帧不是一个播送帧,则需求设备宣布一个回复,假如前面有过错产生,则要回复一个过错报告帧。

  22、在Keil中程序需求运用大形式编译,不然会呈现error c249: data: segment too large的过错。

  23、若运用波特率为9600,则 t3.5= ( 11 * 3.5 ) / 9600 = 4.01 ms。 不能运用8位形式的Timer,由于11.0590MHz主频在最大48分频后,最长的超时时刻为1.11ms,不能满意T35的超时要求。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/xinwen/318102.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部