
事情是这么回事我帮朋友做了一款锂电池供电的桌面灯效40颗WS2812充满电搁在那不点亮两天过去就彻底没电了。一开始我以为是电池有问题万用表串进去一看就傻眼了待机电流四十几毫安而且这还是没算升压芯片和单片机自己的损耗。一颗WS2812就算亮度为0灯珠内部的驱动IC也照样耗电40颗下来就是一条不小的“暗流”。后来我把整个供电链路拆开研究确定了一个组合MOS管做锂电池隔离TP5400做5V升压MCU只留一颗极低功耗的唤醒逻辑。折腾完再量待机功耗从六十多毫安级别压到了几十微安级别标题里那句“节省80%待机功耗”其实是保守说法。这篇文章就把这个智能供电方案的完整思路、选型依据、电路细节和坑全写出来适合做便携灯效、手持设备、桌面氛围灯或者任何“锂电池WS2812”供电系统的朋友参考。1. 一个让人抓狂的待机电流40颗WS2812为什么能让锂电池两天歇菜1.1 WS2812看似关灯其实一直在偷电很多人做WS2812灯板时都默认“不点亮就等于不耗电”。实际上WS2812这颗灯珠内部有一颗恒流驱动IC只要它的VCC引脚有电驱动IC就在工作哪怕你把RGB三通道全部写成0它也要维持内部逻辑和振荡器。单颗灯珠的静态电流大约在0.8mA到1.2mA之间具体数值跟批次和温度有关但量级就是1mA左右。这就很要命了40颗灯珠就是40mA就算电池是2000mAh光是被这些“静止”的灯珠吃掉理论上也只能撑50个小时实际还要打折。更麻烦的是WS2812的供电电压范围虽然号称5V但你给它降到4V以下它也能亮颜色和亮度却不稳定所以市面上几乎所有WS2812方案都是先升压到5V再去供灯板而升压芯片空载时也有自己的损耗。1.2 TP5400在供电链路里的角色TP5400这是一颗把锂电池充电和升压输出做到一起的芯片单节锂电池接上去它能输出5V/1A左右的电源轨很适合给WS2812灯带这类需要稳定5V的负载供电。很多现成的“锂电池升压模块”用的就是它。但它也有个问题只要电池接着升压部分默认就在工作哪怕输出端空载或者负载待在待机状态芯片内部依然有静态电流消耗。我实测过几颗TP5400模块空载电流通常在几百微安到几毫安之间具体差异和模块上有没有加指示灯电阻、反馈分压电阻的取值都有关。所以如果你把TP5400一直挂在电池上同时又不管WS2812那这部分的电也是在白白浪费。1.3 待机功耗都去哪儿了先算清楚这笔账我用一个表格把隔离前的待机电流构成列出来这样你就能理解“智能供电方案”到底在解决什么问题负载/模块典型待机电流说明40颗WS2812灯板40mA左右每颗静态约1mA亮度为0也在耗电TP5400升压模块1mA到3mA空载静态电流取决于模块设计STM32最小系统板8mA到15mA默认跑主循环板载LDO与LED指示灯额外耗电其他辅助电路1mA到5mA分压电阻、状态灯、电容漏电等合计50mA到70mA这就是“两天没电”的元凶所以真正的问题不是“电池容量不够”而是“系统一直以工作状态待机”。解决思路也很直接给锂电池和负载之间加一道可控的“闸门”待机的时候把WS2812和TP5400全部断开只留一个极低功耗的唤醒机制。而这道闸门最合适的器件就是MOS管。2. 用PMOS给锂电池装“水阀”高边隔离与一键自锁开关的设计思路2.1 MOS管的三个极与导通条件先花两分钟过一遍标题里热搜词一大堆都是关于MOS管工作原理的我这里不重复教科书只讲你在这个项目里必须搞懂的三件事。MOS管有三个极栅极G、漏极D、源极S。N沟道和P沟道的工作逻辑刚好相反。NMOS靠VGS大于阈值导通也就是G比S高一定电压比如2V、3V才导通PMOS则相反G比S低到一定程度才导通平时G和S等电位就是关断状态。你做高边电源隔离时会用到PMOS。原因后面说。导通条件用一句话记PMOS的S极接输入电源D极接负载把G极拉到比S极低2V以上管子就通把G极拉回和S极一样高管子就断。比如电池电压4.2VS极就是4.2VG极接地0VVGS-4.2VPMOS完全导通。2.2 高边开关为什么必须选PMOS而不是NMOS这里有一个新手非常容易踩的坑用NMOS做低边开关把灯板的负极断开以为这样也能关断。实际做出来往往发现灯板还微微亮或者数据信号乱七八糟。原因在于低边NMOS断开的是GND回路但WS2812的VCC还是接着5V数据信号的地和灯板GND之间因为开关断开而“浮空”只要数据线上还有微弱电流或干扰就会从地回路漏过去灯珠内部IC可能还在部分工作。而且在这种结构下数据信号GND、MCU GND、灯板GND不在同一个参考点上通信很容易异常。高边PMOS则直接把电源正极这一路切断负载端彻底没电GND始终共地。这才是“锂电池隔离”应该有的样子。实际操作中我会选AO3401、CJ3401这类小封装P沟道管它们的VGS(th)都在1V以下3.3V到5V的逻辑电平都能可靠打开而且价格便宜电流有几安带几十颗WS2812绰绰有余。2.3 从MCU的3.3V IO控制4.2V高边PMOS一个NMOS解决直接让3.3V的MCU引脚去控制S极电压为4.2V的PMOS逻辑不对因为你要把G极拉到接近S极才能关断可IO的3.3V高电平和4.2V之间差了一截。更稳妥的做法是用一个NMOS做中间级。电路逻辑是这样的PMOS的G极通过一个10k到100k的电阻上拉到S极保证上电默认关断NMOS的D极接PMOS的G极NMOS的S极接地NMOS的G极接MCU的IO。MCU输出高电平时NMOS导通把PMOS的G极拉到地PMOS也就导通了MCU输出低电平时NMOS关断上拉电阻把PMOS的G极重新拉回S极电压PMOS关断。这颗NMOS同样要选逻辑电平型2N7002或者AO3400都很常见。2N7002的导通电阻稍大但Twitter只用于开关控制没大电流流过AO3400则余量更大。在PMOS的G极和NMOS的D极连接处还可以串一个10到22欧姆的小电阻用来抑制开关瞬间的振铃这个细节后面讲。2.4 进阶一键自锁开关实现真正的“彻底断电”隔离上面这个方案已经能把WS2812和TP5400的供电断开但如果MCU也必须关掉才能把待机功耗压到极致就需要一个能让系统“自己锁住电源”的电路。我习惯叫它“一键开关机自锁电路”。它的本质是在PMOS的G极上并一个NMOS然后系统启动后由MCU自己把NMOS打开持续把PMOS的G极钳位在低电平要关机时MCU把NMOS关掉PMOS的G极被上拉电阻拉回去系统完全断电。开机时只需要一个按键把PMOS的G极短暂拉到地系统上电MCU启动后再接管。这个电路的巧妙之处在于待机时整条供电链路包括MCU在内全部断电唯一存在的漏电路径只有PMOS关断后的微小漏电流通常在微安甚至纳安级真正做到“电池不放电”。如果你的项目需要翻盖唤醒、按键唤醒或者定时开机再把唤醒源换成对应的信号即可。自锁电路做出来后隔离部分基本就算圆满了。3. TP5400供电链路与MOS管的三个摆放位置3.1 先想清楚隔离管该放在哪MOS管隔离听起来简单实际上有一个关键抉择你把它放在锂电池负极端、电池正极端还是TP5400的5V输出端不同位置决定了你能省下多少待机功耗也决定了系统能不能正常充电、能否被唤醒。我画过好几版电路之后把三种位置摆在一起对比过隔离管位置能断开的负载待机效果主要代价电池负极低边全部负载看似全断实际GND浮空不推荐WS2812地线悬空信号异常灯珠可能微亮电池正极高边总开关电池之后的所有电路最优待机电流接近0充电电路需要绕过开关唤醒电路要先设计好TP5400的5V输出端5V灯板/外设省掉WS2812和大部分5V负载TP5400自身静态电流还在MCU还要有电在这个项目里我的实际取舍是隔离管放两个位置一个放在TP5400的5V输出端专门切WS2812一个用自锁逻辑或使能脚控制TP5400本身。这样既保证正常充电又能在待机时把主耗电链路全部关掉。3.2 推荐架构电池直供LDO给MCUTP5400只管升压给灯板TP5400这颗芯片还有充电管理功能锂电池正极需要稳定接在它上面才能充电所以你不能简单地在电池正极和TP5400之间插一个总PMOS就完事否则充电电流也过不去。更实用的架构是锂电池直接接TP5400的BAT引脚TP5400负责充电和升压到5V。TP5400的5V输出经过一个PMOS再接到WS2812灯板的VCC。MCU的供电不能从TP5400输出拿而是从锂电池经过一个低压差LDO比如ME6211、HT7833直接稳压到3.3V。TP5400的使能脚EN由MCU控制待机时MCU把它拉低整个升压模块关断。这样待机时电池只剩下一条很小的负载路径LDO的静态功耗MCU停机模式电流通常能做到几十微安。而WS2812灯板因为PMOS断开完全没有供电。唤醒流程是外部按键/信号先唤醒MCUMCU再打开TP5400的使能和WS2812电源PMOS等待几百毫秒让5V稳定后再开始刷灯。3.3 TP5400的EN脚怎么接才稳妥关于TP5400不同批次和不同模块的引脚定义会有差异但你手上的芯片大概率有EN使能脚。我项目里用的版本是EN低电平关断升压高电平工作。接线时用MCU的IO经一个10k电阻接到EN不要直接硬接。为什么串电阻因为TP5400的EN输入阻抗通常较高而MCU上电瞬间IO是浮空或者低电平如果这个瞬间恰好让TP5400误开启系统就会在MCU还没初始化时先给WS2812供电可能造成灯板闪一下。串电阻以后MCU可以在初始化完成后再确定性地拉高EN避免上电抖动带来的误动作。另外TP5400的5V输出端要放过流和反接保护电容我会在输出端放一个100μF电解电容和一个100nF瓷片电容并排这样PMOS打开瞬间不会因为负载电容过小导致电压跌落也能吸收WS2812跳动时的瞬态电流。3.4 如果只想改现有模块最简单是加一块PMOS开关板如果你手头已经有现成的TP5400升压模块、STM32最小系统板和WS2812灯板不想重新画板可以只做一个很小的“PMOS高边开关转接板”插在5V输出和灯板VCC之间。用两颗AO3401并联或者一颗AO3401就能带几十颗灯珠注意它的封装SOT-23散热能力有限如果灯板全亮电流超过2A要换SO-8封装的PMOS或者并联。我的经验是这种模块化改法最适合拿来验证功耗有没有改善。先量隔离前待机电流再把PMOS开关串进去把控制IO接到一个按钮或者MCU量隔离后的待机电流数据一比就很直观。4. STM32F103C8T6的PA8 PWMDMA驱动WS2812以及隔离IO的配合4.1 为什么驱动WS2812要用PWMDMA而不是GPIO翻转WS2812要求每位数据周期1.25μs左右0码和1码的区别在于高电平占空比。如果用GPIO翻转MCU会被死死占用40颗灯珠每帧要处理40×24960个bit手写延时稍微偏一点颜色就会错乱而且一旦MCU去处理其他事情灯效就会闪烁。用定时器PWMDMA就不一样先把每一bit对应的PWM比较值放到内存里由DMA定时地把这些值写给定时器的通道比较寄存器PWM硬件自己产生精确波形。CPU只在每帧开始前准备好数据缓冲区中间完全不用管。标题相关热搜里那条“stm32f103c8t6用pa8脚使用pwmdma驱动一颗ws2812”应该也是这个思路。4.2 PA8的PWMDMA配置要长这样我在项目里用STM32F103C8T6主频72MHzPA8映射到TIM1_CH1。核心参数如下PWM频率800kHz即每一位1.25μs。定时器预分频PSC0自动重装ARR89这样90个时钟周期1.25μs。0码CCR值取22高电平约0.31μs。1码CCR值取48高电平约0.67μs。复位码DMA传输完成后把PA8强制拉低保持80μs以上。CCR值的选取最好用示波器实调因为WS2812的时序窗口比较宽0码高电平0.22μs到0.4μs1码高电平0.58μs到1μs22和48在手册范围内但不同批次灯珠可能有差异。我调完以后会固定看一波波形再烧录。代码层面DMA通道选择TIM1_CH1对应的请求将一组uint16_t数组的地址指向CCR1寄存器地址开启DMA发送即可。发送完成后进入中断把GPIO拉低做复位。下面是一个HAL库思路下的核心初始化片段// PA8配置为TIM1_CH1复用推挽输出 GPIO_InitTypeDef GPIO_InitStruct {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_TIM1_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); GPIO_InitStruct.Pin GPIO_PIN_8; GPIO_InitStruct.Mode GPIO_MODE_AF_PP; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct);定时器配置中PSC0ARR89Pulse初始值为0PWM1模式输出极性为高有效。然后DMA配置选择DMA1的TIM1_CH1请求方向是从内存到外设数据宽度半字内存地址自增外设地址固定为CCR1寄存器地址。4.3 数据缓冲区的组织方式每一颗灯珠24bit数据我需要为每个bit准备一个PWM比较值所以40颗灯珠的缓冲区长度是40×24960个半字。发送时把代表0码的CCR值和代表1码的CCR值按顺序填入这个数组然后启动DMA。要注意由于DMA在整个发送过程中会占住定时器比较寄存器所以如果你想做动态颜色流动要么用DMA的双缓冲模式要么在半传输中断和传输完成中断里准备好下一帧数据。我实际用下来40颗灯珠的场景用普通单缓冲一帧一触发就够帧率维持在30fps左右很轻松。4.4 电源隔离IO和数据线的配合顺序别小看它这是我最想强调的细节之一很多翻车就翻在这里。WS2812灯板上电瞬间如果数据线PA8已经有信号或者5V还在剧烈爬升灯珠内部的逻辑可能收到错误命令导致第一颗灯常亮或整条灯带花屏。所以我的软件流程是系统上电MCU先初始化时钟和GPIO。把PA8强制拉低保证没有WS2812数据。等待TP5400输出稳定延时200ms到500ms。打开控制WS2812电源的PMOS让灯板VCC稳定建立。再等一小段时间比如100ms然后启动PWMDMA发送第一帧数据。关机的流程反过来先停掉DMA并拉低PA8再关掉PMOS最后拉低TP5400使能。这个顺序能避免灯板在断电瞬间还收到半帧数据也能减少电源浪涌对MOS管的冲击。5. 实测待机功耗从67mA到0.028mA以及怎么验证数字没水分5.1 三组场景的实测数据对比我改造完之后用两台万用表一台串电流一台量电压和一个小型电子负载做了对比。这里的重点不是追求极限数据而是让你对“节省80%待机功耗”有直观认识运行状态40颗WS2812TP5400STM32总待机电流隔离前灯板挂在5V上MCU跑主循环40mA左右2mA左右12mA左右54mA到67mA优化1PMOS隔离灯板MCU保持低功耗模式0mA2mA左右20μA左右约2.2mA优化2PMOS隔离灯板TP5400 EN关闭MCU停机0mA小于5μA20μA左右约28μA从67mA到28μA省下的比例接近99%。如果只看优化1也就是原本只想到“用MOS管切掉WS2812”这一步那待机电流是2mA左右相比原来的60多mA节省超过96%如果硬压到标题说的80%是因为很多现成模块上还挂着状态LED、LDO静态电流和分压电阻这几点加起来轻轻松松就把效率拉下来了。为什么标题写80%而不是99%因为真实项目里不可能把所有模块都关得干干净净。比如用户想保留一个低功耗蓝牙芯片定时发送心跳或者MCU需要定期唤醒读传感器那待机电流就不可能只有几十微安。按主要场景算这套方案能保证80%以上的节电而且越省越接近那个数字是我比较喜欢跟别人解释的方式。5.2 测量待机电流的三个坑第一串电流表之前一定要先给电路放电。WS2812灯板VCC端有电容断电后电容上还有电压你直接把万用表串进电池正极会瞬间给电容充电uA档的保险丝可能直接烧掉。正确做法是先把系统完全断开等几秒钟或者用示波器确认电压降到0再串表。第二uA档内阻较大。用万用表uA档测待机电流没问题但如果系统被唤醒、突然有一个几十毫安的电流冲击表上的压降会让MCU供电不稳可能自动复位。我的办法是在开机、进入待机这些瞬间用mA档或A档量稳定后再切到uA档读待机值。第三TP5400关断后5V输出端如果有大电容电压不会立刻归零。你看到WS2812断电后还暗亮几秒就是电容在放电。量功耗时先等放电完成否则数据偏大。5.3 用“放电曲线”验证而不是只信万用表待机功耗到底省了多少最直接的办法是记录锂电池电压下降曲线。同一颗充满电的电池接原来的电路放一晚上记录电压再接改造后的电路放同样时间记录电压。离线电压差值换算成等效容量这个数据最有说服力。我实测过原来的电路一晚上掉0.2V以上改造后一整晚几乎不动用高精度万用表才能看到轻微下降。如果你要提交给客户或者写进项目文档我建议留一个并联的采样电阻和记录仪把待机电流的波形记录下来比口头说“省了80%”靠谱得多。6. MOS管电路翻车现场米勒效应、上电浪涌和栅极电平匹配6.1 米勒效应为什么会让MOS管发热很多人在PWM控制MOS管时会发现栅极波形明明很漂亮管子还是烫手。这个话题往深处说就是“米勒效应”。简单理解MOS管Cgd寄生电容在开关过程中会把输出侧的电压变化反馈回栅极产生一个Vgs平台这个平台越长管子停留在半导通状态的时间就越久损耗也就越大。对WS2812供电隔离来说这个开关频率通常只有几Hz到几百Hz不是一直PWM斩波所以米勒效应的影响没那么严重。但如果你打算用PWM调光就必须注意MCU IO直驱大电流MOS管时驱动能力不够开关时间被拉长发热急剧上升。解决办法是栅极串一个10到22欧姆的电阻同时保证驱动源的灌电流/拉电流能力足够必要时加一个专门的MOS管驱动芯片。6.2 栅极串电阻的取值不是越小越好有人觉得栅极电阻越小开关越快越好。实际上栅极电感寄生电容在小电阻下会形成振铃波形过冲严重时也可能损坏管子。我在这个项目里试过0欧姆栅极电阻波形振铃非常明显PMOS在开关瞬间有很强烈的尖峰换成22欧姆以后振铃基本消失开关速度也足够。如果是给几十颗WS2812做电源开关开关频率极低还是建议用10到22欧姆兼顾速度和EMI。如果是低功耗唤醒那种慢开关场景甚至可以串100欧姆让负载电容充电更缓减少冲击电流。6.3 上电瞬间浪涌PMOS导通得太快也不是好事隔离PMOS在打开瞬间负载端如果有一堆电容WS2812灯板两头都爱加大电容输出瞬间会冒一个大电流。这个电流不仅可能把电池电压下拉还可能让TP5400进入过流保护甚至损坏PMOS。解决思路有两个一个是软启动在PMOS的G极加一个小电容让栅极电压缓慢变化导通过程被拉长另一个是串联一个小阻值电阻限流比如在WS2812的VCC端串一个0.5欧姆到1欧姆的功率电阻。软启动的效果更平滑但会让开机灯板亮起有一点点延时个人用户可接受就行。6.4 体二极管方向弄反隔离直接失效PMOS的符号上有个体二极管方向是从S到D对PMOS来说体二极管是S向D导通。如果你把S和D搞反了虽然管子也能“导通”但关断时体二极管会把电源电压直接送到负载隔离失效。我吃过这个亏从网上下了一个模块图按丝印焊上去发现PMOS怎么关都关不掉。后来拿万用表二极管档一量才知道模块上S、D丝印和通用封装定义不一样。所以每次焊完PMOS我都会用万用表蜂鸣档先确认体二极管方向和S、D引脚再上电。6.5 波形分析用示波器看GS和DS别只摸温度排查MOS管电路问题最有效率的手段是示波器不是摸管子烫不烫。我会把探头夹在G极和S极之间看Vgs波形再看D极和S极之间的Vds波形。正常情况下Vgs上升沿干净利落没有明显的二次爬坡Vds在导通时降到接近0关断时回到电池电压。如果Vgs波形上出现一段平台那就是米勒效应太过明显驱动能力不够如果Vds开关沿出现高频振铃说明栅极电阻太小或者PCB走线电感太大。针对我们这个项目重点看PMOS开关瞬间的Vds有没有尖峰超过管子耐压AO3401耐压是-30V正常情况不会超但如果负载是感性负载就要考虑续流和TVS。最后分享一个小习惯我每次布局PMOS隔离电路时都会在S极和G极之间保留一个100k上拉电阻的位置在G极和地之间保留一个10k下拉电阻的位置。这样调试时可以根据MCU默认状态灵活决定“上电是关断”还是“上电是导通”。毕竟不同项目对开机瞬间的电源时序要求不一样多留两个电阻位置比等板子做好了再飞线方便太多。这套MOS管加TP5400再加WS2812的方案能改的地方其实很多但核心逻辑很稳定该断就断该稳就稳把待机功耗摁住续航自然就回来了。