日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 嵌入式 > 嵌入式分享
[導(dǎo)讀]在嵌入式系統(tǒng)開發(fā)中,DMA(直接內(nèi)存訪問)控制器作為硬件加速的核心模塊,通過獨立于CPU的數(shù)據(jù)搬運能力顯著提升系統(tǒng)性能。以STM32H7系列為例,其雙DMA控制器(各含8通道)可實現(xiàn)高達(dá)480MHz總線頻率下的數(shù)據(jù)傳輸,本文將系統(tǒng)解析DMA寄存器配置的全流程。


在嵌入式系統(tǒng)開發(fā)中,DMA(直接內(nèi)存訪問)控制器作為硬件加速的核心模塊,通過獨立于CPU的數(shù)據(jù)搬運能力顯著提升系統(tǒng)性能。以STM32H7系列為例,其雙DMA控制器(各含8通道)可實現(xiàn)高達(dá)480MHz總線頻率下的數(shù)據(jù)傳輸,本文將系統(tǒng)解析DMA寄存器配置的全流程。


一、硬件架構(gòu)與初始化

DMA控制器由地址總線、數(shù)據(jù)總線和控制寄存器構(gòu)成,其初始化需完成三步操作:


時鐘使能

通過RCC(復(fù)位和時鐘控制)寄存器激活DMA時鐘:

c

__HAL_RCC_DMA1_CLK_ENABLE();  // 啟用DMA1時鐘

HAL_Delay(1);                 // 等待時鐘穩(wěn)定

通道復(fù)位

清除通道歷史配置,避免殘留狀態(tài)干擾:

c

DMA_HandleTypeDef hdma;

hdma.Instance = DMA1_Stream0;  // 選擇DMA1的Stream0

HAL_DMA_DeInit(&hdma);         // 復(fù)位通道

優(yōu)先級仲裁

通過仲裁器寄存器設(shè)置通道優(yōu)先級(軟件階段),STM32H7支持四級優(yōu)先級(VERY_HIGH/HIGH/MEDIUM/LOW):

c

hdma.Init.Priority = DMA_PRIORITY_HIGH;  // 設(shè)置高優(yōu)先級

二、核心傳輸參數(shù)配置

傳輸規(guī)則通過六組關(guān)鍵寄存器定義:


方向與地址模式

c

hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;  // 內(nèi)存→外設(shè)

hdma.Init.PeriphInc = DMA_PINC_DISABLE;       // 外設(shè)地址固定

hdma.Init.MemInc = DMA_MINC_ENABLE;           // 內(nèi)存地址自增

數(shù)據(jù)對齊與突發(fā)傳輸

c

hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;  // 外設(shè)32位

hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;      // 內(nèi)存32位

hdma.Init.FIFOMode = DMA_FIFOMODE_ENABLE;             // 啟用FIFO

hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;    // 滿閾值觸發(fā)

傳輸模式與中斷

c

hdma.Init.Mode = DMA_CIRCULAR;  // 循環(huán)模式(持續(xù)傳輸)

__HAL_DMA_ENABLE_IT(&hdma, DMA_IT_TC);  // 啟用傳輸完成中斷

三、地址與數(shù)據(jù)量配置

綁定外設(shè)與內(nèi)存地址

c

hdma.Init.PeriphBaseAddr = (uint32_t)&SPI4->DR;  // SPI4數(shù)據(jù)寄存器

hdma.Init.Mem0BaseAddr = (uint32_t)display_buffer; // 顯示緩沖區(qū)

設(shè)置傳輸數(shù)據(jù)量

c

#define BUFFER_SIZE 1024  // 1024個32位數(shù)據(jù)

hdma.Init.NDTR = BUFFER_SIZE;  // 數(shù)據(jù)項數(shù)量

四、外設(shè)請求綁定與啟動

關(guān)聯(lián)DMA請求源

通過DMAMUX(DMA請求多路復(fù)用器)綁定外設(shè):

c

HAL_DMAEx_ConfigMuxRequest(&hdma, DMA_REQUEST_SPI4_TX);  // 綁定SPI4發(fā)送請求

初始化與啟動

c

HAL_DMA_Init(&hdma);                     // 初始化DMA

__HAL_LINKDMA(&hspi4, hdmatx, hdma);      // 關(guān)聯(lián)SPI與DMA

HAL_SPI_Start_DMA(&hspi4, display_buffer, BUFFER_SIZE);  // 啟動SPI+DMA

五、中斷處理與狀態(tài)監(jiān)控

中斷服務(wù)例程

c

void DMA1_Stream0_IRQHandler(void) {

 HAL_DMA_IRQHandler(&hdma);  // 調(diào)用HAL庫處理中斷

}

傳輸狀態(tài)查詢

c

if (HAL_DMA_GetState(&hdma) == HAL_DMA_STATE_BUSY) {

 uint32_t remaining = __HAL_DMA_GET_COUNTER(&hdma);  // 剩余數(shù)據(jù)量

 printf("Remaining: %lu\n", remaining);

}

六、性能優(yōu)化實踐

地址對齊優(yōu)化

確保內(nèi)存緩沖區(qū)地址為4字節(jié)對齊(如__attribute__((aligned(4)))),避免總線錯誤。

突發(fā)傳輸配置

設(shè)置FIFOThreshold為DMA_FIFO_THRESHOLD_1QUARTERFULL,當(dāng)FIFO積累4個數(shù)據(jù)時觸發(fā)傳輸,減少總線占用。

雙緩沖機(jī)制

通過交替使用兩個緩沖區(qū)實現(xiàn)無縫傳輸,避免屏幕撕裂:

c

HAL_SPI_Start_DMA(&hspi4, buffer1, BUFFER_SIZE);  // 啟動第一緩沖區(qū)

// 在中斷中切換緩沖區(qū)

void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) {

 static uint8_t toggle = 0;

 toggle ^= 1;

 HAL_SPI_Start_DMA(hspi, toggle ? buffer2 : buffer1, BUFFER_SIZE);

}

七、典型應(yīng)用場景

在STM32H7驅(qū)動ST7789V顯示屏的案例中,DMA實現(xiàn)每秒60幀的240x320像素刷新,CPU占用率從45%降至8%。關(guān)鍵配置包括:


使用TCM RAM存儲顯示緩沖區(qū),減少總線競爭

啟用SPI TX FIFO(32字節(jié)深度)緩沖數(shù)據(jù)

配置DMA突發(fā)傳輸為4字節(jié)(INCR4)

通過系統(tǒng)化的寄存器配置與優(yōu)化策略,DMA控制器可成為嵌入式系統(tǒng)性能提升的核心引擎,為實時數(shù)據(jù)處理、高速通信等場景提供硬件級加速支持。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀
關(guān)閉