当将 s_tim_dma 数组从 const 常量改为普通变量数组时,DMA 突发传输功能异常的根本原因是:变量数组被存储在 DMA 无法访问的内存区域(如 DTCM)或缓存(Cache)一致性未正确处理。
const 数组存储在 Flash 中(默认可被 DMA 访问)。 printf("Array address: 0x%pn", s_tim_dma);0x2000_0000–0x2001_FFFF → 位于 DTCM(问题所在)。__attribute__((section(".dma_buffer"))) uint32_t s_tim_dma[] = {1600, 0, 500};在链接脚本(*.ld)中创建段并映射到 AXI SRAM:
.dma_buffer :
{
*(.dma_buffer)
} > RAM_D1 /* 0x24000000 (AXI SRAM) */#include "stm32h7xx_hal.h"
SCB_CleanDCache_by_Addr((uint32_t*)s_tim_dma, sizeof(s_tim_dma));0b00)。 if ((uint32_t)s_tim_dma & 0x3) {
printf("Unaligned address!n");
}__ALIGNED(4) uint32_t s_tim_dma[] = {1600, 0, 500};#include "stm32h7xx_hal.h"
// 指定存储区域 + 对齐 + Cache处理
__attribute__((section(".dma_buffer"))) __ALIGNED(4) uint32_t s_tim_dma[] = {1600, 0, 500};
void Start_DMA_Transfer(void) {
// 1. 清理Cache确保数据写入物理内存
SCB_CleanDCache_by_Addr((uint32_t*)s_tim_dma, sizeof(s_tim_dma));
// 2. 配置并启动DMA
HAL_DMA_Start_IT(&hdma_tim, (uint32_t)s_tim_dma, (uint32_t)&TIM8->DMAR, 3);
}.dma_buffer 或类似的自定义段映射到 DMA 可访问内存(如 RAM_D1/AXI SRAM)。main() 中临时禁用 Cache 测试:SCB_DisableDCache();TIM8->DMAR 是否正确。| 问题原因 | 解决方案 |
|---|---|
| 数组位于 DTCM(DMA 不可访问) | 重定位到 AXI/SRAM(使用 section 属性) |
| Cache 未更新到内存 | 启动 DMA 前调用 SCB_CleanDCache_by_Addr |
| 地址未对齐 | 使用 __ALIGNED(4) 确保 32 位对齐 |
通过上述方法,即可解决 DMA 传输异常问题,并保证变量数组的正常传输。
举报
更多回帖