RM新时代网站-首页

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

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

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

STM32 HAL庫串口收發(fā)如何使用

科技綠洲 ? 來源:矜辰所致 ? 作者:矜辰所致 ? 2023-06-22 10:38 ? 次閱讀
  • 前言
  • 一、 HAL 庫串口收發(fā)
    • 1.1 串口發(fā)送
    • 1.2 串口接收
  • 二、 收發(fā)同時串口卡死?
    • 2.1 問題說明
    • 2.2 嘗試的處理方式
  • 結語

前言

對于 STM32 串口的使用,確實很簡單使用 STM32CubeMX 做好初始化,就可以直接使用了。

但是最近在某些產(chǎn)品上使用串口同時收發(fā)的時候,發(fā)現(xiàn)有時候串口會收不到數(shù)據(jù)了,但是發(fā)送正常,而且這個問題再數(shù)據(jù)量大的時候很容易出現(xiàn),于是乎進行了好幾天的問題測試……

一、 HAL 庫串口收發(fā)

先簡單回顧一下 STM32 HAL庫串口收發(fā)是如何使用的。

1.1 串口發(fā)送

對于 STM32 來說,串口發(fā)送有3中方式:

  1. 輪詢發(fā)送;
  2. 中斷發(fā)送;
  3. DMA發(fā)送;

在實際產(chǎn)品上,大部分項目中都用的是 輪詢 方式發(fā)送,本次出現(xiàn)接收卡死的問題的產(chǎn)品也是采用的輪詢發(fā)送,所以我簡單的說明一下輪詢發(fā)送,其他兩種方式為 STM32 學習的基礎問題,這里就不過多討論。

發(fā)送相對簡單,在 HAL 庫實際都是使用HAL_UART_Transmit函數(shù):

圖片

在這里插入圖片描述

不管是哪個串口發(fā)送,都做了個簡單的發(fā)送函數(shù):

圖片

在這里插入圖片描述

發(fā)送沒什么好說的,簡單易用。

1.2 串口接收

和串口發(fā)送一樣,串口接收有3中方式:

  1. 輪詢接收;
  2. 中斷接收;
  3. DMA接收;

在我們正常的項目使用中,一般都是 中斷接收 或者 DMA 接收,基本上不會使用 輪詢接收的方式。

那么對于本次出問題的產(chǎn)品,我采用的是 中斷接收的方式。

但是相比較發(fā)送,在 HAL 庫中 使用中斷接收的方式就有點 “五花八門” 的感覺。

1.2.1 標準庫接收

在標準庫的時候,我們經(jīng)常這么用,在串口初始化的時候使用下面的語句使能中斷:

//在串口初始化代碼之后加上中斷使能
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);

如果需要自動判斷一幀數(shù)據(jù),我們再開啟一下 IDLE 中斷:

USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);

然后在對應的中斷處理函數(shù)中,直接讀取 DR 寄存器(STM32F103 而言為 DR,STM32L051 為RDR),然后當 IDLE 中斷產(chǎn)生,也可以處理一下標志位:

//自己用的,用到了 USART_IT_IDLE 標志位,有時候不合適
void USART3_IRQHandler(void)                 //串口3中斷服務程序
{
 u8 clear3=clear3;    //消除編譯器沒有用到的提醒
 // u8  Res;

 if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  
  {
   USART_Enocean_BUF[Enocean_Data++] = USART3- >DR;
   USART3_RX_BUF[USART3_Data++] = USART_ReceiveData(USART3);
   // Res= USART_ReceiveData(USART3);
   // USART_SendData(USART1,Res);while(!(USART1- >SR&USART_FLAG_TXE)); 
  }

    else if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)    
    {
   clear3=USART3- >SR; //讀SR寄存器 可以清空寄存器
   clear3=USART3- >DR; //讀DR寄存器(先讀SR寄存器,再讀DR,為了清除IDLE中斷)      
   USART3_RX_STA=1;   //標記接收到了一幀數(shù)據(jù)
   //USART3_Data=0;
    }               //enocean是不是讀不到一幀數(shù)據(jù),不用一幀數(shù)據(jù)測試一下  
}

1.2.1 HAL庫接收

HAL庫接收方式一

在 HAL 庫函數(shù)接收的時候,其實也可以使用標準庫上一樣的中斷標志使能:

MX_LPUART1_UART_Init();
__HAL_UART_ENABLE_IT(&hlpuart1,UART_IT_RXNE);

IDLE 中斷使能:

__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);

這種方式的處理方式,可以和標準庫差不多。

在 HAL 庫中,外設的中斷的入口函數(shù)都放在stm32l0xx_it.c 這個文件夾中( 以STM32L051 為例),在這個文件中可以找到和標準庫一樣的 中斷入口函數(shù),我們可以進行如下處理:

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
  if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_RXNE) == SET){
      //  USART_Enocean_BUF[Enocean_Data++] = huart2.Instance- >RDR    
      //  RXNE 數(shù)據(jù)處理,直接讀取數(shù)據(jù)      
  }
  if((__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE) != RESET))
  {
     __HAL_UART_CLEAR_IT(&huart2,UART_CLEAR_IDLEF); //??3y?D??  
     // ReceiveState = 1;
     // IDLE 數(shù)據(jù)處理,一幀數(shù)據(jù)接收標志位置位
  }
}
HAL庫接收方式二

但是在于 HAL 中,還有一種比較常用的開啟中斷方法,不是直接使能中斷,而是通過調(diào)用 HAL 庫函數(shù) HAL_UART_Receive_IT

圖片

在這里插入圖片描述

一般的使用方式步驟:

圖片

在這里插入圖片描述

對于本次需要說明的問題,就是使用了 HAL_UART_Receive_IT 函數(shù)導致的,下文我們會說明,這里列出了基本的使用步驟。

二、 收發(fā)同時串口卡死?

2.1 問題說明

最近測試部反饋,產(chǎn)品有些時候的下行沒反應,這里所說的下行,其實就是串口接收。

霹靂扒拉一大堆多余的省略 ... ... 只說幾個重點:

出問題的最后現(xiàn)象就是串口發(fā)送正常,但是永遠接收不到數(shù)據(jù)了,其他程序正常運行。

出問題只存在于串口又有接收,又有發(fā)送的產(chǎn)品上。

產(chǎn)品發(fā)送一般是周期性的,但是接收是隨機的,無線信號串口接收,所以產(chǎn)品的出問題的情況也是隨機的,但是數(shù)據(jù)量大起來肯定就會出現(xiàn)永遠接收不到的問題。

2.2 嘗試的處理方式

因為所有的一些都是按照正常流程設計的,按理來說實在是不知道為什么會這樣,所以網(wǎng)上查詢測試了好久,現(xiàn)在我把嘗試的處理方式以及步驟記錄說明一下:

2.2.1 清除錯誤標志位

在使用 HAL 庫的時候,有4個錯誤 flag,如下圖:

圖片

在這里插入圖片描述

期初還以為是某些異常錯誤導致的,經(jīng)過網(wǎng)上的的一些查詢,剛開始是添加了清除錯誤標志位:

__HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_PE);//清標志
 __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_FE);
 __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_NE);
 __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_ORE);

在需要的地方加上錯誤標志位清除,我是在清除串口緩存中處理的:

圖片

在這里插入圖片描述

2.2.2 串口溢出錯誤

其實串口溢出錯誤在上面的已經(jīng)清除過標志位,因為這個問題著實搞得我頭有點大,所以看到網(wǎng)上前人的處理方式和上面直接清除不一樣,還是試了一把。

這里簡單說明一下,我還特意去看了下自己的 CubeMX 設置,在設置的時候 有一個 Overrun 錯誤標志位,平時我們設置都不一定往下拉著看 = =!:

圖片

在這里插入圖片描述

然后確定了開啟了串口溢出錯誤檢測以后,我根據(jù)網(wǎng)上的方式,加了一個HAL_UART_ErrorCallback函數(shù),其實就類似于HAL_UART_RxCpltCallback 函數(shù):

圖片

在這里插入圖片描述

自己加了一個 出錯處理函數(shù),其實現(xiàn)在看來,當然也是沒有用的。

2.2.3 HAL庫的半雙工處理?

折騰了好長一段時間,其實一開始就知道問題在于 同時收發(fā)會出問題的情況,那么繼續(xù)上網(wǎng)找問題。

最終確定了一個問題就是:

我們都知道 STM32 串口是全雙工的, STM32 HAL庫在處理接收的時候會鎖一下串口一會,導致變成某個短時間的“半雙工”。

這個時候如果同時收發(fā)就會出現(xiàn)問題,最后解決的辦法在這篇文章中看到了:STM32 F103串口同時收發(fā)出現(xiàn)死鎖問題解決辦法

問題在于我們使用的HAL_UART_Receive_IT函數(shù)中,有對串口加鎖的操作:

圖片雖然在后面有解鎖:

圖片

在這里插入圖片描述

但是根據(jù)后期的解決方式來說,確實就是這個HAL_UART_Receive_IT函數(shù)的問題,最后使用的方式為,在產(chǎn)生一次中斷以后開啟的時候手動解鎖:

圖片

在這里插入圖片描述

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if(huart- >Instance == LPUART1){
    Enocean_Data++;
    if(Enocean_Data > 98)Enocean_Data = 0;
    while(HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1) != HAL_OK){
      hlpuart1.RxState = HAL_UART_STATE_READY;
      __HAL_UNLOCK(&hlpuart1);
    }
  }
  else if(huart- >Instance==USART1)
  {  
  }
}

終于,串口不再卡死 , 成功!

結語

沒想到和 EEPROM 一樣,一個簡單的芯片,一個熟悉的串口 ,出了這種問題 = =!還好最后解決了問題。

踩過的坑都是積累與經(jīng)驗,加油。

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

    關注

    2270

    文章

    10895

    瀏覽量

    355721
  • 串口
    +關注

    關注

    14

    文章

    1551

    瀏覽量

    76421
  • HAL
    HAL
    +關注

    關注

    2

    文章

    70

    瀏覽量

    12607
收藏 人收藏

    評論

    相關推薦

    淺析STM32HAL串口處理

    STM32HAL串口處理—中斷收發(fā)文章目錄STM32HAL
    發(fā)表于 08-16 06:28

    STM32 HAL串口收發(fā)崩潰的原因

    的校驗碼后字節(jié)添加1-8字節(jié)隨機數(shù),每種字節(jié)長度測試10000次。以上測試初串口就會崩潰,只能發(fā)不能收,調(diào)試結果是,串口接收中斷不再響應。源碼中使用HAL_UART_Receive_I...
    發(fā)表于 08-23 08:58

    STM32F429標準串口收發(fā)通信程序的詳細資料免費下載

    本文檔的主要內(nèi)容詳細介紹的是STM32F429標準串口收發(fā)通信程序的詳細資料免費下載,此程序可實現(xiàn)串口
    發(fā)表于 12-07 08:00 ?70次下載
    <b class='flag-5'>STM32</b>F429標準<b class='flag-5'>庫</b><b class='flag-5'>串口</b>的<b class='flag-5'>收發(fā)</b>通信程序的詳細資料免費下載

    STM32 串口使用IDLE中斷+DMA接收(HAL庫函數(shù))

    STM32 串口使用IDLE中斷+DMA接收(HAL庫函數(shù))一、開發(fā)環(huán)境單片機型號:STM32H743IIT6工程配置環(huán)境:STM32Cub
    發(fā)表于 12-02 21:06 ?41次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>串口</b>使用IDLE中斷+DMA接收(<b class='flag-5'>HAL</b>庫函數(shù))

    HAL】Proteus+VSPD實現(xiàn)仿真stm32虛擬串口

    Proteus+VSPD仿真stm32串口工具軟件準備Proteus工程CubeMX工程配置串口收發(fā)程序虛擬串口仿真工具軟件準備
    發(fā)表于 12-06 18:36 ?41次下載
    【<b class='flag-5'>HAL</b><b class='flag-5'>庫</b>】Proteus+VSPD實現(xiàn)仿真<b class='flag-5'>stm32</b>虛擬<b class='flag-5'>串口</b>

    串口通信小試牛刀~使用STM32CubeMX+ HAL點亮流水燈

    STM32CubeMX與Keil MDK配合HAL完成流水燈的點亮。目錄一、STM32串口通信基礎二、
    發(fā)表于 12-07 10:06 ?14次下載
    <b class='flag-5'>串口</b>通信小試牛刀~使用<b class='flag-5'>STM32</b>CubeMX+ <b class='flag-5'>HAL</b><b class='flag-5'>庫</b>點亮流水燈

    STM32CubeMX基于HAL實現(xiàn)簡單串口通信

    STM32CubeMX基于HAL實現(xiàn)簡單串口通信板子:STM32F103C8編譯工具:Keil+STM
    發(fā)表于 12-08 12:36 ?20次下載
    <b class='flag-5'>STM32</b>CubeMX基于<b class='flag-5'>HAL</b><b class='flag-5'>庫</b>實現(xiàn)簡單<b class='flag-5'>串口</b>通信

    HAL串口通信

    HAL入門之串口通信學習經(jīng)驗分享
    發(fā)表于 12-16 16:58 ?5次下載
    【<b class='flag-5'>HAL</b><b class='flag-5'>庫</b>】<b class='flag-5'>串口</b>通信

    STM32HAL串口接收丟字節(jié)

    HAL串口數(shù)據(jù)收發(fā)前言使用cubeMX創(chuàng)建工程文件時,默認使用HAL。作為最新的主流
    發(fā)表于 12-17 18:36 ?8次下載
    <b class='flag-5'>STM32</b>之<b class='flag-5'>HAL</b><b class='flag-5'>庫</b>的<b class='flag-5'>串口</b>接收丟字節(jié)

    STM32 HAL CubeMX教程(五)串口通信基礎

    STM32 HAL CubeMX教程(五)串口通信基礎串口通信簡介CubeMX配置初始化程序分析程序編寫UART: 通用異步
    發(fā)表于 12-24 18:49 ?12次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>HAL</b><b class='flag-5'>庫</b> CubeMX教程(五)<b class='flag-5'>串口</b>通信基礎

    STM32 HAL UART 串口讀寫功能筆記

    STM32L0 HAL UART 串口讀寫功能串口發(fā)送功能:uint8_t TxData[10]= “01234abcde”;
    發(fā)表于 12-27 19:11 ?13次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>HAL</b><b class='flag-5'>庫</b> UART <b class='flag-5'>串口</b>讀寫功能筆記

    stm32 hal資料分享

    stm32 hal資料分享
    發(fā)表于 11-03 16:17 ?120次下載

    STM32 HAL的功能和使用方法 STM32 HAL和標準的區(qū)別

    和可維護性,從而節(jié)省開發(fā)成本和時間。STM32 HALSTM32系列芯片的HAL,由ST公
    發(fā)表于 08-08 18:21 ?4363次閱讀

    STM32 HAL串口收發(fā)是如何使用的?

    STM32 HAL串口收發(fā)是如何使用的? STM32是一款高性能的微控制器,它擁有廣泛的應用領
    的頭像 發(fā)表于 10-26 17:42 ?1221次閱讀

    STM32 HAL串口同時收發(fā),接收卡死?

    STM32 HAL串口同時收發(fā),接收卡死? 為什么STM32
    的頭像 發(fā)表于 10-26 17:42 ?3493次閱讀
    RM新时代网站-首页