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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32F0单片机快速入门八 聊聊 Coolie DMA

發布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32F0单片机快速入门八 聊聊 Coolie DMA 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.苦力 DMA

世上本沒有路,走的人多了,便成了路。世上本沒有 DMA,需要搬運的數據多了,便有了 DMA。

大多數同學應該沒有在項目中用過這個東西,因為一般情況下也真不需要這個東西。在早期的單片機中也不存在DMA模塊。再加上很多談 DMA 的文章,一上來就先來一個總線架構圖,然后來一大堆讓人生畏的詞兒:共享總線,仲裁器,指針增量,對齊,中斷 ... 好吧,每一個詞都能嚇跑一批膽小的。

真的需要這么復雜嗎?就好比我們學開車一樣,能不能先別去嘗試弄懂發動機的原理,直接掛檔踩油門走起來呢?

DMA是很簡單的一個模塊,首先他的功能單一,就是把數據從一個地方搬運到另一個地方,再一個它的用法也很簡單,我們還是先從一個例子說起:

我們用 Keil 打開下面這個工程:

STM32Cube_FW_F0_V1.11.0\Projects\STM32F030R8-Nucleo\Examples\DMA\DMA_FLASHToRAM\MDK-ARM\Project.uvprojx

如圖,有一些存儲在 Flash 的數據需要搬運到 RAM 區的一個數組。通常我們可以用如下的代碼實現:

for(i=0;i<buffer_size;i++)

? ? aDST_Buffer[i]?= aSRC_Const_Buffer[i];

上面這個操作是 CPU 親自完成的,首先把數據裝進自己的寄存器,再把寄存器中的數據存放到目的地址。在例中所示這種數據比較少的情況下,這種搬運工作可以說瞬間就完成了。但如果數據量比較大,比如說要往顯示屏刷新顯示數據,就要占用 CPU 大量的時間了。這時候 CPU 就可以叫來 DMA 來干這件苦差事。DMA 就是芯片中的苦力集中營。

跟苦力需要交代清楚的最基本的事情就是:從哪兒搬到哪兒,貨物有多少,搬一次還是有貨物源源不斷的到來,需要循環不斷的搬。

讓我們看一下代碼,主程序非常簡單,調用 DMA_Config(); 進行了一下配置后就自己該干嘛干嘛去了。

2.代碼

像串口工程代碼聲明了串口類型的 Handle一樣,這里聲明了一個 DMA 類型的 Handle 來負責 DMA 模塊的處理。

DMA_HandleTypeDef???? DmaHandle;

需要注意的地方:

__HAL_RCC_DMA1_CLK_ENABLE();

使能模塊時鐘,使能模塊時鐘,使能模塊時鐘!重要的事情要說3遍。在使用任何一個模塊之前首先要使能該模塊的時鐘,這是經常被忘記的一件事兒。這個功能在老型號單片機里是沒有的。在不使用某模塊時,徹底關斷其時鐘可以達到最大節省功耗的目的。

初始化參數(DmaHandle.Init.):

Direction ?從外設到內存,從內存到內存,還是從內存到外設?

PeriphInc? 每傳完一個數后外設地址是否自增1

MemInc? 每傳完一個數后內存地址是否自增1

PeriphDataAlignment? 外設地址對齊方式,Byte,Halfword or Word

MemDataAlignment ?內存地址對齊方式,Byte,Halfword or Word

Mode? 單次,還是循環模式

Priority? 優先級

初始化參數(DmaHandle.Instance):

DMA模塊中有多個通道,此參數指明使用哪一個通道。

這個代碼調用 HAL_DMA_Start_IT 這個函數啟動了 DMA 傳輸,當數據搬運完后會產生一個完成中斷,并調用回調函數 TransferComplete。在HAL層驅動中,已經完成了 DMA 中斷所要做的基本處理,比如根據中斷類型清除相應中斷標志等。在回調函數中用戶可以什么都不做,也可以根據需要添加代碼,比如此例中用點亮 LED 燈的方式來標志傳輸完成。

3.串口如何使用 DMA 傳輸

前面的例子是用軟件的方式觸發 DMA 傳輸,在應用中經常會用到由某個事件觸發的情況。比如通過串口發送,接收中斷來觸發 DMA 傳輸。

我們打開下面這個例子:

STM32Cube_FW_F0_V1.11.0\Projects\STM32F030R8-Nucleo\Examples\UART\UART_TwoBoards_ComDMA\MDK-ARM\ Project.uvprojx

在串口初始化的回調函數 HAL_UART_MspInit(UART_HandleTypeDef *huart)中:

a 聲明了兩個 DMA 類型的 Handle: hdmatx 和 hdmarx

b 初始化這兩個 Handle

c 把這兩個 Handle 和串口的 UartHandle 連接起來

__HAL_LINKDMA(huart, hdmatx, hdma_tx);

__HAL_LINKDMA(huart, hdmarx, hdma_rx);

在串口及其關聯 DMA 通道初始化完成后,既可以啟動DMA方式的接收和發送。從下圖中可以看到接收 HAL_UART_Receive_DMA 的調用過程,發送調用過程類似:

下圖是UART中斷,和DMA中斷的觸發調用過程。USART1模塊產生錯誤時仍然進USART1的中斷向量,DMA模塊傳輸完成或傳輸過程中產生錯誤時進 DMA 中斷向量。

如果沒有迫切的需要,DMA 模塊了解一下就行了。沒有必要在細節上過多糾纏,即使現在搞懂了,過兩三個月估計也忘了。建議在真正用到大量數據傳輸時再仔細研究和優化相關代碼。

參考資料:

PM0215? STM32F0xxx Cortex-M0 programming manual

UM1785 Description of STM32F0 HAL and low-layer drivers

STM32F030 Datasheet

STM32F030 Reference Manual

掃碼關注公眾號:

加入微信交流群:


推薦閱讀:

專輯|Linux文章匯總

專輯|程序人生

專輯|C語言

我的知識小密圈

關注公眾號,后臺回復「1024」獲取學習資料網盤鏈接。

歡迎點贊,關注,轉發,在看,您的每一次鼓勵,我都將銘記于心~

嵌入式Linux

微信掃描二維碼,關注我的公眾號

總結

以上是生活随笔為你收集整理的STM32F0单片机快速入门八 聊聊 Coolie DMA的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。