1. 程式人生 > >STM32 HAL庫使用中斷實現串列埠接收不定長資料

STM32 HAL庫使用中斷實現串列埠接收不定長資料

  以前用DMA實現接收不定長資料,DMA的方法接收串列埠助手的資料,全部沒問題,不過如果接收模組返回的資料,而這些資料如果包含回車換行的話就會停止接收,例如接收:AT\r\nOK\r\n,就只能接收到AT\r,導致沒有接收完成,具體原因還沒搞懂,有了解的,希望可以告知一下,DMA不定長接收方法傳輸門:https://www.cnblogs.com/xingboy/p/9714907.html

  好了,不多說了,現在進入正文。首先建立一個STM32Cumebx的工程,開啟串列埠中斷,完成配置,具體的配置流程就不細說了,沒什麼難度就只是開啟串列埠跟中斷而已。

  生成工程程式碼後,先定義好一些變數:

//串列埠4中斷接收定義
#define MAX_RECV_LEN 1024         //設定可以接收的最大位元組
uint8_t msg_buff[MAX_RECV_LEN] = {0}; //接收快取區
uint8_t * msg = msg_buff;    //定義一個指標指向接收快取區
int flag = 0;        //接收完成標誌
int len_u4=0;  //資料長度記錄

  接著重寫串列埠接收回調函式

/*重寫串列埠接收回調函式*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
{
     uint8_t ret 
= HAL_OK; msg++; len_u4++;//資料長度計數 if( msg == msg_buff + MAX_RECV_LEN) { msg = msg_buff; } do { ret = HAL_UART_Receive_IT(UartHandle,(uint8_t *)msg,1); }while(ret != HAL_OK); if(*(msg-1) == '\n') //接收以\n為結尾字元,則表示接收完成 { flag
= 1; } }

  最後在main函式裡面編寫接收後的邏輯,注意要在while(1){ }前開啟串列埠接收中斷

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();

 MX_DMA_Init();

  MX_USART3_UART_Init();

  MX_UART4_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    //自己新增程式碼部分:while前開啟串列埠中斷接收
    HAL_UART_Receive_IT(&huart4, (uint8_t *)msg, 1); //開啟第一次中斷
  while (1)
  {
  /* USER CODE END WHILE *//* USER CODE BEGIN 3 */
//======自己新增程式碼部分=========        
            if (flag == 1)
    {
            printf("msg_buff = %s ;len = %d\r\n",msg_buff,len_u4);
            HAL_UART_Transmit(&huart3,msg_buff, len_u4,100);     //將串列埠4接收到的資料通過串列埠3傳出    
            memset(msg_buff, 0, sizeof(msg_buff));   //清空快取區
           // 指向接收快取的頭部
            msg = msg_buff;
            (&huart4)->pRxBuffPtr = msg;
            flag = 0;
                        len_u4=0;//每次資料長度清0
    }
        HAL_Delay(10);
  }
//==============================
  /* USER CODE END 3 */

}

  執行結果如下,效果正確