打印
[其他ST产品]

STM32 TIM DMA burst 输出变频 PWM 波形

[复制链接]
718|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ST, RS, PWM, DMA, DM
问题背景
客户需要 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 访问此寄存器

使用特权

评论回复
沙发
原来是wjc|  楼主 | 2024-4-10 23:48 | 只看该作者
产生 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} ;
1
2
即输出 3 个 pulse1 的脉冲后,再输出 2 个 pulse2 脉冲,这样交替输出。

使用特权

评论回复
板凳
原来是wjc|  楼主 | 2024-4-10 23:48 | 只看该作者
TIM 与 GPDMA 配置
3.1.1. TIM1 配置
TIM1 配置如下,使能寄存器预装载功能。

图1.TIM1 配置

使用特权

评论回复
地板
原来是wjc|  楼主 | 2024-4-10 23:49 | 只看该作者
GPDMA 配置
使用 GPDMA 通道 12 的 linked list 模式,并配置为循环模式:

图2.GPDMA 配置

使用特权

评论回复
5
原来是wjc|  楼主 | 2024-4-10 23:50 | 只看该作者
Linked List 配置中,创建一个 list queue,并添加两个 list node,选择 GPDMA 来执行此 list queue,同样配置为循环模式,指定循环起始节点为 TN1,如下图。

图3.Linked List 配置 Linked List 节点配置中,使用 TIM1 update 事件来产生 DMA 请求,指定 DMA 目的地址为 TIMx_DMAR 寄存器,源地址为 pulse1 数组地址。TN2 只需将 pulse1 修改为 pulse2即可。

使用特权

评论回复
6
原来是wjc|  楼主 | 2024-4-10 23:50 | 只看该作者
图4.Linked List Node 配置

使用特权

评论回复
7
原来是wjc|  楼主 | 2024-4-10 23:50 | 只看该作者
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);

使用特权

评论回复
8
原来是wjc|  楼主 | 2024-4-10 23:50 | 只看该作者
测试结果
测试结果如下图,可以看到两个频率的 PWM 波形交替输出,且脉冲个数也符合需求:

图5.PWM 波形输出

使用特权

评论回复
9
原来是wjc|  楼主 | 2024-4-10 23:51 | 只看该作者
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 功能

使用特权

评论回复
10
原来是wjc|  楼主 | 2024-4-10 23:51 | 只看该作者
图7.GPDMA 通道 2D 寻址配置

使用特权

评论回复
11
原来是wjc|  楼主 | 2024-4-10 23:51 | 只看该作者
配置 TIM2
配置 TIM2 CH1 输出 PWM,使用 PA5 引脚:

图8.TIM2 配置

使用特权

评论回复
12
原来是wjc|  楼主 | 2024-4-10 23:51 | 只看该作者
修改代码
在 CubeMX 生成代码后,修改 pulse1/pulse2 的值,将 TIM2 与 DMA 通道绑定,并配置 TIMx_DCR 寄存器,这样也可实现两个频率,不同脉冲个数 PWM 交替输出的需求。

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

使用特权

评论回复
13
原来是wjc|  楼主 | 2024-4-10 23:51 | 只看该作者
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);

使用特权

评论回复
14
原来是wjc|  楼主 | 2024-4-10 23:52 | 只看该作者
小结
使用 TIM DMA burst 功能,结合 STM32U5 的 GPDMA Linked list 模式及 2D 寻址特性,能灵活的输出 PWM 波形满足客户需求。

文档中所用到的工具及版本
1,STM32CubeMX 6.6.1
2,IAR 9.20.2

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

76

主题

978

帖子

0

粉丝