STM32 DMA入門指導

什么是DMA

DMA,全稱直接存儲器訪問(Direct Memory Access),是一種允許硬件子系統直接讀寫系統內存的技術,無需中央處理單元(CPU)的介入。下面是DMA的工作原理概述:
數據傳輸觸發:DMA傳輸可以由CPU指令觸發,也可以由硬件事件(如一個外設準備好數據)自動觸發。
外設和內存之間的數據交換:一旦DMA傳輸開始,DMA控制器會將數據從源地址直接傳送到目的地址。源地址常常是外設的數據寄存器,目的地址通常是內存中的一個緩沖區;反之亦然。
CPU解放:在沒有DMA的情況下,CPU需要執行多個指令來完成數據的傳送,包括數據的讀取和寫入操作。當使用DMA時,CPU只需初始化傳輸,之后DMA控制器將自動處理數據傳送,CPU則可以執行其他任務。
傳輸完成中斷:當所有數據都被傳輸至目的地之后,DMA控制器會向CPU發送一個中斷信號。這個中斷告知CPU數據已經成功傳輸完畢,CPU隨后可以進行后續處理,比如停止DMA,處理數據,或重新初始化另一次DMA傳輸。
優先級和通道:DMA控制器可能有多個通道,每個通道可以獨立配置并與特定的外設關聯。在多通道DMA系統中,可能會有優先級設置,以決定哪個DMA請求被優先處理。
DMA是提高數據傳輸效率、減少CPU負荷、優化系統性能的有效手段,特別是在處理高速數據流或頻繁數據傳輸時。在嵌入式系統和計算機架構中,有了DMA,CPU就可以更有效地處理邏輯計算和數據處理任務,而不是花費大量時間在數據移動上。

DMA可以用于哪些數據傳輸方式?

DMA 可以用于多種數據傳輸方式,包括:
1、內存到內存:數據可以直接從一個內存地址復制到另一個內存地址,無需CPU的介入。
2、外設到內存:數據從外設(如ADC,UART接收緩沖區,SPI等)直接傳輸到內存。這通常用于從外設讀取數據時。
3、內存到外設:數據從內存直接傳輸到外設(如DAC,UART發送緩沖區,SPI等)。這通常在向外設寫入數據時使用。
4、外設到外設:雖然不是所有DMA控制器都支持這個功能,但有些高級系統允許直接從一個外設到另一個外設的數據傳輸,不經過內存。
這些傳輸方式中,最常見的使用場景是外設到內存和內存到外設。因為這可以大幅度減輕CPU的工作負擔,尤其是在數據流量較大時,如從網絡接口接收數據包,或向圖形處理器發送圖像數據。?

DMA初始化的步驟有哪些?

DMA初始化的步驟通常如下所示:
1、DMA控制器時鐘使能:
通過 RCC(Reset and Clock Control)模塊使能 DMA 控制器的時鐘。
2、DMA通道配置:
? ? ? ? a、為目標 DMA 通道配置傳輸方向(從內存到外設、從外設到內存或者內存到內存)。
? ? ? ? b、設置源地址和目的地址及其增量模式(地址在傳輸后是否遞增)。
? ? ? ? c、配置數據大小(傳輸的數據寬度,一般為8位、16位或32位)。
? ? ? ? d、設定傳輸數據的數量(數據塊大小)。
3、外設配置:
如果外設(如 ADC, UART, SPI)使用 DMA 進行數據傳輸,需要在外設的配置中使能相應的 DMA 傳輸請求。
4、中斷配置(可選):
根據實際需要,可以配置并使能傳輸完成、半傳輸完成及傳輸錯誤中斷。
5、DMA流控制(如果適用):
在某些情況下,特別是在使用雙緩沖或循環模式時,可能需要配置 DMA 流控制。
6、啟動DMA傳輸:
使用相應的庫函數或直接通過控制寄存器啟動 DMA 傳輸。

重要寄存器

STM32微控制器中的DMA(直接存儲器訪問)寄存器包括幾組關鍵的控制和狀態寄存器,用于管理和監控DMA的操作。具體的寄存器會根據STM32的不同系列及其內部架構的差異而有所不同,但一般而言,一個DMA通道會涉及以下幾個主要寄存器:
1、DMA控制寄存器 (DMA_CCRx):
控制傳輸的基本配置,包括傳輸方向、傳輸模式(正常或循環模式)、優先級、內存和外設大小、內存增量模式、外設增量模式等。
2、DMA數量寄存器 (DMA_CNDTRx):
包含被傳輸數據的數量。一次DMA操作開始前,此寄存器需要被加載。
3、DMA外設地址寄存器 (DMA_CPARx):
保存外部外設的基地址。
4、DMA內存地址寄存器 (DMA_CMARx):
保存內存的基地址。這是數據要被傳輸到或從中傳輸出的內存位置。
5、DMA狀態寄存器 (DMA_ISR):
表示每個通道的狀態,包括傳輸完成、半傳輸、傳輸錯誤和全局中斷標志。
6、DMA標志清除寄存器 (DMA_IFCR):
用于清除特定通道的中斷標志位。

DMA的狀態寄存器具體表示了哪些通道的狀態?

DMA的狀態寄存器提供了關于各通道傳輸狀態的具體信息,主要包括:
1、傳輸完成(TC):指示相應DMA通道是否已經完成所配置的數據傳輸任務。
2、半傳輸(HT):指示相應DMA通道是否已經完成一半的數據傳輸(對于某些應用可能需要在傳輸一半時進行處理)。
3、傳輸錯誤(TE):如果DMA通道在傳輸過程中遇到錯誤,該標志會被置位。
這些狀態可以用來觸發中斷服務程序(Interrupt Service Routines, ISRs), 允許軟件響應DMA傳輸的完成或錯誤。開發者通常會在對應的中斷處理函數中檢查這些狀態,以確定傳輸是否成功,或者是否需要采取措施來處理錯誤情況。

?
DMA的中斷服務程序是如何觸發的?

DMA的中斷服務程序(ISR)是通過設置DMA控制寄存器中的中斷使能位來觸發的。具體觸發步驟如下:
1、使能中斷:在初始化DMA時,你需要在DMA通道的控制寄存器(DMA_CCRx)中使能傳輸完成中斷、半完成中斷和/或傳輸錯誤中斷。
2、配置NVIC:在嵌套向量中斷控制器(NVIC)中,你需要為對應的DMA通道中斷配置優先級,并使能中斷。
3、中斷發生:
? ? ? ? a、當DMA傳輸完指定數量的數據后,如果啟用了傳輸完成中斷,DMA控制器將設置狀態寄存器(DMA_ISR)的傳輸完成標志(TC)。
? ? ? ?b、 如果啟用了半傳輸中斷,當傳輸完成一半的數據量時,DMA控制器將設置狀態寄存器的半傳輸完成標志(HT)。
? ? ? ? c、如果在傳輸過程中發生任何錯誤,如FIFO溢出或者總線錯誤等,DMA控制器將設置狀態寄存器的傳輸錯誤標志(TE)。
4、中斷處理:一旦相應的標志位被置位,如果NVIC中對應的中斷已使能,CPU將暫停當前任務,跳轉到對應的中斷服務程序執行中斷處理代碼。
5、中斷標志清除:在中斷服務程序中,需要手動清除DMA的狀態寄存器中的中斷標志位,以防止重復進入中斷服務程序。
通過以上步驟,STM32 中的DMA中斷服務程序可以在特定的事件發生時被觸發,以便進行如數據處理、錯誤處理等操作。

代碼演示

下面是一個簡單的STM32程序例子,用于演示如何使用DMA將數據從一個數組復制到另一個數組(內存到內存的DMA傳輸)

#include "stm32f4xx.h"
// 定義數組大小
#define ARRAYSIZE 5
// 定義源數組和目標數組
uint32_t srcArray[ARRAY_SIZE] = {1, 2, 3, 4, 5};
uint32_t destArray[ARRAY_SIZE] = {0, 0, 0, 0, 0};
void DMA_Config(void)
{// 手動使能DMA1時鐘RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);// 創建DMA初始化結構體并填入配置DMA_InitTypeDef DMA_InitStructure;DMA_DeInit(DMA1_Stream0);  // 將DMA Stream恢復到初始狀態DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&srcArray;  // 設置DMA源地址DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&destArray;    // 設置DMA目標地址DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;  // 設置內存到內存模式DMA_InitStructure.DMA_BufferSize = ARRAY_SIZE;  // 傳輸的數據大小DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;   // 外設地址遞增DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;   // 內存地址遞增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; // 32位數據寬度DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; // 32位數據寬度DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;   // 設置為正常模式DMA_InitStructure.DMA_Priority = DMA_Priority_Low; // 設置優先級為低DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;  // FIFO模式禁用DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; // FIFO閾值設置DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // 單次突發模式DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // 單次突發模式// 初始化DMADMA_Init(DMA1_Stream0, &DMA_InitStructure);// 使能DMA流DMA_Cmd(DMA1_Stream0, ENABLE);// 如果都是定期的規律的檢查傳輸狀態,可以留空這里// 如果你需要傳輸完成的通知,可能需要使用中斷和相應的服務函數
}
int main(void)
{// 系統初始化SystemInit();// 配置DMADMA_Config();// 在這里,我們假定系統只是簡單地執行一次內存到內存的復制// 復制完后,可以添加代碼檢查destArray數組中的值// 這里以簡單的檢查第一個元素是否等于1為例if (destArray[0] == 1){// 如果傳輸成功,將會進入到這里}// 主循環,程序可以繼續執行或者進入睡眠while (1){}
} 

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716302.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716302.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716302.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決Java并發問題的常見思路

寫在文章開頭 近期對一些比較老的項目進行代碼走查,碰到一些極端的并發編程惡習,所以筆者就基于此文演示這類問題以及面對并發編程時我們應該需要了解一些常見套路。 Hi,我是sharkChili,是個不斷在硬核技術上作死的java coder&am…

基于 Amazon EKS 的 Stable Diffusion ComfyUI 部署方案

01 背景介紹 Stable Diffusion 作為當下最流行的開源 AI 圖像生成模型在游戲行業有著廣泛的應用實踐,無論是 ToC 面向玩家的游戲社區場景,還是 ToB 面向游戲工作室的美術制作場景,都可以發揮很大的價值,如何更好地使用 Stable Dif…

scanf和cin的利弊

scanf和cin的利弊: scanf: 利:耗時短,寫法方便輸入固定格式,比如scanf(“%*d%d”,&a),可以直接忽略第一個輸入,不用創建新對象,再比如scanf(“%1d”,&x[i]),輸入3214&#x…

卡牌——二分

卡牌 題目分析 想一下前面題的特點,是不是都出現了“最大邊長”,“最小的數”這種字眼,那么這里出現了“最多能湊出多少套牌”,我們可以考慮用二分。接下來我們要看一下他是否符合二段性,二分的關鍵在于二段性。 第…

續Java的執行語句、方法--學習JavaEE的day07

day07 一、特殊的流程控制語句 break(day06) continue 1.理解: 作用于循環中,表示跳過循環體剩余的部分,進入到下一次循環 做實驗: while(true){ System.out.println(“111”); System.out.println(“222”); if(true){ conti…

編譯鏈接實戰(25)gcc ASAN、MSAN檢測內存越界、泄露、使用未初始化內存等內存相關錯誤

文章目錄 1 ASAN1.1 介紹1.2 原理編譯時插樁模塊運行時庫2 檢測示例2.1 內存越界2.2 內存泄露內存泄露檢測原理作用域外訪問2.3 使用已經釋放的內存2.4 將漏洞信息輸出文件3 MSAN1 ASAN 1.1 介紹 -fsanitize=address是一個編譯器選項,用于啟用AddressSanitizer(地址

基于SpringBoot的教師考勤管理系統(贈源碼)

作者主頁:易學蔚來-技術互助文末獲取源碼 簡介:Java領域優質創作者 Java項目、簡歷模板、學習資料、面試題庫 教師考勤管理系統是基于JavaVueSpringBootMySQL實現的,包含了管理員、學生、教師三類用戶。該系統實現了班級管理、課程安排、考勤…

基于springboot的足球俱樂部管理系統的設計與實現

** 🍅點贊收藏關注 → 私信領取本源代碼、數據庫🍅 本人在Java畢業設計領域有多年的經驗,陸續會更新更多優質的Java實戰項目希望你能有所收獲,少走一些彎路。🍅關注我不迷路🍅** 一 、設計說明 1.1 課題…

2024.3.3每日一題

LeetCode 用隊列實現棧 題目鏈接:225. 用隊列實現棧 - 力扣(LeetCode) 題目描述 請你僅使用兩個隊列實現一個后入先出(LIFO)的棧,并支持普通棧的全部四種操作(push、top、pop 和 empty&…

如何取消ChatGPT 4.0的自動續費和會員訂閱(chatgpt4.0自動續費嗎)

如何取消ChatGPT 4.0的自動續費和會員訂閱 ChatGPT 4.0自動續費是否存在 是的,ChatGPT 4.0 Plus會員服務存在自動續費功能。 ChatGPT 4.0 Plus會員服務自動續費 ChatGPT Plus會員服務的自動續費機制用戶在購買ChatGPT 4.0 Plus會員服務后,系統會自動…

npm ERR! code ERESOLVE

1、問題概述? 執行npm install命令的時候報錯如下: tangxiaochuntangxiaochundeMacBook-Pro stf % npm install npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resol…

LeetCode102.二叉樹的層序遍歷

題目 給你二叉樹的根節點 root ,返回其節點值的 層序遍歷 。 (即逐層地,從左到右訪問所有節點)。 示例 輸入:root [3,9,20,null,null,15,7] 輸出:[[3],[9,20],[15,7]]輸入:root [1] 輸出&am…

SpringCloud-MQ消息隊列

一、消息隊列介紹 MQ (MessageQueue) ,中文是消息隊列,字面來看就是存放消息的隊列。也就是事件驅動架構中的Broker。消息隊列是一種基于生產者-消費者模型的通信方式,通過在消息隊列中存放和傳遞消息,實現了不同組件、服務或系統…

2024全新手機軟件下載應用排行、平臺和最新發布網站,采用響應式織夢模板

這是一款簡潔藍色的手機軟件下載應用排行、平臺和最新發布網站,采用響應式織夢模板。 主要包括主頁、APP列表頁、APP詳情介紹頁、新聞資訊列表、新聞詳情頁、關于我們等模塊頁面。 地 址 : runruncode.com/php/19703.html 軟件程序演示圖:…

最小高度樹-力扣(Leetcode)

題目鏈接 最小高度樹 思路:本質上是找到樹中的最長路徑。當最長路徑上中間點(若路經長為偶數,則中間點僅有一個,否者中間點有兩個)作為根時,此時樹高最小。 Code: class Solution { public://拓撲排序int…

【深度優先搜索】【樹】【C++算法】2003. 每棵子樹內缺失的最小基因值

作者推薦 動態規劃的時間復雜度優化 本文涉及知識點 深度優先搜索 LeetCode2003. 每棵子樹內缺失的最小基因值 有一棵根節點為 0 的 家族樹 ,總共包含 n 個節點,節點編號為 0 到 n - 1 。給你一個下標從 0 開始的整數數組 parents ,其中…

第二講:用geth和以太坊交互

一:安裝geth brew install ethereum geth github網址: https://github.com/ethereum/go-ethereum 二: 用geth連接以太坊 以太坊有主網絡(Ethereum Mainnet),有測試網絡(Sepolia、Goerli 等等…

設計模式學習筆記 - 設計原則 - 5.依賴反轉原則(控制反轉、依賴反轉、依賴注入)

前言 今天學習 SOLID 中的最后一個原則,依賴反轉原則。 本章內容,可以帶著如下幾個問題: “依賴反轉” 這個概念指的是 “誰跟誰” 的 “什么依賴” 被反轉了? “反轉” 這兩個字該如何理解。我們還經常聽到另外兩個概念&#…

【分塊三維重建】【slam】LocalRF:逐步優化的局部輻射場魯棒視圖合成(CVPR 2023)

項目地址:https://localrf.github.io/ 題目:Progressively Optimized Local Radiance Fields for Robust View Synthesis 來源:KAIST、National Taiwan University、Meta 、University of Maryland, College Park 提示:文章用了s…

【Spring】20 解析Spring注解驅動的容器配置

文章目錄 注解 vs. XMLJavaConfig選項注解配置注解注入順序注解處理器實際運用總結 Spring 框架一直以 XML 配置為主導,然而隨著注解驅動配置的引入,我們不禁思考:是注解配置優于 XML 呢,還是反之?本篇博客將介紹 Spri…