stm32F051 HAL库+DMA+串口空闲中断
STM32CubeMX 配置實現參考這里。
1.?串口空閑中斷
1.1 UART_DMA方式接收數據
STM32串口使用DMA方式接收數據可以減小CPU的開銷。
對于接收定長數據,可以將DMA接收緩沖區的長度設定為待接收數據的長度,這樣利用DMA的傳輸完成中斷DMAx_IT_TCy就可以知道已經接收了一幀數據。
對于接收不定長數據,如何知道意見完成了數據的接收呢?
1.2不定長數據接收的原理及其解決的問題
在 STM32 中,UART是最為常見的通信方式——它每次接收一個字節,我們可以使用輪詢的方式,但是對于某些數據不固定時間發送的數據,輪詢的方式有時候不夠靈活。也可以使用中斷的方式,如每一個字節都中斷一次,比較消耗系統資源。特別是HAL庫中,從中斷到回調函數運行了不少的程序,頻繁的中斷很可能造成數據溢出。
為了避免這個問題,我們使用指定接收一定長度的數據,再調用回調函數,這會讓我們可以接收大數據,但是這種情況則造成了,要求每次的包是固定長度。
為了解決以上一些問題,網上最常用的辦法是使用空閑中斷,即在串口空閑的時候,觸發一次中斷,通知內核,本次運輸完成了。串口空閑中斷的判定是:當串口開始接收數據后,檢測到1字節數據的時間內沒有數據發送,則認為串口空閑了。由于我們的內核在串口接收數據到空閑這段時間,是不受理串口數據的,所以我們還需要使用DMA來協助我們把數據傳送到指定的地方,當數據傳輸完成后,通知內核去處理。
2. 實現流程
?2.1 開啟串口空閑中斷
首先,我們在初始化的時候,使能串口空閑中斷,讓串口在中斷的時候,MCU可以調用串口中斷函數。我們這里還有一個uart2連接了WIFI模塊,所以使能兩個。
在 main.c 文件中的 MX_USART1_UART_Init(void) 和MX_USART2_UART_Init函數中:
當添加這個函數到工程以后,每發送一次數據,都會調用一次USART1_IRQHandler()?中斷服務函數,你可以在該函數中插入打印語句,來驗證是否空閑中斷正常。
2.2 配置 DMA 接收
?雖然我們使用的CubeMx來配置DMA,當然只是配置DMA模式為串口到內存(DMA初始化),但還需要在程序中進一步制定,DMA具體搬運到哪一個內存中,我們建立一個數組用以存放DMA搬運的串口數據,并使用HAL_UART_Receive_DMA()函數來配置,具體代碼如下所示:
... ... uint8_t receive_buff1[255]; uint8_t receive_buff2[255]; //定義接收數組 ... ... void main(void) {} ... ...重點要注意的就是這兩個地方,stm32cubemax生成這個代碼的時候有個小bug呀,它默認生成的MX_DMA_Init()放在了串口初始化的后面這樣每次發數據都只能接收到最后一個字節。按照上圖挪到前面就可以了。
還有一個問題就是stm32 hal串口 dma和idle模式只能接收第一個字符
原因分析:
在單片機執行完串口初始化之后,并沒有立馬開啟DMA接收,在這個時間差之內如果有數據發過來就會導致這個問題
解決方案:
在完成串口初始化之后,立馬開啟DMA接收,中間不能有較大的空擋時間差即可。直接放一起的時候又會有緩沖區刷新不趕緊的問題,加了個500ms的延時。自行調整
?
?2.3 添加中斷處理函數和回調函數
stm32f0xx_it.c :
uart.c
總結
以上是生活随笔為你收集整理的stm32F051 HAL库+DMA+串口空闲中断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【无标题】STM32F407VGT6文件
- 下一篇: python进制转换简述