您的位置:首页 > 科技 > 能源 > FreeModbus学习——eMBEnable协议栈使能

FreeModbus学习——eMBEnable协议栈使能

2024/10/6 4:12:28 来源:https://blog.csdn.net/rerrick_rose/article/details/140641608  浏览:    关键词: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;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com