STM32实战:用PWM+DMA生成正弦波信号(附完整代码)

STM32实战:用PWM+DMA生成高精度正弦波信号

最近在做一个电机驱动项目,需要生成一个干净、稳定的正弦波作为参考信号。一开始我尝试用DAC,但发现手头的芯片DAC通道不够,或者精度达不到要求。后来转念一想,PWM配合一个简单的RC滤波电路,不就是一个廉价的“DAC”吗?这个思路在很多低成本、高精度的信号发生场景里特别实用。今天,我就把自己在STM32上实现PWM+DMA生成正弦波的完整过程、踩过的坑以及优化技巧,毫无保留地分享给大家。无论你是正在做逆变器、音频处理,还是需要任意波形生成,这套方案都能直接拿来用。

1. 核心原理:为什么PWM能“变”成正弦波?

很多人一听到用PWM生成模拟信号,第一反应是“输出不是方波吗?”。这里的关键在于“等效”和“平均”的概念。想象一下,你快速开关一个水龙头,如果开关的速度足够快,那么在一段时间内流出的平均水量,就可以等效于你缓慢调节阀门开度得到的水流。PWM生成正弦波的原理与此类似。

一个固定频率的PWM波,其高电平时间(脉宽)占整个周期的比例,称为占空比。当我们让这个占空比按照正弦函数的规律变化时,经过一个低通滤波器(比如最简单的RC电路)滤除高频的开关噪声后,剩下的低频分量——也就是平均电压——就会呈现出正弦波的形状。这就是脉冲宽度调制(PWM)用于数模转换(DAC) 的基本思想,有时也被称为Σ-Δ调制的一种简化形式。

注意:这里的低通滤波器至关重要。它的截止频率必须远低于PWM的开关频率(通常为几十到几百kHz),但又要略高于你想要生成的正弦波频率。这样才能有效滤除PWM载波,同时保留我们需要的正弦信号。

数学上可以这样理解:假设PWM周期为 T_pwm,高电平时间为 T_on,电源电压为 Vcc。那么在一个PWM周期内的平均输出电压 V_avg = (T_on / T_pwm) * Vcc。如果我们让 T_on 随时间 t 的变化满足: T_on(t) = (0.5 + 0.5 * sin(2π * f_signal * t)) * T_pwm 那么,V_avg(t) 就会是一个带有直流偏置(0.5 * Vcc)的正弦波。这个直流偏置是为了让占空比始终为正(0%到100%)。在实际电路中,我们可以通过隔直电容将其去除,得到纯交流正弦波。

2. 硬件平台与工程框架搭建

我这次使用的是STM32F407VET6,主频168MHz,定时器资源丰富。选择这款芯片是因为它的高级定时器(如TIM1, TIM8)支持互补PWM输出和丰富的DMA触发,但基本定时器(如TIM2-TIM5)也完全够用。大家可以根据自己手头的开发板进行调整。

2.1 所需硬件清单

  • STM32核心板(F1、F4、H7系列均可)
  • 一个RC低通滤波器元件:
    • 电阻R:1kΩ - 10kΩ
    • 电容C:0.1µF - 1µF(具体值需计算)
  • 示波器(用于观察最终波形)
  • 万用表或逻辑分析仪(调试用)

2.2 开发环境与工程初始化

我使用的是STM32CubeIDE,它集成了CubeMX图形化配置工具,非常方便。首先,我们创建一个新工程,并进行关键外设的初始化:

  1. 系统时钟:配置到最高频率,确保定时器有足够的计数精度。
  2. GPIO:配置一个引脚为定时器的PWM输出通道。例如,我使用 PA8(TIM1_CH1)
  3. 定时器:配置一个定时器用于产生PWM。关键参数如下表所示:
参数项 推荐值 说明
时钟源 Internal Clock 使用内部时钟驱动
预分频器 (PSC) 0 不分频,时钟直接用于计数器
计数模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值