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_Delay(100); //加延時,保證接收到數據過長的時候,等待數據存入緩存區發送 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 */ }

  運行結果如下,效果正確

  

 

  談談串口RS232跟RS485:這兩個串口除了邏輯電平不同外,還有傳輸距離也不同,如果對速度要求不高,傳輸距離要比較遠的就用RS485比較好,雖然RS485是個半雙工,但是抑制共模干擾能力比較強,不過這些只是對於硬件層面的,對於軟件層面來說他們的本質都是串口,在STM32Cubemx中,都是只是配置為串口,按照串口的編程來處理即可。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM