日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

stm32 hal uart_STM32 非阻塞HAL_UART_Receive_IT解析与实际应用

發(fā)布時間:2025/4/16 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stm32 hal uart_STM32 非阻塞HAL_UART_Receive_IT解析与实际应用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本文章主要探討如何使用STM32中HAL庫的UART_Receive_IT非阻塞接收數(shù)據(jù)。其他網(wǎng)絡教程(包括正點原點相關(guān)教程)可能個人原因無法完全理解,苦苦掙扎后才完成非阻塞UART接收。
希望可以通過不同的視角能更好的總結(jié)分享如何使用HAL庫中的非阻塞UART。關(guān)于如何配置UART的問題本文不做具體介紹,需要這部分內(nèi)容的可以參考其他分享者的文章。另外,如希望在MacOS或Linux平臺優(yōu)雅的編寫、燒錄STM32代碼的可以參考我另外兩篇文章。Yume:MacOS在VSCode中優(yōu)雅的編寫STM32(HAL庫)?zhuanlan.zhihu.comYume:MacOS基于STM32CubeMX、Makefile和OpenOCD的Stm32交叉編譯環(huán)境搭建?zhuanlan.zhihu.com

1 通過STM32CubeMX初始化并生成工程目錄

通過STM32CubeMX可以很輕松的完成配置,網(wǎng)絡上也有很多很優(yōu)秀的分享者寫的教程。同時也可以參考我的另一篇文章(MacOS、Liunx用戶也可作為參考)進行相關(guān)的配置

Yume:MacOS基于STM32CubeMX、Makefile和OpenOCD的Stm32交叉編譯環(huán)境搭建?zhuanlan.zhihu.com

2 通過CoolTerm與STM32通信

Roger Meier's Freeware?freeware.the-meiers.org

具體使用方法,可以在網(wǎng)絡上找到很多教程,基本方法就是設置好對應的如波特率、有無奇偶校驗位等。需要特別指出的是,此軟件發(fā)送"ASCII"是原生發(fā)送,不會自動添加額外的結(jié)束符(也可能是我沒有配置)。

3 HAL庫中的非阻塞UART

可以在工程目錄"Drivers/CMSIS/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c"中看到所有關(guān)于UART的HAL庫函數(shù)使用方法。其中我們重點關(guān)注4個函數(shù)"UART_Receive_IT"、"HAL_UART_RxCpltCallback"、"HAL_UART_IRQHandler"、"HAL_UART_Receive_IT"

  • HAL_UART_IRQHandler

此函數(shù)是request(響應中斷),即UART的RX中斷入口。當有數(shù)據(jù)發(fā)送時,就會進入到這個函數(shù)中。

HAL_UART_IRQHandler

可以從HAL的UART庫文件看到該函數(shù)的描述與具體過程。正常情況下(即errorflags = RESET)將會調(diào)用"UART_Receive_IT"進入處理數(shù)據(jù)的部分。

  • UART_Receive_IT

這個函數(shù)可以理解為RX接收數(shù)據(jù)處理的函數(shù)

UART_Receive_IT

可以看到當進入到這個函數(shù)的時候,會判斷當前RX接收狀態(tài)(重要)。中間數(shù)據(jù)處理過程我們略過,大概知道就是將數(shù)據(jù)存入到一個特殊寄存器里。(想了解具體過程的,可以自行閱讀HAL庫相關(guān)文件)。再看看完成數(shù)據(jù)的轉(zhuǎn)存、狀態(tài)設置之類操作后會發(fā)生什么

UART_Receive_IT

判斷條件"--huart->RxXferCount"就是判斷進來比特數(shù)是否到達指定的大小??梢钥吹疆敐M足條件是,將會關(guān)閉中斷響應,同時調(diào)用"HAL_UART_RxCpltCallback"函數(shù)。這個函數(shù)時給用戶的自定義的函數(shù),指定完成數(shù)據(jù)接收后的操作。

  • HAL_UART_RxCpltCallback

上文已經(jīng)提到了,這是個給用戶在完成RX數(shù)據(jù)接收后自行決定怎么操作的函數(shù)。但我們還是看看在HAL庫文件中是怎么定義的

HAL_UART_RxCpltCallback

可以看到void前面的"__weak"描述就是弱定義,指當用戶在進行定義時,可以理解為這個定義就失效了。所以我們可以在"main.c"再定義這個函數(shù),用于Rx完成接收后的操作。

那說到這,具體如何將Rx接收的數(shù)據(jù)進行轉(zhuǎn)存、處理等操作呢?

等等,是不是發(fā)現(xiàn)還有一個函數(shù)沒有說?

誒,通過從中斷入口層層進入,始終沒出現(xiàn)過"HAL_UART_Receive_IT"。那他究竟來干嘛的?還記得前面說到,在完成接收后"UART_Receive_IT"就會關(guān)閉中斷?,F(xiàn)在我們看看"HAL_UART_Receive_IT"

可以看到,該函數(shù)UART的RX為準備狀態(tài)后,就會將數(shù)據(jù)從接收數(shù)據(jù)的特殊寄存器"pRxBufferPtr"指針指向"pData"(用戶創(chuàng)建的寄存器)和一系列包括修改標志位等操作后,重新開啟UART的Receive中斷。

4 使用UART的HAL庫

那通過上面的一步一步從中斷入口走向出口。那我們也從入口開始,那就需要先打開入口(偽代碼形式)

uint8_t

其中"huart1"是UART1的數(shù)據(jù)結(jié)構(gòu),STM32CubeMX配置時會幫我們完成,是全局變量;"rDataBuffer"是用戶自定義用于轉(zhuǎn)存RX接收數(shù)據(jù)的寄存器;后面的數(shù)字"1"表示接收數(shù)據(jù)為1比特(目的是接收到1比特數(shù)據(jù)就拿出來,實現(xiàn)通過結(jié)束符判斷數(shù)據(jù)接收完成,而不是指定的字節(jié)長度)。在main中編寫這段,就完成了打開中斷入口的操作,同時配置"huart1"數(shù)據(jù)結(jié)構(gòu)中關(guān)于RX接收信息,提供給中斷入口函數(shù)"HAL_UART_IRQHandler"。那為何在這里需要用while不斷循環(huán)檢測返回值呢?因為可能RX處于正忙狀態(tài)。如果在RX正忙狀態(tài)調(diào)用HAL_UART_Receive_IT,可能就會導致不是按預期執(zhí)行的。

當數(shù)據(jù)發(fā)送到RX時,觸發(fā)中斷,進入"HAL_UART_IRQHandler"。從第一步的到的RX接收信息可知,收到1Byte數(shù)據(jù)就會進入到"UART_Receive_IT"處理數(shù)據(jù)、關(guān)閉總斷入口。再進入到用戶自定義操作的函數(shù)"HAL_UART_RxCpltCallback"。所以我們需要在"main.c"中編寫這個函數(shù)(函數(shù)外定義的變量是全局變量)

uint8_t

其中,全局變量"rData"用于存放接收到的數(shù)據(jù);"rDataBuffer"用于將接收到的數(shù)據(jù)從UART的RX特殊寄存器中轉(zhuǎn)移出來;"rDataCount"用于記錄收到的結(jié)束符之前(可以看到是通過"~"確認結(jié)束符,也可以根據(jù)需求自行定義)的數(shù)據(jù)字節(jié)數(shù);"rDataFlah"是通過一個符號表示完成RX的接收工作。當然,這些符號可以根據(jù)具體需求定義,并不是必須這么做的。

注意到的是,這里還有一個條件判斷"rDataBuffer[0]!=0x00",這么寫的目的首先是接收到"0"不處理,還有一個原因是因為在實踐過程中,不知道是什么原因,第一次發(fā)RX數(shù)據(jù)時,回顯數(shù)據(jù)顯示已經(jīng)進入過中斷,并進行RX數(shù)據(jù)接收轉(zhuǎn)存。如果不加判斷即使是沒接收到數(shù)據(jù)("0"=0x00)也判斷為有效數(shù)據(jù),那會出現(xiàn)第一次RX數(shù)據(jù)前面有幾字節(jié)為"0",不是預期的結(jié)果。我的判斷是可能在確認分隔幀時(大概就是取樣點),誤進入中斷導致的。但這不會影響后續(xù)RX的接收,所以及時不加也不會出現(xiàn)大問題。

然后接下來的判斷就是檢查是否收到RX接收結(jié)束符號,然后改變標志位,用于其他操作。

后面"while"就是重新打開UART的RX中斷,繼續(xù)接收數(shù)據(jù)。

5 結(jié)語

可以看出來,具體使用時其實就可以分為簡單的兩步:

  • "HAL_UART_Receive_IT"開啟中斷
  • "HAL_UART_RxCpltCallback"用戶處理中斷
  • 但如何完全掌握,能在實際項目中變通運用UART。還需要仔細分析庫函數(shù)的層層套娃中摸出一條線來。

    還有需要注意的是,本文所寫的沒有關(guān)注如寄存器溢出、出現(xiàn)錯誤如何處理等細節(jié)問題,這都需要更仔細的思考解決。


    總結(jié)

    以上是生活随笔為你收集整理的stm32 hal uart_STM32 非阻塞HAL_UART_Receive_IT解析与实际应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。