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