扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

STM32U5 Timer+GPDMA 2D 通道实现多波形交替输出 实操方案与优化

03/31 14:58
217
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

工业控制、信号发生等嵌入式开发场景中,常遇到需要 MCU 输出正弦波、固定电平等多种波形并实现交替切换的需求,但若 MCU 内置 DAC 资源不足,可采用PWM + 滤波的方式模拟生成模拟波形。传统方案需使用两个 Timer(一个输出 PWM,一个定时切换波形),而 STM32U5 系列的 GPDMA(通用 DMA)12-15 通道自带2D addressing/Repeat专属功能,配合 Linked List 链表模式,仅需单 Timer + 单 GPDMA 2D 通道即可实现多波形的自动交替输出,不仅节省外设资源,还能实现硬件级的平滑切换,无需 CPU 干预。本文基于 ST 官方 LAT1189 应用笔记,以 STM32U575 NUCLEO 开发板为测试平台,从原理、配置、代码、实测四个维度,详解该方案的实操实现与灵活拓展。

资料获取:【应用笔记】LAT1189 Timer结合DMA 2D通道实现不同波形输出

1. 方案核心原理:PWM 滤波 + GPDMA 2D 硬件功能

本方案的核心是高频 PWM 脉宽实时调整模拟波形+GPDMA 2D 通道的硬件级数据传输与切换,替代传统软件或双 Timer 的切换方式,先明确核心实现逻辑与测试基础参数。

1.1 PWM + 滤波生成模拟波形的基础逻辑

DAC 资源不足时,通过调整 PWM 脉宽的连续序列模拟模拟波形的幅值变化,再经外部无源滤波电路滤除 PWM 高频载波,即可得到平滑的模拟波形:

  • 正弦波:按正弦波幅值变化规律,设置一组连续的 PWM 脉宽值,按顺序循环输出,滤波后还原正弦波;
  • 固定电平:输出等脉宽的 PWM 波,滤波后得到稳定的直流电平。

本次测试的核心参数(基于 STM32U575,主频 100MHz):

  • PWM 频率:2MHz(周期 500ns),脉宽可调范围 0~50 个计数时钟;
  • 正弦波:1 个周期 10us,对应 20 个 PWM 脉冲,脉宽序列为 [25,33,40,45,49,50,49,45,40,33,25,17,10,5,1,0,1,5,10,17];
  • 波形时长:正弦波序列重复 1000 次,对应 10ms 连续正弦波,后自动切换为固定电平,循环交替。

1.2 GPDMA 2D 通道的专属核心功能

STM32U5 的 GPDMA 共 16 个独立通道,仅 12-15 通道支持 2D addressing/Repeat 功能,搭配 Linked List 链表模式,完美适配多波形交替需求,三个核心功能相互配合:

  • 2D addressing(2D 寻址):完成一次指定长度的块数据传输后,源地址自动回滚至数组起点,无需软件重新配置,实现单波形脉宽序列的循环传输;
  • Repeat(重复传输):可设置块传输的重复次数,精准控制单个波形的持续时长(如本次设置 1000 次,对应 10ms 正弦波);
  • Linked List(链表模式):创建多个波形传输节点(如正弦波节点、固定电平节点),配置为循环模式后,节点可按顺序自动切换,实现多波形的硬件级交替输出,无软件延时。

1.3 整体工作流程

TIM1 输出 2MHz PWM,其更新事件作为 GPDMA 的触发信号;每次 TIM1 更新,GPDMA 从内存脉宽数组中读取一个值,写入 TIM1 的 CCR1 寄存器(PWM 脉宽控制寄存器),实现 PWM 脉宽的实时调整;GPDMA 按链表节点配置,先重复 1000 次正弦波脉宽传输,再自动切换至固定电平脉宽传输,循环往复,最终经滤波得到正弦波与固定电平交替的模拟波形。

2. CubeMX 实操配置:三步完成核心外设配置

基于 STM32CubeMX 生成测试工程,核心配置TIM1 CH1 PWM、GPDMA CH12 2D 通道、Linked List 链表三部分,所有配置均为图形化操作,无需手动修改寄存器,步骤可复现。

前提准备

新建 STM32U575ZGQx 工程,配置系统时钟为 100MHz,开启 ICACHE/DCACHE(提升内存访问效率,保证 DMA 传输速率),配置系统电源管理为正常模式。

步骤 1:TIM1 CH1 PWM 核心配置

TIM1 作为 PWM 输出核心,配置为向上计数、PWM 模式 1,参数与测试需求严格匹配,关键配置如下:

  1. 模式选择:Channel1 PWM Generation CH1,时钟源为内部时钟;
  2. 计数器设置:Prescaler(预分频)=0,Counter Period(自动重装值)=50,Counter Mode=Up(向上计数);
    • 计算逻辑:TIM1 时钟 = 系统主频 = 100MHz,预分频 0 则计数时钟 100MHz,PWM 周期 = 50/100MHz=500ns,频率 = 2MHz,完美匹配测试需求;
  3. PWM 配置:PWM Mode=PWM mode1,Output Compare Preload=Disable(禁用输出比较预加载),Fast Mode=Disable;
  4. 其他:Repetition Counter=0,Break And Dead Time=Disable(无需死区和刹车功能)。

步骤 2:GPDMA CH12 2D 通道配置

选择GPDMA1 Channel12(仅 12-15 通道支持 2D 功能),配置为循环模式,开启 Linked List 功能,关键配置:

  1. 通道属性:8Words Internal FIFO/2D addressing=Enabled,Linked-List Mode=Enabled;
  2. 执行模式:Execution Mode=Circular(循环模式),保证 DMA 传输持续进行;
  3. 传输配置:Allocated Port for Transfer=Port0,Transfer Event Generation=TC/HT(传输完成 / 半完成均触发事件)。

步骤 3:Linked List 链表与节点配置

创建一个循环链表队列,包含正弦波节点(TN1)和固定电平节点(TN2),实现两个波形的自动交替,核心配置:

  1. 链表队列(TQ1):创建 Queue 命名为 TQ1,关联 GPDMA1 Channel12,Linked List Setting=Circular(循环模式),First Loop Node=TN1(首个执行正弦波节点);
  2. 正弦波节点(TN1):核心为 “TIM1 更新事件触发 + 2D 寻址 + 重复 1000 次”
    • 触发源:Request Configuration=GPDMA_REQUEST_TIM1UP(TIM1 更新事件为 DMA 请求);
    • 2D 与 Repeat:2D Addressing=Enabled,Repeat Counter=1000(重复 1000 次);
    • 传输参数:Direction=Memory To Peripheral(内存到外设),Data Size=20(对应 20 个脉宽值),Burst Length=1;源地址为正弦波脉宽数组sine_100k,目的地址为&TIM1->CCR1;地址偏移:源地址偏移 0,目的地址偏移 0,块传输后源地址回滚;
  3. 固定电平节点(TN2):配置与 TN1 完全一致,仅源地址改为固定电平脉宽数组bias_100k,实现 PWM 脉宽的固定输出。

关键说明:两个节点的目的地址均为 TIM1->CCR1,DMA 传输的核心是将内存中的脉宽值实时写入 CCR1,实现 PWM 脉宽的硬件级调整,无需 CPU 参与。

3. 核心测试代码解析:简洁高效,无冗余逻辑

CubeMX 生成基础工程后,仅需添加脉宽数组定义和DMA+TIM 关联启动代码,主函数逻辑简洁,无复杂的中断处理或软件切换代码,核心代码如下(基于 HAL 库)。

3.1 脉宽数组定义

在 main.c 中定义正弦波和固定电平的脉宽数组,长度为 20,与 DMA 节点的 Data Size 匹配:

// 正弦波脉宽数组:20个值,对应1个正弦波周期(10us)
uint8_t sine_100k[20] = {25,33,40,45,49,50,49,45,40,33,25,17,10,5,1,0,1,5,10,17};
// 固定电平脉宽数组:20个24,对应稳定PWM脉宽,滤波后为固定直流电平
uint8_t bias_100k[20] = {24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24};

3.2 主函数核心执行流程

系统初始化后,依次完成外设初始化→链表关联→PWM 启动→DMA 启动→TIM 与 DMA 关联,全程无软件循环,硬件自动执行:

int main(void)
{
  // 1. 系统基础初始化:HAL库、系统时钟、电源管理、缓存
  HAL_Init();
  SystemClock_Config();
  SystemPower_Config();
  MX_ICACHE_Init();
  
  // 2. 外设初始化:GPDMA、GPIO、TIM1
  MX_GPDMA1_Init();
  MX_GPIO_Init();
  MX_TIM1_Init();
  // 3. 链表配置:初始化TQ1队列及TN1、TN2节点
  MX_TQ1_Config();

  // 4. 关联GPDMA12通道与TQ1链表,失败则进入错误处理
  if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel12, &TQ1) != HAL_OK)
  {
    Error_Handler();
  }

  // 5. 启动TIM1 CH1 PWM输出
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  // 6. 启动GPDMA12链表中断,开启DMA传输
  HAL_DMAEx_List_Start_IT(&handle_GPDMA1_Channel12);
  // 7. 关联TIM1与GPDMA12:将TIM1 CC1通道DMA句柄与GPDMA12绑定
  __HAL_LINKDMA(&htim1, hdma[TIM_DMA_ID_CC1], handle_GPDMA1_Channel12);
  // 8. 使能TIM1更新事件DMA请求:触发DMA传输的核心
  __HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE);

  // 死循环:无需软件操作,硬件自动完成波形交替
  while (1)
  {
  }
}

关键代码说明

  1. HAL_DMAEx_List_LinkQ:将 DMA 通道与链表队列关联,是链表模式执行的基础;
  2. __HAL_LINKDMA:实现 TIM1 与 GPDMA12 的硬件绑定,保证 DMA 传输的脉宽值准确写入 TIM1->CCR1;
  3. __HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE):开启 TIM1 更新事件的 DMA 请求,是 DMA 传输的触发源,每次 TIM1 计数到 50 产生更新事件,触发一次 DMA 传输。

4. PWM 滤波与实测效果:波形精准,切换平滑

完成硬件配置和代码编写后,在 STM32U575 NUCLEO 板上进行实测,重点验证波形参数准确性和切换平滑性。

4.1 PWM 滤波实现

在 TIM1 CH1 输出引脚(PA8)外接RC 无源滤波电路,滤除 2MHz 的 PWM 高频载波,滤波电路参数需与 PWM 频率匹配:推荐电阻 1kΩ、电容 0.1μF,可根据实际波形平滑度微调。

4.2 实测核心结果

  1. 波形参数完全符合预期:滤波后的正弦波周期为 10us(频率 100kHz),持续时长 10ms,与配置的 “20 个 PWM 脉冲 / 周期、重复 1000 次” 完全一致;固定电平幅值稳定,无波动;
  2. 波形切换无延时、超平滑:正弦波与固定电平的交替切换无任何毛刺和延时,远优于传统双 Timer 方案;
    • 传统双 Timer 方案:需通过 Timer 中断触发软件修改 CCR1 值,存在 CPU 中断响应延时,切换处易出现毛刺;
    • 本方案:GPDMA 链表实现硬件级节点切换,无需 CPU 干预,切换瞬间完成,波形平滑无瑕疵。

5. 方案灵活拓展:适配多场景波形生成需求

本方案的核心优势是配置灵活、可拓展性强,仅需修改链表节点和脉宽数组,即可适配不同的波形生成需求,无需重新配置 TIM 和 GPDMA 基础参数,常见拓展场景如下:

5.1 调整波形持续时长

修改 DMA 节点的 Repeat Counter(重复计数器)值,即可精准控制单个波形的持续时长:

  • 如将 Repeat Counter 改为 2000,正弦波持续时长变为 20ms;改为 500,持续时长变为 5ms;
  • 若需不同波形的持续时长不同,可分别修改 TN1、TN2 的 Repeat Counter 值(如 TN1=1000,TN2=500,实现 10ms 正弦波 + 5ms 固定电平交替)。

5.2 实现多波形循环输出

在 Linked List 链表中添加更多节点,即可实现 3 种及以上波形的循环交替输出:

  • 如新增三角波节点 TN3,定义三角波脉宽数组,按 TN1→TN2→TN3 的顺序配置链表,即可实现正弦波→固定电平→三角波的循环输出;
  • 每个节点可独立配置脉宽数组长度、重复次数,实现个性化的波形组合。

5.3 生成其他类型波形

更换脉宽数组的数值序列,即可通过 PWM + 滤波生成三角波、方波锯齿波等其他模拟波形:

  • 三角波:脉宽值按 “递增→递减” 的线性规律设置;
  • 方波:脉宽值按 “高值→低值” 的固定规律交替设置,调整占空比即可改变方波幅值。

5.4 提高波形分辨率

增加脉宽数组的长度(即 DMA 节点的 Data Size),即可提高波形的分辨率,让波形更平滑:

  • 如将正弦波的脉宽数组长度从 20 增加到 40,一个正弦波周期对应 40 个 PWM 脉冲,幅值变化更细腻,滤波后的正弦波更接近标准波形。

STM32U5 的Timer+GPDMA 2D 通道方案,完美解决了 “DAC 资源不足 + 多波形交替输出” 的开发痛点,相比传统双 Timer 方案,具有节省外设资源、硬件级执行低 CPU 占用、波形切换平滑、配置灵活四大核心优势,可广泛应用于工业信号发生、电机控制、传感器模拟等场景。结合实际开发,给出 5 条实用建议,避免踩坑:

1. 严格选择 GPDMA 通道:仅GPDMA1 12-15 通道支持 2D addressing/Repeat 功能,其他通道无此专属特性,切勿选错通道导致功能失效。

2. 保证参数匹配性:脉宽数组的长度必须与 DMA 节点的Data Size完全一致,Repeat Counter 的数值需根据波形时长需求精准计算,避免传输错误或波形时长偏差。

3. 优化滤波电路参数:RC 滤波电路的电阻、电容值需与PWM 频率匹配:PWM 频率越高,电容可选择更小的值,保证波形的响应速度;若波形出现毛刺,可适当增大电容值。

4. 开启缓存提升传输效率:STM32U5 系列支持 ICACHE/DCACHE,开启后可大幅提升内存访问效率,保证 GPDMA 从内存中读取脉宽值的速率,避免因内存访问过慢导致 PWM 脉宽更新不及时。

5. 开启 DMA 中断实现软件监控:可开启 GPDMA 的传输完成中断(TC),在中断回调函数中实现波形切换的软件监控和干预:如实时统计波形输出次数、根据外部信号手动切换波形节点、异常情况下停止 DMA 传输等。

本方案的本质是充分利用 STM32U5 的 GPDMA 硬件特性,将波形切换的工作从 CPU 和软件转移到硬件,不仅简化了代码逻辑,还提升了系统的稳定性和实时性。对于嵌入式开发而言,这种 “硬件级实现” 的思路是提升系统性能的关键 —— 合理利用 MCU 的专属硬件功能,替代软件循环和中断,既能降低 CPU 占用率,又能避免软件带来的延时和误差,让系统更高效、更稳定。

相关推荐