FreeModbus学习——eMBEnable协议栈使能

此函数在mb.c文件中
eMBEnable用于使能协议栈,在初始化函数之后调用
Modbus初始化后,协议栈状态由eMBState由未初始化变成了STATE_DISABLED

eMBErrorCode
eMBEnable( void )
{
    eMBErrorCode    eStatus = MB_ENOERR;

    if( eMBState == STATE_DISABLED )
    {
        /* Activate the protocol stack. */
        pvMBFrameStartCur(  );
        eMBState = STATE_ENABLED;
    }
    else
    {
        eStatus = MB_EILLSTATE;
    }
    return eStatus;
}

先进行协议栈状态判断,若eMBState == STATE_DISABLED即初始化完成了,就激活协议栈。
调用pvMBFrameStartCur( );函数
然后另协议栈状态为STATE_ENABLED使能状态。
(注意eStatus是本函数返回值,为错误码,不要跟协议栈状态混淆)

这个函数是初始化时被赋值的函数pvMBFrameStartCur( );也就是说实际上调用的是eMBRTUStart
在这里插入图片描述
看一下eMBRTUStart这个函数

void
eMBRTUStart( void )
{
    ENTER_CRITICAL_SECTION(  );
    /* Initially the receiver is in the state STATE_RX_INIT. we start
     * the timer and if no character is received within t3.5 we change
     * to STATE_RX_IDLE. This makes sure that we delay startup of the
     * modbus protocol stack until the bus is free.
     */
    eRcvState = STATE_RX_INIT;
    vMBPortSerialEnable( TRUE, FALSE );
    vMBPortTimersEnable(  );

    EXIT_CRITICAL_SECTION(  );
}

这里要先引入两个状态机,接受状态机eMBRcvState和发送状态机eMBSndState。
eMBRcvState有四个状态:初始化,空闲态,接收中,帧无效(错误)
eMBSndState只有两个状态:空闲态,发送态

typedef enum
{
    STATE_RX_INIT,              /*!< Receiver is in initial state. */
    STATE_RX_IDLE,              /*!< Receiver is in idle state. */
    STATE_RX_RCV,               /*!< Frame is beeing received. */
    STATE_RX_ERROR              /*!< If the frame is invalid. */
} eMBRcvState;

typedef enum
{
    STATE_TX_IDLE,              /*!< Transmitter is in idle state. */
    STATE_TX_XMIT               /*!< Transmitter is in transfer state. */
} eMBSndState;

所以RTU开始这个函数eMBRTUStart。

先将接收状态机赋值为初始化状态 eRcvState = STATE_RX_INIT;

然后vMBPortSerialEnable( TRUE, FALSE ); 串口接收使能,发送禁止。

vMBPortSerialEnable这个函数是在portserial.c文件中定义的,要由用户自己实现它。

void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
    /* If xRXEnable enable serial receive interrupts. If xTxENable enable
     * transmitter empty interrupts.
     */
    if (xRxEnable) {
        /*还要设置485为接收模式*/
        __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);//使能接收中断
    } else {
        __HAL_UART_DISABLE_IT(&huart2, UART_IT_RXNE);
    }

    if (xTxEnable) {
        /*还要设置485为发送模式*/
        __HAL_UART_ENABLE_IT(&huart2, UART_IT_TXE);//使能发送中断
    } else {
        __HAL_UART_DISABLE_IT(&huart2, UART_IT_TXE);
    }
}

然后调用vMBPortTimersEnable( );进行定时器使能。此函数要将计数清零,并开启定时器
vMBPortTimersEnable在文件porttimer.c文件中,由用户自己定义

inline void
vMBPortTimersEnable(  )
{
    __HAL_TIM_CLEAR_IT(&htim7,TIM_IT_UPDATE);
    __HAL_TIM_SET_COUNTER(&htim7,0);
    HAL_TIM_Base_Start_IT(&htim7);
    /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
}

在定时器第一次溢出后会将接收状态机的状态由STATE_RX_INIT变为STATE_RX_IDLE。

使能流程:
eMBEnable→
pvMBFrameStartCur→
eMBRTUStart→
接收状态机eRcvState = STATE_RX_INIT→
串口使能vMBPortSerialEnable→
定时器使能vMBPortTimersEnable→
协议栈状态eMBState = STATE_ENABLED;

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值