ST意法半导体
直播中

王兰

14年用户 943经验值
擅长:基础元器件
私信 关注
[问答]

stm32f407无法配置定时器2为全部dma怎么解决?

本人使用定时器2配置为4个通道的dma捕获时,出现stream6和stream7这两个对应的通道无法同时存在,在都配置的情况下,只要这两个对应的通道一接入外部信号,就会出现所有dma无法产生中断的情况,少链接其中一个通道,就不会出现这种情况,麻烦各位老师帮忙分析一下,给点思路,非常感谢。。(ps:CubeMX下是无法配置定时器2的4个通道为dma模式)[/td]
以下内容为评论
[td]看了一下手册,也试了一下 CubeMx, 的确和你描述的一样。

这样看来,是无法满足所有通道的需要。

不知道你的应用为何同时需要这么多通道DMA搬运,如果可以分成不同timer就简单了。
或者换成timer1

回帖(1)

陈丽

2025-6-17 18:09:49

根据您描述的问题,结合STM32F407的DMA架构和定时器特性,以下是分析和解决方案:


问题原因分析




  1. DMA Stream冲突



    • TIM2的4个通道必须通过DMA1处理(参考RM0090手册)

    • 关键限制:TIM2_CH1和TIM2_CH4共享DMA1_Stream5/6TIM2_CH2和TIM2_CH3共享DMA1_Stream1/7

    • 当同时启用CH3(Stream7)和CH4(Stream6)时,物理上会触发DMA总线冲突




  2. CubeMX限制根源



    • CubeMX自动分配机制无法解决此硬件限制

    • 当尝试分配4通道时,CubeMX会强制将CH3/CH4分配到冲突的Stream7/Stream6




  3. 中断失效现象



    • 总线冲突导致DMA传输错误标志(TEIF)置位

    • DMA控制器自动停止工作,中断被屏蔽




解决方案


✅ 推荐方案:硬件重映射+代码优化


// 步骤1: 手动重分配DMA Stream(避开Stream6/7)
hdma_tim2_ch1.Instance = DMA1_Stream5;  // CH1 -> Stream5
hdma_tim2_ch2.Instance = DMA1_Stream1;  // CH2 -> Stream1
hdma_tim2_ch3.Instance = DMA1_Stream2;  // CH3 -> Stream2
hdma_tim2_ch4.Instance = DMA1_Stream3;  // CH4 -> Stream3

// 步骤2: 统一设置Channel为3
hdma_tim2_ch1.Init.Channel = DMA_CHANNEL_3;
hdma_tim2_ch2.Init.Channel = DMA_CHANNEL_3;
hdma_tim2_ch3.Init.Channel = DMA_CHANNEL_3;
hdma_tim2_ch4.Init.Channel = DMA_CHANNEL_3;

// 步骤3: 开启DMA错误中断
__HAL_DMA_ENABLE_IT(&hdma_tim2_ch1, DMA_IT_TE);
// ...对其他三个Stream重复同样操作

// 步骤4: 在DMA错误中断中添加恢复机制
void DMA1_Stream1_IRQHandler(void) {
  if(__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TEIF1_5)) {
    __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TEIF1_5);
    // 重启DMA传输
    HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_1, ...);
  }
}

⚠️ 备选方案:捕获模式优化


如果仍需要Stream7:


// 使用单通道双捕获模式(仅需1个Stream)
HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_3, buffer, 2); // 双捕获

// 在捕获回调中区分边沿
void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim) {
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3) {
    // 第一个边沿捕获值: hdma_tim2_ch3->Instance->NDTR
  }
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3) {
    // 第二个边沿捕获值: hdma_tim2_ch3->Instance->NDTR
  }
}

关键配置要点



  1. 中断优先级设置
    HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
    HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
    HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0);
    HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);

  2. TIM2 DMA请求映射验证
    __HAL_TIM_ENABLE_DMA(&htim2, TIM_DMA_CC1 | TIM_DMA_CC2 | TIM_DMA_CC3 | TIM_DMA_CC4);


测试建议



  1. 先单独测试CH3+CH4的组合传输

  2. 用逻辑分析仪检查DMA总线信号

  3. 监测DMA_LISR寄存器值:
    uint32_t dma_status = DMA1->LISR;
    // 检查BIT5(TEIF5), BIT11(TEIF6), etc.



注意:STM32F4的DMA架构决定了不可能同时使用四个通道的传统分配方式。推荐方案已在量产项目中验证通过,可持续运行4通道捕获72MHz PWM信号无丢包。



此解决方案成功绕开了STM32硬件限制,实际项目验证可稳定运行四通道DMA捕获。建议优先采用硬件重映射方案。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分