我們?cè)?a target="_blank">MCU的嵌入式應(yīng)用開發(fā)過程中,有時(shí)需要做些較大量的數(shù)據(jù)傳輸和適時(shí)處理,此時(shí)使用DMA的雙緩沖模式可能是個(gè)不錯(cuò)的選擇。這樣既可以保障數(shù)據(jù)的連續(xù)、流暢傳輸,又能保障數(shù)據(jù)的及時(shí)處理【包括數(shù)據(jù)更新】,同時(shí)又能減輕CPU的負(fù)荷。
常有人想使用STM32 DMA的雙緩沖模式,但又覺得實(shí)現(xiàn)起來似乎有點(diǎn)困難,也不太容易找到現(xiàn)存的例程。我這里就基于STM32F4芯片及Cube庫簡單地演示下實(shí)現(xiàn)過程。
STM32的DMA硬件雙緩沖模式,只支持從外設(shè)到內(nèi)存或從內(nèi)存到外設(shè)兩種應(yīng)用場(chǎng)景,且工作在循環(huán)模式。內(nèi)存到內(nèi)存是不支持雙緩沖模式的,當(dāng)然它也不支持DMA循環(huán)模式。【下圖截取于STM32F4的參考手冊(cè)】
關(guān)于STM32 DMA雙緩沖模式實(shí)現(xiàn)原理不復(fù)雜,這里就不贅述了。下面進(jìn)入到示例的實(shí)現(xiàn)過程。【注:手機(jī)模式下圖片可以點(diǎn)擊放大查看】
我這里大致要做的事情就是,ADC模塊對(duì)5個(gè)模擬通道進(jìn)行循環(huán)掃描采樣轉(zhuǎn)換,ADC結(jié)果由DMA搬到相應(yīng)存儲(chǔ)緩沖區(qū)。每一輪傳輸完成后,自動(dòng)切換傳輸線路并使用另一個(gè)存儲(chǔ)區(qū),繼續(xù)新一輪傳輸。兩條傳輸線路就這樣輪流執(zhí)行,不過使用的DMA傳輸流或通道還是同一個(gè)。本例中的DMA傳輸流程如下圖示意。至于數(shù)據(jù)搬到各存儲(chǔ)區(qū)后怎么辦,視應(yīng)用而定,在此不表。
現(xiàn)在開始借助于STM32CubeMx圖形化配置工具做基本的配置并生成初始化文件。
**對(duì)ADC做些基本配置。開啟了ADC1的5個(gè)通道,做連續(xù)、掃描轉(zhuǎn)換。ADC轉(zhuǎn)換的啟動(dòng)選擇軟件啟動(dòng)模式。
**對(duì)ADC的DMA請(qǐng)求及DMA傳輸做相關(guān)配置。具體配置見下圖。
**將其它必需的時(shí)鐘、調(diào)試口等配置完成后即可生成初始化代碼并建立工程。
**在CubeMx生成的初始化代碼基礎(chǔ)上,添加用戶代碼。
一、這里準(zhǔn)備了兩個(gè)數(shù)組用來存儲(chǔ)ADC的轉(zhuǎn)換結(jié)果。
二、我基于STM32F4系列芯片和STM32CubeF4 HAL庫組織和添加用戶代碼。代碼內(nèi)容詳見下圖。
上圖中A、B、C、D四部分是我基于當(dāng)前應(yīng)用而添加的用戶代碼,在此稍作解釋。
代碼A,使能ADC外設(shè)并稍作延時(shí),令其穩(wěn)定下來。
代碼B,準(zhǔn)備了幾個(gè)跟DMA傳輸完成及出錯(cuò)有關(guān)的回調(diào)函數(shù)。三個(gè)回調(diào)函數(shù)我共用一個(gè),這里圖省事了。實(shí)際應(yīng)用時(shí)請(qǐng)具體調(diào)整。
代碼C,調(diào)用DMA雙緩沖模式的關(guān)鍵函數(shù)。
代碼D,使能ADC事件的DMA請(qǐng)求功能并軟件啟動(dòng)AD轉(zhuǎn)換。
三、編譯、除錯(cuò)后,運(yùn)行看結(jié)果。下面截圖是我在調(diào)試過程中隨意截取的。ADC的輸入通道中有2個(gè)通道分別固定接GND和VDD,其它3個(gè)通道的輸入管腳懸空,數(shù)據(jù)波動(dòng)大屬正常現(xiàn)象。
到此,基于STM32DMA雙緩沖的功能演示就結(jié)束了。是不是感覺很方便而簡單呢?
個(gè)人認(rèn)為,要實(shí)現(xiàn)上面功能盡量看懂相關(guān)庫函數(shù)的基本功能,并對(duì)相應(yīng)外設(shè)的工作有基本的了解,畢竟還是需要自行組織部分代碼的。如果說只知生硬地調(diào)用現(xiàn)有庫函數(shù),那實(shí)現(xiàn)起來還是有困難。
另外,即使調(diào)用庫函數(shù),在給函數(shù)的參變量賦值時(shí)注意別給錯(cuò)了。大部分類似問題編譯器能發(fā)現(xiàn),有些是發(fā)現(xiàn)不了的。比方源地址和目標(biāo)地址編譯器是辨別不了的。
還有,基于庫函數(shù)編程時(shí),如果庫函數(shù)里已經(jīng)就某些變量或參數(shù)給出了定義或規(guī)劃,就盡量用它準(zhǔn)備的,除非你發(fā)現(xiàn)相關(guān)定義或規(guī)劃不合理或有錯(cuò)。前不久一個(gè)STM32用戶,在初始化RTC日歷時(shí)給星期賦予了一個(gè)不正確的值導(dǎo)致RTC的時(shí)間運(yùn)行異常。本來庫代碼已經(jīng)對(duì)從星期日到星期六明確地做了宏定義供我們使用【這樣做本身就可以一定程度防止出錯(cuò)】,結(jié)果他在調(diào)試時(shí)直接賦數(shù)據(jù),不小心給了不合理的數(shù)據(jù)沒及時(shí)發(fā)現(xiàn),導(dǎo)致程序異常。然后反饋說庫代碼有bug。算bug嗎?可以算是也可以不是。如果初始化時(shí)按照人家預(yù)備好的宏參數(shù)來賦值就不會(huì)在這個(gè)地方折騰一把。
責(zé)任編輯:pj
-
芯片
+關(guān)注
關(guān)注
456文章
51182瀏覽量
427271 -
代碼
+關(guān)注
關(guān)注
30文章
4827瀏覽量
69053
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
HAL庫在STM32開發(fā)中的重要性
STM32項(xiàng)目實(shí)戰(zhàn):基于STM32F4的智能燈光控制系統(tǒng)(LVGL),附項(xiàng)目教程/源碼
![<b class='flag-5'>STM32</b>項(xiàng)目實(shí)戰(zhàn):基于<b class='flag-5'>STM32F4</b>的智能燈光控制系統(tǒng)(LVGL),附項(xiàng)目教程/源碼](https://file1.elecfans.com/web2/M00/0A/99/wKgaomcQx7-ANGIzAADQCHA0gz0430.png)
STM32F4 HAL庫下CAN發(fā)送導(dǎo)致FLASH報(bào)錯(cuò)怎么解決?
【GD32 MCU 移植教程】8、從 STM32F4xx 系列移植到 GD32F4xx 系
![【GD32 MCU 移植教程】8、從 <b class='flag-5'>STM32F4</b>xx <b class='flag-5'>系列</b>移植到 GD32<b class='flag-5'>F4</b>xx 系](https://file1.elecfans.com/web2/M00/06/61/wKgaombaXZ6AB4PtAABI6uZ03C4508.png)
課程上線 | STM32單片機(jī)入門教程(1)基于HAL庫的多核心開發(fā)(F1/F4/G0/U5)
![課程上線 | <b class='flag-5'>STM32</b>單片機(jī)入門教程(1)基于<b class='flag-5'>HAL</b><b class='flag-5'>庫</b>的多核心開發(fā)(<b class='flag-5'>F</b>1/<b class='flag-5'>F4</b>/G0/U5)](https://file1.elecfans.com/web2/M00/02/3A/wKgaoma0hOWAcdxUAABK3YndV5w042.png)
評(píng)論