资讯动态

PWM DAC纹波抑制全解析:从RC滤波到高阶调制策略

发布时间:2026/8/26 6:02:44 来源:尧图企业网站定制
最早做PWM DAC的时候我踩过一个特别典型的坑用STM32的定时器输出20kHz PWM后面接了一级R10kΩ、C100nF的RC低通满心以为出来的1.65V会很干净。结果示波器一夹上去纹波将近40mV而且波形还带着毛刺。那时候我第一反应是滤波电容不够大于是拼命加电容纹波确实降了一点但响应速度慢到没法用一个电压指令要等好几百毫秒才能稳定。后来我才真正把这件事想明白PWM DAC的纹波从来不是一个加大电容就能解决的问题它牵扯到PWM频率、滤波器截止频率、定时器分辨率、输出阻抗、测量方法这五六个变量的联动。这也就是我写这篇文章的初衷——把PWM DAC Ripple Reduction这件事从头到尾拆开讲清楚纹波到底从哪来、怎么算、怎么滤、怎么测以及那些常规教程里不会写的坑。适合正在用MCU做模拟输出、或者想把低成本PWM DAC方案做到接近真实DAC效果的朋友参考。1. 为什么偏要用PWM做DAC又为什么纹波总是降不下去很多新手会觉得奇怪现在带DAC的MCU不算少哪怕是ESP32也内置了两路8位DAC为什么还要费劲用PWM来做模拟输出答案其实很现实——DAC通道数量不够、分辨率不够、或者成本不允许。比如说你要做四路电机调速给定、六路LED恒流控制参考电压、再加两路音频音量控制一般的MCU根本拿不出这么多DAC通道。但PWM引脚到处都是只要是定时器输出通道随便拉一路出来加个RC就能当准DAC用。这也是PCA9685这类16路PWM芯片能被大量用在舵机、LED调光场景里的原因——它本质上就是在用PWM做模拟控制。但PWM DAC有个天生的矛盾那就是纹波抑制和响应速度永远在打架。RC低通的本质是一阶惯性环节转折频率越低对PWM载波的衰减越大纹波越小但阶跃响应也越慢。你要想纹波低于1mV转折频率可能得压到几十赫兹这时候输出一个电压跳变要好几个毫秒甚至几十毫秒才能到位。对温度控制、电机缓启动这种场景还能接受但如果你想用它输出一个音频波形这个响应速度就是灾难。还有一个容易被忽略的因素PWM频率本身。理论上一阶RC对载波的衰减幅度是每倍频程6dB也就是PWM频率每提高一倍相同RC参数下纹波就能减半。那是不是无脑把PWM频率调高就行了当然不是因为定时器的分辨率会跟着掉。以STM32F103为例72MHz主频下如果ARR设成255PWM频率就是281kHz分辨率8位可如果你想要12位分辨率ARR4095PWM频率直接掉到17.6kHz左右。频率和分辨率互为反比这就是所有PWM DAC方案都绕不开的跷跷板。所以我建议动手之前先别急着选参数先理解纹波在电路里的三个来源再谈怎么降。2. 纹波从哪里来三种来源的机理拆解2.1 开关纹波RC滤波器永远滤不干净的通断痕迹第一种也是最主要的一种就是PWM方波本身经RC滤波后残余的充放电纹波。它有个很直观的工程近似公式ΔV ≈ V_H × D × (1 - D) / (f_PWM × R × C)其中V_H是PWM高电平电压D是占空比f_PWM是PWM频率R、C是低通滤波参数。当D0.5时纹波最大此时ΔV_max ≈ V_H / (4 × f_PWM × R × C)。这个公式非常实用。举个例子3.3V系统、20kHz PWM、R10kΩ、C100nF计算结果是3.3 / (4 × 20000 × 10000 × 1e-7) ≈ 41mV。也就是说你在这个配置下输出1.65V示波器上看到几十毫伏的锯齿波是完全正常的不是电路坏了。从公式可以直观看出三个降纹波的路径提高PWM频率、增大R或C、以及让占空比避开0.5附近。但实际工程中占空比往往是被应用需求锁死的比如你就是要输出1.65V能动的只有频率和RC。而这两者又受到定时器分辨率和响应速度的限制所以第一步永远是先把公式算清楚别凭感觉选参数。2.2 量化纹波分辨率不够时输出其实是台阶第二种纹波是很多人会忽略的——量化纹波。8位PWM在3.3V系统下每一步占空比对应约13mV的电压变化。也就是说你想输出1.650V8位PWM只能给出1.643V或1.656V这样的离散值不可能精确落在1.650V上。这个误差不是滤波能解决的它是PWM分辨率的天花板。如果后面的负载对电压精度敏感比如精密恒流源、ADC参考电压13mV的量化台阶可能完全不可接受。此时必须考虑更高分辨率的PWM方案12位PWM的步进约0.8mV16位PWM则能达到0.05mV级别。但高分辨率又带来频率问题。STM32F103的16位定时器如果ARR6553572MHz主频下PWM频率只有约1.1kHz这个频率对滤波来说实在偏低需要很大的RC常数才能压住纹波。所以实际工程上常见的是折中方案ARR取值409512位分辨率PWM频率做到17.6kHz然后用二阶甚至三阶滤波器来补偿RC乘积不够大的问题。2.3 参考电压与实际输出的噪声底第三种纹波来源不在RC滤波通路上而在电源和参考电压里。PWM引脚输出的高电平电平直接从MCU的电源轨取得如果VDD本身有纹波比如DCDC开关噪声、数字电路瞬态电流引起的压降那么PWM的高电平电压也会跟着抖动。RC滤波能滤除PWM开关频率成分滤波不掉电源本身携带的噪声。这种情况在系统里有电机、继电器、WiFi模块等大电流负载时特别明显。我实测过一块ESP32开发板板载AMS1117供电有约30mV的工频和开关噪声叠加这种情况下无论如何优化RC参数PWM DAC输出的噪声底都到不了1mV以下。解决方案一个是改用低噪声LDO或者外部基准电压源比如TL431给MCU的AVDD供电另一个是在PWM DAC输出端加一级有源滤波和缓冲把电源噪声的影响降到最低。还有一个容易忽略的点数字IO翻转时很多引脚同时动作会在地线上产生瞬态电流形成地弹噪声。这种噪声频率很高通常会被RC滤掉但如果PCB布局不合理它可能直接耦合到滤波电容的接地端导致输出纹波异常。后面讲布局的时候我会再提。3. 滤波电路设计从元件算起到实际搭板3.1 一阶RC低通参数计算与负载匹配先把最基本的单级RC设计流程说清楚。RC低通的转折频率是f_c 1 / (2πRC)对PWM载波的衰减量在转折频率以上的频段大约是每倍频程6dB。从工程角度我一般建议把转折频率设在PWM频率的1/50到1/100这样对载波基频的抑制大约在34dB到40dB之间。配合前面那个纹波公式实际纹波会比理论值更小因为理论公式假设的是理想积分实际RC在载波频率附近已经有衰减。举个具体例子。如果PWM频率是100kHz取转折频率2kHz那么R×C 1/(2π×2000) ≈ 79.6μs。选R8.2kΩC10nF实际乘积82μs转折频率约1.94kHz理论纹波按公式算为3.3/(4×100000×8200×1e-8) ≈ 10mV。这个水平对一般的LED调光、风扇转速控制已经够用。但要注意负载匹配问题。RC网络的输出阻抗就是R本身8.2kΩ如果后面直接接一个10kΩ的负载电阻会产生分压输出精度直接偏掉近一半。所以要么保证后级负载阻抗远大于R至少10倍以上要么在RC输出后加一个电压跟随器。大多数情况下我建议加运放缓冲一劳永逸。3.2 二阶RC与有源滤波器什么情况下值得加当你需要的纹波低于5mV但响应速度又不能太慢时单级RC往往会陷入两难。这时候就该上二阶滤波了。无源二阶RC有两种接法。一种是在单级RC后面再串一级R-C但这两级之间会有阻抗互相影响后级的输入阻抗会加载前级的输出导致转折频率偏移所以通常需要用一个运放缓冲器隔开两个RC级。另一种是直接用运放搭Sallen-Key拓扑反馈结构让两级RC互相补偿可以获得平坦的通带和更陡峭的滚降用比较小的RC乘积就能达到很高的载波衰减。Sallen-Key低通滤波器的设计参数并不复杂。以单位增益、Butterworth响应Q0.707为例取两个电阻相等R1R2R两个电容按C22C1配置转折频率近似为f_c ≈ 1/(2πR√(C1×C2))。比如R16kΩC14.7nFC210nFf_c≈1.2kHz左右。这样一来100kHz的PWM载波会被衰减约80dB二阶滤波器约12dB/倍频程滚降纹波几乎可以完全压掉。运放选型上有几个要点单位增益带宽GBW至少要10倍于信号频率最好是100倍以上输出要轨到轨否则低占空比时输出底部会削波输入偏置电流要小特别是用大阻值电阻时。我常用的几款便宜的LM358GBW只有1.1MHz仅适合慢速信号、TI的TL072JFET输入偏置电流极小GBW 3MHz、Microchip的MCP6002轨到轨GBW 1MHz。如果只需要单通道MCP6021或者OPA340都是不错的选择。3.3 RC元件本身的坑电容选型与直流偏压效应很多人设计RC滤波器时只看阻值和容值完全忽略电容的材料特性这是一个大坑。MLCC陶瓷电容在施加直流偏压后实际容量会明显下降这个现象在X5R、X7R材料上尤为严重。一颗额定10V的X5R 100nF电容在3.3V偏置下有效容量可能只有标称的70%在5V下可能只剩50%。这会导致你计算的转折频率和实际不符滤波效果比设计值差不少。所以滤波电容最好选用C0G/NP0材质虽然容值做不大一般最大也就100nF级别但它的容量几乎不随偏压和温度变化精度高稳定性好。如果需要大容值可以C0G小电容并联一个薄膜电容或者使用额定电压远高于工作电压的X7R电容来缓解偏压效应比如耐压50V的X7R在3.3V下容量几乎不衰减。另外电容的等效串联电阻ESR和等效串联电感ESL在高频段会影响滤波性能因此我习惯在滤波电容旁边并联一个100pF级别的高频去耦电容用来吸收PWM边沿引起的高频分量。PCB布局上RC元件要尽量靠近MCU的PWM引脚滤波电容的接地端要直接打过孔到主地平面千万不要让开关电流路径和模拟地混在一起。否则你辛苦设计的滤波器会被一块不良布局毁掉。4. 更高位数的PWM调制策略从8位到16位的进阶玩法4.1 定时器分频与分辨率换频率的矛盾刚才反复提到的分辨率换频率矛盾根源在定时器的分频结构。以STM32的通用定时器为例PWM频率 定时器时钟 / (PSC1) / (ARR1)ARR决定了PWM的周期同时也决定了占空比的分辨率。ARR255时8位分辨率ARR4095时12位分辨率ARR65535时16位分辨率。要想PWM频率高ARR就得小分辨率就低要想分辨率高ARR就得大频率就掉下来。我第一次用STM32F103做PWM DAC时就犯了想当然的错误直接把ARR设成65535想拿16位分辨率结果PWM频率只有1.1kHz加了一堆RC都压不住纹波。后来用公式一算才知道16位分辨率在72MHz主频下根本跑不出足够高的PWM频率除非用更高主频的芯片或者带高分辨率定时器的型号比如STM32F334的HRTIM可以做到几GHz等效PWM时钟。如果你用的是F103这类通用MCU12位分辨率17.6kHz PWM已经是比较实际的折中方案。4.2 抖动Dithering用时间平均换等效分辨率当你的定时器分辨率实在不够但应用只需要慢速响应时可以试试软件抖动Dithering技术用时间换等效分辨率。原理很简单假设你的PWM是8位想输出占空比128.5对应1.668V硬件无法直接输出0.5级。方案是交替输出128和129两个相邻占空比比如128输出50个周期、129输出50个周期在一个时间窗口内平均等效为128.5。这个平均窗口越长等效分辨率越高。8位PWM加上32周期的时间平均等效分辨率可以做到13位。抖动在LED调光、电机转速给定这类对瞬时精度要求不高的场合非常好用。我实测下来12kHz PWM、8位分辨率、加128次抖动平均驱动一个LED灯肉眼看完全没有频闪亮度调节的平滑度明显好于纯8位。但它也有代价抖动会造成短时间内的电压波动如果后端接了灵敏的ADC或者音频电路这些抖动会被当成噪声捡到所以用之前要想清楚负载的敏感度。4.3 Sigma-Delta调制思路把噪声推向高频再滤除Sigma-DeltaΣ-Δ调制是另一个高阶玩法也是许多精密DAC的内部原理只不过我们可以用PWM引脚加RC滤波器复现一个简化版。核心思想是用1位输出引脚在0和V_H之间翻转配合反馈环路以远高于普通PWM的频率进行调制把量化噪声整形到高频段再用低通滤波器滤除。软件实现并不复杂每N微秒中断一次累加一个期望值当累加器溢出时输出高电平并减去一个基准量否则输出低电平。输出的平均占空比就是期望电压但脉冲密度分布经过整形噪声集中在高频。用一颗几十MHz主频的MCU配一阶RC就能达到12位以上的等效精度。我试过在ESP32上用GPIO做1位Σ-Δ输出跑2MHz左右的调制频率加一级R10kΩ、C100nF的低通输出一个1.2V的直流电压纹波实测在1mV以内效果相当惊艳。缺点是对实时性要求高主控不能同时干太多活而且要确保代码里没有其他中断频繁打断调制循环否则会产生低频噪声。如果你的应用对精度有硬需求这个方案值得研究。5. 实测对比不同参数组合下的纹波表现与示波器技巧5.1 一组实测数据参数组合对纹波的影响我用一块STM32F103开发板和一块ESP32开发板做过一组对比测试统一输出3.3V系统的1.65V中点电压用示波器在20MHz带宽限制下测量结果如下表。方案PWM频率滤波网络理论纹波估算实测纹波峰峰值A20kHz8位单级RC 10kΩ/100nF约41mV35~45mVB100kHz8位单级RC 10kΩ/100nF约8.3mV7~12mVC17.6kHz12位单级RC 10kΩ/1uF约0.8mV3~6mVD17.6kHz12位两级RC 10kΩ/1uF 10kΩ/100nF远小于0.1mV1~2mVE17.6kHz12位Sallen-Key二阶运放缓冲远小于0.1mV0.5~1.5mV这里有几个值得注意的点。第一方案A的实测纹波和理论值基本吻合说明120kHz的PWM用这种参数确实压不住。第二方案B把PWM频率从20kHz提到100kHz后纹波降到10mV左右但代价是分辨率只有8位ARR255输出本身有13mV的量化台阶所以实际跳变比纯纹波更难看。第三方案C的频率不算高但RC时间常数已经很大理论纹波只有0.8mV实测却有三四毫伏这是因为电源噪声和测量噪声成了主要来源。第四加了第二级滤波和运放缓冲后纹波进一步降低到1mV级别这个水平已经接近入门级12位DAC了。5.2 示波器测量纹波的正确姿势说到实测就不得不提一个很多人都在犯的错误——拿示波器探头的地线夹子去测纹波尤其测PWM DAC这种低阻抗、低噪声的信号。普通探头的地线夹引线很长会与探头的探针形成一个大环路这个环路就像一根天线会把周围空间的电磁干扰全部拾取进来。我用同样的电路换了两种接线方式测出来的结果能差出一大截长地线夹测出来纹波有25mV换上弹簧接地之后实际只有8mV。所以测量纹波时请务必使用探头自带的短接地弹簧或者用铜丝绕一个尽可能短的地线环。另外示波器要开启20MHz带宽限制。如果不限制带宽高频噪声会全部叠加在波形上让你误以为滤波效果很差。我见过有人在100MHz带宽下测出50mV纹波切换到20MHz带宽后只剩下3mV这就是典型的高频噪声干扰。如果你有高分辨率示波器12位或以上ADC记得把采集模式设为高分辨率模式能进一步消除量化噪声。还有一个测量技巧测量点要尽量靠近滤波电容的引脚并且示波器探头尖端和接地环之间不要夹到PCB走线太长的一段。理想情况是探头尖端直接触碰RC输出端电容的正极弹簧地直接触碰电容负极。5.3 输出方波过冲和振铃的问题热搜词里有一条dac输出方波上升有过冲振荡这类现象的根源往往不是滤波器本身而是PWM信号的快速边沿。MCU的IO引脚驱动能力比较强上升沿可以做到几纳秒这个陡峭的边沿在走线电感、寄生电容和探头负载的共同作用下很容易产生振铃。如果你在RC滤波器的输入端看到过冲通常不是RC的问题而是测量点选得太靠前或者探头补偿不正确。如果你在输出端看到过冲那大概率是PCB走线过长、输出端到运放输入之间的寄生电容与电阻形成了额外谐振。解决办法是缩短PWM输出引脚到RC元件的走线在RC网络输入侧串联一个几十欧姆的小电阻来抑制边沿斜率或者在滤波电容旁边并联一个100pF的高频去耦电容吸收振铃能量。如果用了运放缓冲还要检查运放输出端的负载电容是否过大必要时加一个几十欧姆的隔离电阻。6. 避坑清单与实际原型推荐配置6.1 我踩过的那些坑做PWM DAC方案做了大半年我记录了一些典型的翻车现场整理出来供大家避雷。第一个坑是直接用软件模拟PWM而不是用硬件定时器。有些简单项目里随手用GPIO翻转加delay实现PWM这在低频伺服场景勉强能用但输出的抖动很大——相邻两个周期的占空比差好几个时钟周期这种抖动在滤波后会表现为额外噪声。务必用MCU的硬件定时器或者完善的PWM外设比如ESP32的LEDC、PCA9685这类专用芯片它们能保证周期和占空比的稳定性。第二个坑是把PWM DAC输出直接接到低阻抗负载。前面说过RC网络的输出阻抗基本等于电阻R通常好几kΩ接个几百Ω的负载输出电平直接就被拉低了。我见过有人用PWM DAC直接驱动一个LED恒流电路结果发现电流根本达不到设计值查了半天才发现是负载把分压器拉偏了。正确的做法是在RC网络和负载之间加一级运放缓冲。第三个坑是更新占空比时不用原子操作。在多任务系统里如果某个任务更新占空比时读写了ARR的高字节和低字节由于操作被中断打断可能导致ARR的奇偶字节组合错乱输出瞬间跳变一个很大的电平。STM32定时器预装载寄存器PWM就是为了解决这个问题的记得开启预装载功能让占空比在更新事件时统一生效。第四个坑是选电容只看容值不看材质。我前面已经强调过X5R/X7R的直流偏压效应这里再说一个实例我用X7R 1uF电容做滤波设计转折频率16Hz实测输出响应比我预想的慢得多因为电容在偏置下实际容量比标称值大了不少——所以实际上只是响应慢了点虽然滤波效果好但时间常数完全不在设计范围内。换用C0G之后参数才真正对得上。6.2 一个可以直接抄作业的推荐配置最后给一套我实测了很长时间、在很多项目里直接复用的配置。目标是把PWM DAC做到2mV以内的纹波同时保持毫秒级的响应速度。主控用STM32F103定时器配置为PWM模式ARR409512位分辨率预分频PSC0实际PWM频率约17.6kHz。滤波网络采用两级RC第一级R110kΩ、C11uFC0G/NP0如果没有这么大容量的C0G用薄膜电容或耐压100V的X7R代替第二级R210kΩ、C2100nFC0G两级之间不用运放隔离因为R2远大于C1在1kHz附近的阻抗级间负载效应可控。输出端接一个MCP6002或OPA340运放做电压跟随器运放供电用AVDD的3.3V并在电源引脚加100nF10uF去耦。这套配置实测输出1.65V时纹波约1~2mV阶跃响应时间约2~3ms精度受限于电源噪声和参考电压整体约±5mV。如果你需要更高的精度可以把参考电压换成外部基准IC或者改用Σ-Δ调制配合单级RC能再把噪声压低一个量级。6.3 从PWM DAC继续往前走还是想多说一句PWM DAC终究是用时间换精度、用滤波换速度的一种折中方案。当你发现为了压纹波需要堆太多级滤波和运放时不妨停下来想想是否该评估一下内置真正DAC的MCU或者外挂一颗SPI/I2C接口的DAC芯片。有些DAC芯片比如MCP4921、DAC8568单价并不贵性能却比精心调教的PWM DAC方案好得多。我个人现在的选择逻辑是这样的如果目标是LED调光、电机速度给定、音量控制这类低频、低精度的场景PWM DAC完全够用成本几乎为零如果目标是给精密ADC做参考电压、音频波形输出或者传感激励源我会直接用真正DAC。把PWM DAC用在它擅长的地方能省不少事。从另一个角度看理解PWM DAC的纹波机制也会反向帮助你设计DAC的电源滤波和布局——毕竟模拟电路里的很多道理是共通的。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价