功能實(shí)現(xiàn)背景介紹
本項(xiàng)目中,需要使用STM32的USART6串口與FPGA板(下位機(jī))通信,需要發(fā)送和接收數(shù)據(jù),有報(bào)文應(yīng)答機(jī)制。
使用的報(bào)文規(guī)則如表格所示

板間報(bào)文的通信協(xié)議,校驗(yàn)使用的是和校驗(yàn)
U8 TX_CheckSum(U8 *buf, U8 len) //buf為數(shù)組,len為數(shù)組長(zhǎng)度
{ 
    U8 i, ret = 0;
    for(i=0; i< len; i++)
    {
        ret += *(buf++);
    }
     ret = ~ret;
    return ret;
}
U8 RX_CheckSum(U8 *buf, U8 len) //buf為數(shù)組,len為數(shù)組長(zhǎng)度
{ 
    U8 i, ret = 0;
     for(i=0; i< len; i++)
    {
        ret += *(buf++);
    }
    ret = ret;
    return ret+1;
}
發(fā)送和接收的報(bào)文要滿足不定長(zhǎng)
HAL庫(kù)的中斷接收函數(shù)
如果要直接使用HAL庫(kù)的中斷接收函數(shù),也就是HAL_UART_Receive_IT()函數(shù)
HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);              //下位機(jī)FPGA
在使用時(shí),選擇串口,選擇接收的緩沖區(qū),選擇接收長(zhǎng)度。
/**
  * @brief  Receives an amount of data in non blocking mode.
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
  *         of u16 available through pData.
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
  *               the configuration information for the specified UART module.
  * @param  pData Pointer to data buffer (u8 or u16 data elements).
  * @param  Size  Amount of data elements (u8 or u16) to be received.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  /* Check that a Rx process is not already ongoing */
  if (huart- >RxState == HAL_UART_STATE_READY)
  {
    if ((pData == NULL) || (Size == 0U))
    {
      return HAL_ERROR;
    }
    /* Process Locked */
    __HAL_LOCK(huart);
    huart- >pRxBuffPtr = pData;
    huart- >RxXferSize = Size;
    huart- >RxXferCount = Size;
    huart- >ErrorCode = HAL_UART_ERROR_NONE;
    huart- >RxState = HAL_UART_STATE_BUSY_RX;
    /* Process Unlocked */
    __HAL_UNLOCK(huart);
    /* Enable the UART Parity Error Interrupt */
    __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
    /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
    __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
    /* Enable the UART Data Register not empty Interrupt */
    __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
這個(gè)函數(shù)本質(zhì)上其實(shí)不是中斷接收函數(shù),只是配置函數(shù),配置開(kāi)啟中斷的信息,并且接收多少定長(zhǎng)的數(shù)據(jù)結(jié)束本數(shù)據(jù)接收,串口的中斷接收還是在中斷中進(jìn)行。
我們本次的長(zhǎng)度雖然也是定長(zhǎng),但是有兩種長(zhǎng)度數(shù)據(jù)的接收,所以還是從設(shè)計(jì)接收不定長(zhǎng)的數(shù)據(jù)為最終效果。
狀態(tài)機(jī)的運(yùn)用
對(duì)于不定長(zhǎng)數(shù)據(jù)的接收,使用了狀態(tài)機(jī),分兩次中斷來(lái)接收數(shù)據(jù)

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart- >Instance == USART6)	                                 // 判斷是由哪個(gè)串口觸發(fā)的中斷
	{
		if(StateMachine_USART6)                                      //狀態(tài)機(jī)為1,都接收完畢,準(zhǔn)備校驗(yàn)
		{	
      if(re_flag6 == 1)
			{
				UART6_RxCounter = 6;
				re_flag6 = 0;
			}	
      else
			{
				len_counter6 = 2+5+UART6_RxBuffer[2]+(UART6_RxBuffer[3]< 8);  
			  if(UART6_RxBuffer[len_counter6 - 1] == 0x55 && UART6_RxBuffer[0] == 0xAA)	
			  {
				  UART6_RxCounter = len_counter6;
			  }	
        else
			  {
				  memset(UART6_RxBuffer,0,0x400);
					UART6_RxCounter = 0;
			  }		
			}				
      		
			StateMachine_USART6 = 0;                                   //狀態(tài)機(jī)為0
      len_counter6 = 0;			
			HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);		
		}
		else                                                         //狀態(tài)機(jī)為0,只接受到了前五個(gè)字節(jié),繼續(xù)接收后面的字節(jié)
		{					
			if(UART6_RxBuffer[0] == 0xAA)
			{
				StateMachine_USART6 = 1;
				UART6_RxCounter = 5;
				if(UART6_RxBuffer[2] == 0 && UART6_RxBuffer[3] == 0)
			  {
				  HAL_UART_Receive_IT(&huart6,(uint8_t*)&UART6_RxBuffer[5], 1);
					re_flag6 = 1;
			  }
			  else
			    HAL_UART_Receive_IT(&huart6,(uint8_t*)&UART6_RxBuffer[5], 2 + UART6_RxBuffer[2] + (UART6_RxBuffer[3] < < 8));
			}
			else
			{
				memset(UART6_RxBuffer,0,0x400);
				UART6_RxCounter = 0;
				HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);
			}
			
		}
	}
}
核心思想就是先接收?qǐng)?bào)文的頭,根據(jù)頭來(lái)判斷后面的長(zhǎng)度,把應(yīng)答報(bào)文和音量數(shù)據(jù)報(bào)文區(qū)分開(kāi),不合格的報(bào)文直接舍去同時(shí)開(kāi)啟新的接收。
- 
                                FPGA
                                +關(guān)注
關(guān)注
1652文章
22232瀏覽量
628559 - 
                                STM32
                                +關(guān)注
關(guān)注
2302文章
11108瀏覽量
370278 - 
                                下位機(jī)
                                +關(guān)注
關(guān)注
0文章
96瀏覽量
19393 - 
                                串口中斷
                                +關(guān)注
關(guān)注
0文章
67瀏覽量
14529 - 
                                USART串口
                                +關(guān)注
關(guān)注
0文章
32瀏覽量
7213 
發(fā)布評(píng)論請(qǐng)先 登錄
FreeRTOS串口中斷接收不定長(zhǎng)的數(shù)據(jù)與二值信號(hào)量的使用
    
CW32L083串口中斷+定時(shí)器實(shí)現(xiàn)不定長(zhǎng)數(shù)據(jù)接收
    
stm32串口是如何實(shí)現(xiàn)接收不定長(zhǎng)度數(shù)據(jù)的呢
如何利用串口空閑中斷接收不定長(zhǎng)數(shù)據(jù)
STM32串口接收不定長(zhǎng)數(shù)據(jù)的程序免費(fèi)下載
    
stm32 串口接收不定長(zhǎng)度數(shù)據(jù)及黏包處理 + 串口DMA接收
    
STM32之串口DMA接收不定長(zhǎng)數(shù)據(jù)
    
STM32單片機(jī)串口空閑中斷+DMA接收不定長(zhǎng)數(shù)據(jù)
    
STM32CubeMX之串口接收不定長(zhǎng)數(shù)據(jù)
    
          
        
        
STM32串口中斷接收不定長(zhǎng)報(bào)文介紹
                
 
    
    
           
            
            
                
            
評(píng)論