前言
在嵌入式系統(tǒng)中,串口通信是一項關(guān)鍵的任務(wù),而使用DMA(直接內(nèi)存訪問)結(jié)合IDLE中斷進(jìn)行串口編程,尤其是在STM32 CubeMX環(huán)境中,能夠提高系統(tǒng)的效率和性能。STM32 CubeMX為STM32微控制器提供了圖形化的配置工具,可以簡化初始化代碼的生成過程,使得串口編程變得更加容易。通過結(jié)合DMA和IDLE中斷,我們可以實現(xiàn)高效的異步串口通信,確保數(shù)據(jù)傳輸?shù)目煽啃?,同時減輕CPU的負(fù)擔(dān)。
一、為什么要引入IDLE中斷
比如我們的stm32接了一個wifi模塊esp8266,esp8266會發(fā)來數(shù)據(jù),假設(shè)我現(xiàn)在想去讀數(shù)據(jù),我使用DMA方式讀數(shù)據(jù),我不知道esp8266給我發(fā)多少數(shù)據(jù),但是肯定不超過1024字節(jié)吧,然后我調(diào)用函數(shù)去讀,讀1024字節(jié),如果他給我發(fā)了剛好1024字節(jié),欸,那么就讀成功了。如果他發(fā)1000數(shù)據(jù),而且這1000數(shù)據(jù)是完整的了,但DMA的中斷并不會調(diào)用,DMA中斷只會在接收到一半或者全部接收完才會調(diào)用。
我們?nèi)绾沃浪陌l(fā)的這些東西已經(jīng)完整了呢?
我們知道,當(dāng)串口發(fā)送數(shù)據(jù)的時候,他必定有一個起始位,如果接收方在這一節(jié)數(shù)據(jù)之后,發(fā)現(xiàn)這個引腳一直沒有開始信號,在10bit的時間里發(fā)現(xiàn)對方都沒有數(shù)據(jù),他就認(rèn)為數(shù)據(jù)發(fā)送完了,這時就會產(chǎn)生IDLE空閑中斷。
比如說對方發(fā)了1bit的數(shù)據(jù),由于一些原因卡殼了,過了10bit的數(shù)據(jù)時間,這時就會調(diào)用IDLE中斷,可是數(shù)據(jù)并不完整啊。所以對于這種情況,IDLE中斷是無意義的。
注意:IDLE中斷用來傳輸大量數(shù)據(jù)的時候才有意義。
二、IDLE中斷使用方式
2.1 接收的三種情況
當(dāng)我們使用IDLE中斷來接收數(shù)據(jù)的時候,他完成會有三種情況
- 第一種就是確實接收到了指定數(shù)據(jù),調(diào)用的完成的回調(diào)函數(shù)(HAL_UART_RxCpltCallback被調(diào)用)
- 第二種就是IDLE中斷調(diào)用了(HAL_UARTEx_RxEventCallback被調(diào)用)
- 第三種就是有錯誤發(fā)生導(dǎo)致中斷(HAL_UART_ErrorCallback被調(diào)用)
2.2 函數(shù)的使用
查詢方式
我們可以使用下面這個函數(shù)進(jìn)行IDLE中斷的查詢方式進(jìn)行查詢:
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
uint32_t Timeout);
UART_HandleTypeDef *huart:
作用: 傳遞一個指向UART_HandleTypeDef結(jié)構(gòu)體的指針,該結(jié)構(gòu)體包含了UART的配置和狀態(tài)信息。
解釋: 這個參數(shù)用于標(biāo)識特定的UART外設(shè),通過該參數(shù),函數(shù)知道應(yīng)該對哪個UART進(jìn)行操作。
uint8_t *pData:
作用: 指向要接收數(shù)據(jù)的緩沖區(qū)的指針。
解釋: 這個參數(shù)指定了存儲接收數(shù)據(jù)的緩沖區(qū)。當(dāng)函數(shù)接收到指定數(shù)量的字節(jié)或達(dá)到超時條件時,接收到的數(shù)據(jù)將存儲在該緩沖區(qū)中。
uint16_t Size:
作用: 要接收的數(shù)據(jù)字節(jié)數(shù)。
解釋: 它定義了期望接收的字節(jié)數(shù)目。當(dāng)接收的字節(jié)數(shù)達(dá)到這個值時,函數(shù)將數(shù)據(jù)接收到空閑狀態(tài)(IDLE)。
uint16_t *RxLen:
作用: 指向用于存儲實際接收到的數(shù)據(jù)字節(jié)數(shù)的指針。
解釋: 當(dāng)函數(shù)成功接收到數(shù)據(jù)時,它將更新此指針指向的變量,以反映實際接收到的字節(jié)數(shù)。這對于知道接收了多少數(shù)據(jù)很有用。
uint32_t Timeout:
作用: 接收數(shù)據(jù)的超時時間。
解釋: 定義了等待接收數(shù)據(jù)的最大時間。如果在超時時間內(nèi)未接收到指定數(shù)量的字節(jié),函數(shù)將返回適當(dāng)?shù)腻e誤代碼。
如果有IDLE狀態(tài),他放回HAL_OK
中斷方式
我們可以使用下面這種方式進(jìn)行IDLE中斷的接收:
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
這個函數(shù)就是去使能接收中斷和IDLE中斷。
如果發(fā)生了IDLE中斷他會怎么做?
在串口1這里,IDLE中斷也屬于串口中斷
下面就是如果有IDLE中斷發(fā)生的代碼:如果發(fā)現(xiàn)了IDLE中斷,他會分兩種情況處理
如果你使用DMA:
取消DMA,調(diào)用下面這個:
傳入你收到了幾個字符。
如果你使用中斷:
禁止接收中斷,調(diào)用下面這個:
傳入你收到了幾個字符。
當(dāng)有IDLE中斷時,調(diào)用HAL_UARTEx_RxEventCallback表示有IDLE中斷了
DMA方式
我們可以使用下面這個函數(shù)進(jìn)行DMA+IDLE接收:
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
當(dāng)他產(chǎn)生IDLE中斷后,他會調(diào)用HAL_UARTEx_RxEventCallback
回調(diào)函數(shù)
分析一個問題
UART 的 IDLE 中斷何時發(fā)生?RxD 引腳一開始就是空閑的啊,難道 IDLE 中斷一直產(chǎn)生?
不是的。當(dāng)我們使能 IDLE 中斷后,它并不會立刻產(chǎn)生,而是:至少收到 1 個數(shù)據(jù)后,發(fā)現(xiàn)
在一個字節(jié)的時間里,都沒有接收到新數(shù)據(jù),才會產(chǎn)生 IDLE 中斷。文章來源:http://www.zghlxwxcb.cn/news/detail-828513.html
總結(jié)
串口編程對于嵌入式系統(tǒng)至關(guān)重要,而在STM32 CubeMX環(huán)境中,利用DMA和IDLE中斷的組合可以使串口通信更為高效。DMA允許數(shù)據(jù)在內(nèi)存和外設(shè)之間直接傳輸,減輕了CPU的負(fù)擔(dān),提高了系統(tǒng)的響應(yīng)速度。IDLE中斷則使得在沒有數(shù)據(jù)傳輸時,系統(tǒng)能夠進(jìn)入低功耗狀態(tài),進(jìn)一步降低功耗。通過這樣的串口編程方式,我們能夠在保證性能的同時,實現(xiàn)更加節(jié)能和可靠的嵌入式系統(tǒng)。在STM32 CubeMX的支持下,配置串口通信變得更加簡單,為嵌入式開發(fā)者提供了更高的開發(fā)效率。文章來源地址http://www.zghlxwxcb.cn/news/detail-828513.html
到了這里,關(guān)于【STM32 CubeMX】串口編程DMA+IDLE中斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!