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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

stm32F051 HAL库+DMA+串口空闲中断

發(fā)布時(shí)間:2023/12/31 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stm32F051 HAL库+DMA+串口空闲中断 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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)流程

  • 開(kāi)啟串口空閑中斷:?在程序初始化時(shí)候,使能串口中斷
  • 定義串口空閑中斷處理函數(shù):?在串口中斷中添加串口空閑中斷處理函數(shù)
  • 定義串口空閑中斷回調(diào)函數(shù):?用以標(biāo)記數(shù)據(jù)接收完成,計(jì)算接收到數(shù)據(jù)的長(zhǎng)度
  • ?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ù)中:

    void MX_USART1_UART_Init(void) {// 省略了串口協(xié)議初始化部分__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 使能串口空閑中斷 }

    當(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)題。

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