FreeModbus开源协议栈-mb.c

目录

mb.c

函数定义

定时器配置 

代码分析

头文件定义

变量定义

eMBInit函数初始化

eMBTCPInit函数初始化

注册函数

eMBClose协议栈关闭函数

协议栈eMBEnable使能/eMBDisable失能

事件轮询函数(需周期调用)


mb.c

该文件不需要作出修改,但需要调用该文件函数。

函数定义

eMBErrorCode eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity, eMBStopBit eStopBit, eMBDataBit eDataBit );
eMBErrorCode eMBTCPInit( USHORT ucTCPPort );
eMBErrorCode eMBRegisterCB( UCHAR ucFunctionCode, pxMBFunctionHandler pxHandler );
eMBErrorCode eMBClose( void );
eMBErrorCode eMBEnable( void );
eMBErrorCode eMBDisable( void );
eMBErrorCode eMBPoll( void );

定时器配置 

在CubeMX工程配置中,已经将定时器2(TIM2)的时钟周期设为50us,usTimerT35_50us(产生中断)暂时设为了35,也就是说50us×35=1750us产生一次中断,这个时间就是判断RTU中帧间隔的标准。但在Freemodbus协议栈(遵循Modbus国标)中,这个时间不是固定的,在波特率小于19200bps时,需要具体计算这个时间,当波特率大于或等于19200bps时,这个时间固定为1750us。

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

代码分析

头文件定义

变量定义

定义了modbus模式、modbus状态、和一些函数指针以及功能码处理结构体。

eMBInit函数初始化

主体调用了eMBRTUInit函数,存在于mbrtu.c文件中,后续在portserial.c中对串口进行处理。

流程为:参数从地址判断--赋值modbus从地址--选择modbus模式绑定功能函数--modbus初始化--建立事件组--赋值modbus模式和状态(未使能)。

举例如何使用该函数:

uint8_t mode;	// 1--网络模式,0--串口模式
void Modbus_SerialPort_Init(void)
{  
    mode = 0;
    
    eMBDisable();
    eMBClose();
    
    if(mode)
        eMBTCPInit( MB_TCP_PORT_USE_DEFAULT );
    else
        eMBInit( MB_RTU, 0x01, 0,9600, 0);
    
    eMBEnable();
}

eMBTCPInit函数初始化

主体调用了eMBTCPDoInit函数,存在于mbtcp.c文件中,后续在porttcp.c中对网口(如W5500)进行处理。

流程为:modbus tcp模式初始化--建立事件组(存在则忽略操作)--选择modbus tcp模式绑定功能函数 --赋值modbus地址(255)、模式和状态(未使能)。

注册函数

这个函数功能感觉很鸡肋,没什么用。我的工程中没用上这个函数。 

eMBClose协议栈关闭函数

需要先失能再关闭。实际上就是调用portserial.c文件的vMBPortClose()函数。

协议栈eMBEnable使能/eMBDisable失能

实际上就是调用了mbrtu.c文件的eMBRTUStart函数和eMBRTUStop函数,并修改相关modbus状态。

事件轮询函数(需周期调用)

若事件为EV_READY,则跳出,等待下一次查询;

若事件为EV_FRAME_RECEIVED,则调用mbrtu.c文件的eMBRTUReceive来完成帧信息的提取(从地址、帧指向功能码、长度),并向系统发送EV_EXECUTE事件;

若事件为EV_EXECUTE,则调用对应功能码处理函数。完成处理后,如果处理结果不正确,会填充响应的错误码(0x80|功能码 错误值)。最后通过调用mbrtu.c文件的eMBRTUSend函数完成回复帧的发送;若事件为EV_FRAME_SENT,则跳出,等待下一次查询。

如何使用该函数:

/**
  * @brief  通信任务循环入口
  * @note   None
  * @param  argument : NULL
  * @retval None
  */
void StartCommTask(void *argument)
{
    for(;;)
    {
        ( void )eMBPoll(  );
    }
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值