STM32 TIM DMA burst 输出变频 PWM 波形

admin2024-04-03  4

1. 问题背景

客户需要 MCU 输出一组变频的 PWM 波形来控制外围器件,并且不同频率脉冲的个数也不同。STM32U5 芯片拥有 TIM1/TIM8 高级定时器,还有通用定时器TIM2/TIM3/TIM4/TIM5 以及 TIM15/TIM16/TIM17。TIM 模块中,可通过修改 ARR 寄存器的值来修改 PWM 的频率。如果使用 TIM1/TIM8 或者 TIM15/TIM16/TIM17,则可以通过修改 RCR 与 CCR 寄存器,来控制脉冲个数及占空比。由于要同时修改多个 TIM 寄存器,需要使用 TIM 的 DMA burst 功能来实现此需求。

2. TIM DMA burst

STM32 片内部分 TIMER 在产生单个定时器事件情况下可以基于特定硬件机制触发多个 DMA 请求,这样产生多个连续的 DMA 传输来实现对多个 TIMER 寄存器的批量访问。

这就是所谓的 TIM DMA burst 功能,这里有两个专用寄存器:

  • TIMx_DCR :
  • DBSS : 触发 DMA burst 的事件源
  • DBL : DMA burst 传输个数
  • DBA : DMA burst 传输的 TIM 寄存器基地址索引
  • TIMx_DMAR :
  • TIM DMA Burst 时,DMA 访问此寄存器

3. 产生 PWM

本文使用 TIM1 来产生 PWM,在 U575 NECLEO 板上测试,MCU 主频为 100MHz。
使用两个频率分别对应 TIM 寄存器组的值如下:ARR/ RCR/ CCR1

uint32_t pulse1[3] = {1000, 2, 500} ;
uint32_t pulse2[3] = {5000, 1, 2500} ;

即输出 3 个 pulse1 的脉冲后,再输出 2 个 pulse2 脉冲,这样交替输出。

3.1. TIM 与 GPDMA 配置

3.1.1. TIM1 配置

TIM1 配置如下,使能寄存器预装载功能。

图1.TIM1 配置
STM32 TIM DMA burst 输出变频 PWM 波形,在这里插入图片描述,第1张

3.1.2. GPDMA 配置

使用 GPDMA 通道 12 的 linked list 模式,并配置为循环模式:

图2.GPDMA 配置
STM32 TIM DMA burst 输出变频 PWM 波形,在这里插入图片描述,第2张
Linked List 配置中,创建一个 list queue,并添加两个 list node,选择 GPDMA 来执行此 list queue,同样配置为循环模式,指定循环起始节点为 TN1,如下图。

图3.Linked List 配置
STM32 TIM DMA burst 输出变频 PWM 波形,在这里插入图片描述,第3张
Linked List 节点配置中,使用 TIM1 update 事件来产生 DMA 请求,指定 DMA 目的地址为 TIMx_DMAR 寄存器,源地址为 pulse1 数组地址。TN2 只需将 pulse1 修改为 pulse2即可。

图4.Linked List Node 配置
STM32 TIM DMA burst 输出变频 PWM 波形,在这里插入图片描述,第4张

3.1.3. TIMx_DCR 寄存器配置

在 CubeMX 生成代码后,添加以下代码,将 TIM 与 DMA 通道绑定,并配置TIMx_DCR 寄存器:

MX_TQ1_Config();
 /* Link created queue to DMA channel #######################################*/
 if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel12, &TQ1) != HAL_OK)
 {
 	Error_Handler();
 }
 
 __HAL_LINKDMA(&htim1, hdma[TIM_DMA_ID_CC1], handle_GPDMA1_Channel12);
 __HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE);
 HAL_DMAEx_List_Start_IT(&handle_GPDMA1_Channel12);
 
 // update 事件触发 DMA burst
// 3 个 DMA transfer,分别修改 ARR/ RCR/ CCR1 寄存器
 // TIM 寄存器作为基地址的索引,ARR 寄存器索引为 11
 htim1.Instance->DCR = (1<<16) | ((3-1)<<8) | (11<<0);
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

3.1.4. 测试结果

测试结果如下图,可以看到两个频率的 PWM 波形交替输出,且脉冲个数也符合需求:

图5.PWM 波形输出
STM32 TIM DMA burst 输出变频 PWM 波形,在这里插入图片描述,第5张

3.2. TIM 无 RCR 寄存器情况

3.2.1. TIM2/TIM3/TIM4/TIM5 无 RCR 寄存器

当使用的 TIM 无 RCR 寄存器时,上述方式无法配置每个频率的 PWM 脉冲个数。而在U5 系列上,GPDMA 的 12-15 通道具有 2D 寻址能力,同时也有 repeat 功能。利用repeat 特性同样可以实现上述需求,下面以 TIM2 为例。

在前面配置基础上,使能 DMA 通道的 2D 功能,并添加 2D 寻址配置:

图6.GPDMA 通道 2D 功能
STM32 TIM DMA burst 输出变频 PWM 波形,在这里插入图片描述,第6张
图7.GPDMA 通道 2D 寻址配置
STM32 TIM DMA burst 输出变频 PWM 波形,在这里插入图片描述,第7张

3.2.2. 配置 TIM2

配置 TIM2 CH1 输出 PWM,使用 PA5 引脚:

图8.TIM2 配置
STM32 TIM DMA burst 输出变频 PWM 波形,在这里插入图片描述,第8张

3.2.3. 修改代码

在 CubeMX 生成代码后,修改 pulse1/pulse2 的值,将 TIM2 与 DMA 通道绑定,并配置 TIMx_DCR 寄存器,这样也可实现两个频率,不同脉冲个数 PWM 交替输出的需求。

uint32_t pulse1[3] = {1000, 0, 500};
uint32_t pulse2[3] = {5000, 0, 2500};
MX_TQ1_Config();
 /* Link created queue to DMA channel #######################################*/
 if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel12, &TQ1) != HAL_OK)
 {
 	Error_Handler();
 }
 
 __HAL_LINKDMA(&htim2, hdma[TIM_DMA_ID_CC1], handle_GPDMA1_Channel12);
 __HAL_TIM_ENABLE_DMA(&htim2, TIM_DMA_UPDATE);
 HAL_DMAEx_List_Start_IT(&handle_GPDMA1_Channel12);
 
 // update 事件触发 DMA burst
// 3 个 DMA transfer,分别修改 ARR/ CCR1 寄存器,RCR 寄存器值被忽略
 // TIM 寄存器作为基地址的索引,ARR 寄存器索引为 11
 htim2.Instance->DCR = (1<<16) | ((3-1)<<8) | (11<<0);
 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

4. 小结

使用 TIM DMA burst 功能,结合 STM32U5 的 GPDMA Linked list 模式及 2D 寻址特性,能灵活的输出 PWM 波形满足客户需求。

文档中所用到的工具及版本

1,STM32CubeMX 6.6.1
2,IAR 9.20.2


本文档参考ST官方的《【应用笔记】LAT1202+TIM+DMA+burst+输出变频+PWM+波形》文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!