这次主要讲解从机数据的接收流程。接收流程分为两个阶段:串口中断接收和数据解析。第一阶段为中断接收函数prvvUARTRxISR(xMBRTUReceiveFSM)和定时器中断回调函数xMBRTUTimerT35Expired(),第二阶段为数据解析eMBPoll( )。
一、串口中断接收
从机正常状态下,串口设置为接收中断模式,也不启动定时器。当检测到有数据时,中断函数调用xMBRTUReceiveFSM()函数,通过该函数中的ucRTUBuf数组存储接收帧,用usRcvBufferPos存储数据帧长度。具体函数:
1、中断接收函数。
void UART1_IRQ(void)
{if(USART_GetITStatus(USART1,USART_IT_TXE))
{
pxMBFrameCBTransmitterEmpty( );
}
else if(USART_GetITStatus(USART1,USART_IT_RXNE))//接收中断
{
pxMBFrameCBByteReceived( );//pxMBFrameCBByteReceived = xMBRTUReceiveFSM;
}
}
2、xMBRTUReceiveFSM()函数。只要进人该函数,就会启动定时器中断。从机的接收状态:STATE_RX_INIT(协议栈初始化)、STATE_RX_ERROR(接受错误)、STATE_RX_IDLE(接收空闲,接收帧头,常用)、STATE_RX_RCV(接收所有数据,常用)。注意:接收数据时,只要接收到数据,定时器就会清零,重新计数。
BOOL
xMBRTUReceiveFSM( void )
{
BOOL xTaskNeedSwitch = FALSE;
UCHAR ucByte;assert( eSndState == STATE_TX_IDLE );
/* Always read the character. */
( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );switch ( eRcvState )
{
/* If we have received a character in the init state we have to
* wait until the frame is finished.
*/
case STATE_RX_INIT:
vMBPortTimersEnable( );
break;/* In the error state we wait until all characters in the
* damaged frame are transmitted.
*/
case STATE_RX_ERROR:
vMBPortTimersEnable( );
break;/* In the idle state we wait for a new character. If a character
* is received the t1.5 and t3.5 timers are started and the
* receiver is in the state STATE_RX_RECEIVCE.
*/
case STATE_RX_IDLE:
usRcvBufferPos = 0;
ucRTUBuf[usRcvBufferPos++] = ucByte;
eRcvState = STATE_RX_RCV;/* Enable t3.5 timers. */
vMBPortTimersEnable( );
break;/* We