0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32串口中斷接收不定長報文介紹

冬至子 ? 來源:一養(yǎng)喵子的 ? 作者:手辰 ? 2023-10-26 11:01 ? 次閱讀

功能實現(xiàn)背景介紹

本項目中,需要使用STM32的USART6串口與FPGA板(下位機)通信,需要發(fā)送和接收數(shù)據(jù),有報文應(yīng)答機制。

使用的報文規(guī)則如表格所示

圖片

板間報文的通信協(xié)議,校驗使用的是和校驗

U8 TX_CheckSum(U8 *buf, U8 len) //buf為數(shù)組,len為數(shù)組長度
{ 
    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ù)組長度
{ 
    U8 i, ret = 0;
     for(i=0; i< len; i++)
    {
        ret += *(buf++);
    }
    ret = ret;
    return ret+1;
}

發(fā)送和接收的報文要滿足不定長

HAL庫的中斷接收函數(shù)

如果要直接使用HAL庫的中斷接收函數(shù),也就是HAL_UART_Receive_IT()函數(shù)

HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);              //下位機FPGA

在使用時,選擇串口,選擇接收的緩沖區(qū),選擇接收長度。

/**
  * @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;
  }
}

這個函數(shù)本質(zhì)上其實不是中斷接收函數(shù),只是配置函數(shù),配置開啟中斷的信息,并且接收多少定長的數(shù)據(jù)結(jié)束本數(shù)據(jù)接收,串口的中斷接收還是在中斷中進行。

我們本次的長度雖然也是定長,但是有兩種長度數(shù)據(jù)的接收,所以還是從設(shè)計接收不定長的數(shù)據(jù)為最終效果。

狀態(tài)機的運用

對于不定長數(shù)據(jù)的接收,使用了狀態(tài)機,分兩次中斷來接收數(shù)據(jù)

圖片

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart- >Instance == USART6)	                                 // 判斷是由哪個串口觸發(fā)的中斷
	{
		if(StateMachine_USART6)                                      //狀態(tài)機為1,都接收完畢,準備校驗
		{	
      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)機為0
      len_counter6 = 0;			
			HAL_UART_Receive_IT(&huart6,UART6_RxBuffer,5);		
		}
		else                                                         //狀態(tài)機為0,只接受到了前五個字節(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);
			}
			
		}
	}
}

核心思想就是先接收報文的頭,根據(jù)頭來判斷后面的長度,把應(yīng)答報文和音量數(shù)據(jù)報文區(qū)分開,不合格的報文直接舍去同時開啟新的接收。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1624

    文章

    21538

    瀏覽量

    600458
  • STM32
    +關(guān)注

    關(guān)注

    2262

    文章

    10846

    瀏覽量

    353676
  • 下位機
    +關(guān)注

    關(guān)注

    0

    文章

    93

    瀏覽量

    18707
  • 串口中斷
    +關(guān)注

    關(guān)注

    0

    文章

    64

    瀏覽量

    13824
  • USART串口
    +關(guān)注

    關(guān)注

    0

    文章

    32

    瀏覽量

    6791
收藏 人收藏

    評論

    相關(guān)推薦

    FreeRTOS串口中斷接收不定長的數(shù)據(jù)與二值信號量的使用

    FreeRTOS例程,使用串口中斷接收不定長的數(shù)據(jù),以及二值信號量的使用
    的頭像 發(fā)表于 09-26 09:02 ?3859次閱讀
    FreeRTOS<b class='flag-5'>串口中斷</b><b class='flag-5'>接收</b><b class='flag-5'>不定長</b>的數(shù)據(jù)與二值信號量的使用

    CW32L083串口中斷+定時器實現(xiàn)不定長數(shù)據(jù)接收

    CW32L083 用串口中斷加定時器中斷實現(xiàn)串口不定長數(shù)據(jù)的接收,特別適用于AT指令的接收。
    的頭像 發(fā)表于 07-12 09:00 ?1768次閱讀
    CW32L083<b class='flag-5'>串口中斷</b>+定時器實現(xiàn)<b class='flag-5'>不定長</b>數(shù)據(jù)<b class='flag-5'>接收</b>

    stm32串口是如何實現(xiàn)接收不定長度數(shù)據(jù)的呢

    stm32串口是如何實現(xiàn)接收不定長度數(shù)據(jù)的呢?串口接收數(shù)據(jù)一般會采用
    發(fā)表于 08-11 08:18

    STM32F103串口中斷是如何去接收不定長字符

    STM32F103串口中斷是如何去接收不定長字符的?有什么方法嗎?
    發(fā)表于 12-08 07:40

    接收STM32串口中斷+DMA不定長字符的方法是什么

    接收STM32中斷+DMA不定長字符的方法是什么
    發(fā)表于 12-09 07:52

    如何利用串口空閑中斷接收不定長數(shù)據(jù)

    在上一篇文章STM32單片機串口空閑中斷接收不定長數(shù)據(jù)中介紹了利用
    發(fā)表于 02-22 07:34

    STM32串口中斷 DMA接收的幾點注意地方

    STM32串口中斷、DMA接收的幾點注意地方
    的頭像 發(fā)表于 03-04 13:57 ?2.1w次閱讀

    STM32串口接收不定長數(shù)據(jù)的程序免費下載

    本文檔的主要內(nèi)容詳細介紹的是STM32串口接收不定長數(shù)據(jù)的程序免費下載。
    發(fā)表于 08-26 08:00 ?62次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數(shù)據(jù)的程序免費下載

    stm32 串口接收不定長度數(shù)據(jù)及黏包處理 + 串口DMA接收

    ,那么stm32串口是如何實現(xiàn)接收不定長度數(shù)據(jù)的呢? 串口接收數(shù)據(jù)一般會采用
    發(fā)表于 12-23 19:09 ?27次下載
    <b class='flag-5'>stm32</b> <b class='flag-5'>串口</b><b class='flag-5'>接收</b><b class='flag-5'>不定長</b>度數(shù)據(jù)及黏包處理 + <b class='flag-5'>串口</b>DMA<b class='flag-5'>接收</b>

    STM32 DMA串口接收不定長數(shù)據(jù)

    STM32 DMA串口接收不定長數(shù)據(jù)
    發(fā)表于 12-24 18:50 ?40次下載
    <b class='flag-5'>STM32</b>  DMA<b class='flag-5'>串口</b><b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數(shù)據(jù)

    STM32串口DMA接收不定長數(shù)據(jù)

    使用stm32或者其他單片機的時候,會經(jīng)常使用到串口通訊,那么如何有效地接收數(shù)據(jù)呢?假如這段數(shù)據(jù)是不定長的有如何高效接收呢?同學(xué)A:數(shù)據(jù)來了
    發(fā)表于 12-24 19:03 ?30次下載
    <b class='flag-5'>STM32</b>之<b class='flag-5'>串口</b>DMA<b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數(shù)據(jù)

    STM32單片機串口空閑中斷+DMA接收不定長數(shù)據(jù)

    在上一篇文章STM32單片機串口空閑中斷接收不定長數(shù)據(jù)中介紹了利用
    發(fā)表于 12-27 19:24 ?18次下載
    <b class='flag-5'>STM32</b>單片機<b class='flag-5'>串口</b>空閑<b class='flag-5'>中斷</b>+DMA<b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數(shù)據(jù)

    STM32串口中斷應(yīng)用實例

    本文將介紹如何使用STM32F4的串口接收中斷,通過串口助手模擬上位機發(fā)送指令、
    的頭像 發(fā)表于 04-20 11:45 ?2213次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>串口中斷</b>應(yīng)用實例

    STM32CubeMX之串口接收不定長數(shù)據(jù)

    基本串口通信通常只能接收定長數(shù)據(jù),無法穩(wěn)定接收不定長數(shù)據(jù),本章介紹利用
    的頭像 發(fā)表于 05-11 09:59 ?3109次閱讀
    <b class='flag-5'>STM32</b>CubeMX之<b class='flag-5'>串口</b><b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數(shù)據(jù)

    STM32串口中斷及DMA接收常見的幾個問題

    STM32串口中斷及DMA接收常見的幾個問題
    的頭像 發(fā)表于 10-26 16:41 ?3274次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>串口中斷</b>及DMA<b class='flag-5'>接收</b>常見的幾個問題