文章目錄
- 前言
- 一、使用開發板燒錄dma代碼不生效問題
- 二、一個工程同時使用uart2、uart3借助dma來傳遞
- 1.并行。
- 2.DMA "同時工作"的本質
- 3.總線訪問的具體含義
- 4.實際效果
- 5.最佳實踐
- 5.1 總線傳輸機制:
- 6.DMA傳輸中斷的問題
- 總結
前言
記錄一些使用stm32f4 dma過程中的疑問和一些問題
一、使用開發板燒錄dma代碼不生效問題
參考正點原子的實驗18進行的測試。原版是dma2 uart1
我想改為dma1 uart2
用的新版的stlink(可以供電。。)
同時連接電源、stlink,typec-usb線
我發現燒錄程序后,打開串口調試助手沒有用(即沒有顯示信息)
一開始是有的,后期沒了,特別是改完dma1 uart2之后一直以為自己沒改對。。。
我把stlink拔掉然后重新上下點就開始哐哐收數據了。。。。
在此記錄一下
二、一個工程同時使用uart2、uart3借助dma來傳遞
新手的問題:同時使用dma來傳遞uart2、uart3會不會導致只節省一半的時間(比如使用uart2發送數據不占用CPU時間了,但是uart3還得等地啊uart2這邊發送完之后在重新弄這個過程。)
1.并行。
DMA1 資源分配(STM32F4)
- UART2 TX: DMA1 Stream6(通道4)
- UART3 TX: DMA1 Stream3(通道4)
同時傳輸時的行為:
-
并行傳輸能力:
- DMA1 有8個獨立的數據流(Stream0-7)
- 不同流可以同時工作(如 UART2 TX 用 Stream6,UART3 TX 用 Stream3)
- 實際總線訪問由 DMA 仲裁器調度(基于優先級)
-
沖突場景:
-
如果兩個外設使用同一個流(如 UART2 TX 和 UART3 TX 都嘗試用 Stream6)
-
如果同時訪問相同內存區域(需確保源/目標地址不重疊)
-
2.DMA "同時工作"的本質
-
邏輯層面的并行:
-
不同DMA流可以獨立配置和啟動
-
它們可以同時處于激活狀態
-
從程序員角度看,它們"同時工作"
-
-
物理層面的仲裁:
-
所有DMA流共享相同的總線資源(AHB總線矩陣)
-
當多個流同時請求總線訪問時,仲裁器決定訪問順序
-
實際數據傳輸是分時復用總線資源的
-
3.總線訪問的具體含義
-
總線類型:
-
AHB總線:連接CPU、DMA、內存控制器
-
APB總線:連接低速外設(如UART)
-
DMA需要在AHB總線上讀取內存,在APB總線上寫入外設
-
-
訪問過程示例:
// UART2 TX傳輸(Stream6)
DMA1_Stream6->M0AR = (uint32_t)tx_buf; // 內存地址
DMA1_Stream6->PAR = (uint32_t)&USART2->DR; // 外設地址
每次傳輸需要:1.通過AHB總線從內存讀取數據2.通過APB總線將數據寫入UART數據寄存器
4.實際效果
-
對于UART這種慢速外設(115200bps ≈ 11.5KB/s)
-
DMA傳輸速度(STM32F4 @168MHz > 100MB/s)
-
即使有仲裁,多個UART的DMA傳輸在人類時間尺度上看起來是同時的
對于UART DMA傳輸,即使有總線仲裁,不同流的傳輸在實際應用中可以認為是并行工作的,因為仲裁產生的延遲遠小于UART傳輸一個字節的時間(87μs@115200bps)。
5.最佳實踐
-
優先級配置:
對實時性要求高的外設設高優先級 -
避免總線擁塞:
-
將DMA源/目標緩沖區放在不同內存塊
SRAM1/SRAM2分開使用
-
使用內存對齊訪問
__attribute__((aligned(4))) uint8_t buf1[256]; __attribute__((aligned(4))) uint8_t buf2[256];
-
5.1 總線傳輸機制:
-
STM32的總線系統(AHB/APB)以32位字為基本傳輸單位
-
每次總線訪問至少傳輸4字節
-
非對齊訪問會導致多次總線事務
6.DMA傳輸中斷的問題
DMA_SxCR_TCIE 中斷表示:DMA控制器已經將數據從內存傳輸到UART的數據寄存器(DR),而不是UART已經將數據完全發送出去。
詳細過程分解
-
DMA傳輸完成:
-
DMA將最后一個字節寫入USARTx->DR寄存器
-
DMA控制器設置傳輸完成標志(TCIF)
-
觸發DMA傳輸完成中斷
-
-
UART發送過程:
-
UART將數據從DR寄存器轉移到發送移位寄存器
-
UART按波特率將數據逐位發送到TX引腳
-這個物理發送過程需要時間(例如115200bps下,1字節約需87μs)
-
總結
xxx