You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32 H735 HAL库SPI4 DMA发送数据未更新问题求助

STM32H735 SPI4 DMA传输数据无法更新问题解决

问题核心原因

STM32H735搭载Cortex-M7内核,带有L1数据缓存(DCache)。你将DMA缓冲区放在D2区域RAM后,CPU修改数据时可能仅写入Cache而未同步到物理RAM,而DMA直接访问物理RAM,导致读取到旧数据。添加NOP延迟能偶然生效是因为Cache在这段时间内自动完成了同步,但这不是可靠的解决方案。

可靠解决方案

方案1:手动刷新数据缓存

在修改完DMA缓冲区数据后,主动将Cache中的数据同步到物理RAM,确保DMA能读取到最新值。代码示例:

// 修改DMA缓冲区数据
ToTheDac.Dac = 0x34;
ToTheDac.Data[0] = (dac1 >> 8) & 0xff;
ToTheDac.Data[1] = dac1 & 0xff;

// 计算缓存对齐的起始地址和长度(H7的Cache行是32字节,需确保地址、长度对齐)
uint32_t buf_addr = (uint32_t)&ToTheDac;
uint32_t aligned_addr = buf_addr & ~(31UL);
uint32_t aligned_size = ((buf_addr + sizeof(DACOUTPUT) - aligned_addr) + 31UL) & ~(31UL);

// 清理数据缓存,将Cache内容同步到物理RAM
SCB_CleanDCache_by_Addr((uint32_t*)aligned_addr, aligned_size);

// 发起DMA传输
HAL_SPI_Transmit_DMA(&hspi4, (uint8_t*)&ToTheDac, sizeof(ToTheDac));

方案2:配置缓冲区所在内存为非缓存区

通过MPU(内存保护单元)将.spi_data所在的D2区域配置为Non-Cacheable,这样CPU读写直接操作物理RAM,无需手动刷新Cache。初始化时添加MPU配置代码:

void MPU_Config(void)
{
    MPU_Region_InitTypeDef MPU_InitStruct = {0};

    // 先禁用MPU
    HAL_MPU_Disable();

    // 配置DMA缓冲区所在区域为非缓存
    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER0;
    MPU_InitStruct.BaseAddress = (uint32_t)&ToTheDac; // 直接绑定缓冲区地址
    MPU_InitStruct.Size = MPU_REGION_SIZE_32B; // 32字节足够覆盖你的结构体
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    // 重新启用MPU
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

在main()函数开头调用MPU_Config()即可,之后修改缓冲区数据无需额外刷新操作。

额外注意事项

  • 确保每次发起DMA传输前,上一次传输已经完成,避免数据冲突:
    if (HAL_SPI_STATE_READY == hspi4.State)
    {
        // 修改数据 + 刷新缓存(如果用方案1)
        // ...
        HAL_SPI_Transmit_DMA(&hspi4, (uint8_t*)&ToTheDac, sizeof(ToTheDac));
    }
    
  • 链接脚本中RAM_D2的定义要确保对应正确的D2区域RAM(如SRAM1/SRAM2),避免配置错误。

内容的提问来源于stack exchange,提问作者user2144480

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:07:47