基于STM32的无线充电器DIY:从电磁感应原理到嵌入式闭环控制实践

发布时间:2026/7/29 12:12:05
基于STM32的无线充电器DIY:从电磁感应原理到嵌入式闭环控制实践 1. 从零到一为什么选择STM32做无线充电器几年前我还在用各种“傻大黑粗”的有线充电器每次给设备充电都得对准那个小小的接口晚上摸黑找半天插拔时还得担心接口磨损。后来市面上出现了不少成品无线充电器用起来是方便但作为一个喜欢折腾的电子爱好者总觉得少了点参与感和掌控感。比如充电效率到底怎么样发热严不严重能不能给非标设备充电这些问题成品充电器不会告诉你答案。于是我萌生了自己动手做一个无线充电器的念头。市面上主流的方案有专用集成芯片比如Ti、IDT的方案也有基于单片机控制的方案。专用芯片集成度高开发快但就像个黑盒子参数可调范围有限学习价值也打了折扣。而基于通用微控制器MCU的方案虽然前期需要自己搭建更多电路、编写更多代码但整个能量传输的“脉搏”——从PWM波生成、频率调节、到异物检测、通信握手——都掌握在自己手里可玩性和定制化程度是前者无法比拟的。在MCU选型上我最终锁定了意法半导体的STM32系列。原因很直接性价比、生态和性能的完美平衡。对于无线充电这种应用我们需要一个能产生高精度PWM用于驱动全桥或半桥逆变、具备高速AD采样用于检测电压电流、有足够定时器和通信接口如UART用于调试、I2C/SPI连接屏幕或传感器、并且功耗还不能太高的核心。STM32F1系列的Cortex-M3内核或者F0系列的M0内核完全能满足这些需求。更重要的是STM32的社区资源太丰富了从标准库到HAL库从各种开发板到无穷无尽的论坛帖子几乎你遇到的每一个坑都有人踩过并分享了解决方案。这对于一个个人项目来说意味着极高的开发效率和极低的学习成本。所以这个项目不仅仅是为了得到一个能用的无线充电器更是一次深入理解电磁感应式无线能量传输原理、掌握开关电源控制逻辑、并锻炼嵌入式系统软硬件综合设计能力的绝佳实践。接下来我就把从电路设计、PCB打样、到代码编写、调试优化的完整过程以及其中踩过的坑和收获的经验毫无保留地分享出来。2. 核心原理与系统架构能量是如何“隔空传送”的无线充电听起来很科幻但其核心原理其实非常经典——电磁感应也就是我们中学物理就学过的法拉第定律。当发射线圈Tx中通入交变电流时周围会产生交变的磁场。这个交变磁场如果穿过接收线圈Rx就会在Rx中感应出交变的电动势从而产生电流实现电能的无线传输。但要让这个过程高效、安全、可控地发生一个简单的线圈对是远远不够的。我们需要一套完整的系统。下图清晰地展示了基于STM32的无线充电器典型系统架构它包含了能量发送端发射器和能量接收端接收器两大部分。系统整体架构框图[发射端 Tx] 220V AC - 整流滤波 - DC 5-12V - 全桥/半桥逆变 - 发射线圈 谐振电容 - 交变磁场 ↑ STM32 MCU (控制核心) ├── PWM生成 (驱动MOSFET) ├── ADC采样 (输入电压、电流、线圈电压相位) ├── 通信模块 (如蓝牙/Wi-Fi用于状态上报/控制可选) └── 异物检测电路 (FOD) [接收端 Rx] 交变磁场 - 接收线圈 谐振电容 - 整流滤波 - DC 5V/9V - 负载设备 ↑ DC-DC稳压 (可选) ↑ 通信解码 (如通过负载调制向Tx发送功率需求)这个架构图揭示了我们设计的几个关键层面2.1 谐振是关键为什么需要电容仔细观察无论是发射线圈还是接收线圈都并联或串联了一个电容。这不是随便加的而是为了构成LC谐振电路。线圈本身有电感L我们并联一个电容C使其谐振频率与我们驱动电路产生的交变电流频率一致。当电路工作在谐振点时线圈两端的电压会达到最大串联谐振则是电流最大从而极大地提升了能量传输的效率。可以把它想象成推秋千如果你每次都在秋千荡到最高点的那一刻用力推频率匹配就能用很小的力让秋千荡得很高高效传输。如果乱推一气频率不匹配不仅费劲效果还差。在我们的设计中通常让系统工作在100-200kHz这个频段。STM32的定时器可以非常精准地产生这个频率范围的PWM波这是专用芯片方案难以比拟的灵活性。2.2 逆变与驱动把直流电“摇起来”发射端输入的通常是5V或12V的直流电来自适配器或电池。我们需要把它变成高频交流电去驱动线圈。这个任务由全桥或半桥逆变电路完成由四个或两个功率MOSFET组成受STM32产生的四路互补PWM信号控制轮流导通从而在线圈上产生正负交替的电压。这里STM32的定时器高级功能如互补输出、死区时间插入就派上了大用场。死区时间是为了防止同一桥臂上下两个MOSFET同时导通造成短路这个时间通常设置在几百纳秒STM32可以轻松配置。2.3 闭环控制让系统“聪明”起来一个开环的无线充电器是危险且低效的。STM32的核心价值就在于实现闭环控制。我们通过ADC实时采样发射端的输入电流、输入电压以及通过一些电路如电流互感器、电压相位检测电路间接感知接收端的负载状态。例如过流/过压保护当ADC采样的电流或电压超过设定阈值STM32会立即关闭PWM输出保护后级电路和设备。功率调节接收端可以通过负载调制轻微改变自身谐振参数等方式向发射端“传递”信息比如“我需要5V/1A”或“我需要9V/2A”。发射端的STM32通过检测线圈电压/电流的微小变化来解码这个信息然后动态调整PWM的占空比或频率改变输出功率实现类似QC协议的快充功能。异物检测这是安全性的重中之重。如果在发射线圈上放了一个金属异物如钥匙、硬币它会因为涡流效应而迅速发热可能引发危险。FOD功能通常通过监测发射端功率和效率来实现。STM32会持续计算“输入功率 - 预估接收功率”如果这个差值过大意味着有很大一部分功率被非接收线圈的物体消耗了就会触发报警并停止充电。3. 硬件设计深潜从原理图到PCB的每一个细节理论懂了接下来就是动手画板子。硬件设计是项目的基石这里每一个元器件的选型、每一个走线的考量都直接影响最终的性能、效率和稳定性。3.1 主控与电源电路我选择的是STM32F103C8T6也就是常说的“蓝色药丸”核心板同款MCU。它拥有72MHz主频、足够的定时器TIM1高级定时器用于产生带死区的PWM再好不过、多个ADC通道价格还非常亲民。电源部分分为两级输入级采用一个宽电压输入的DC-DC降压模块如MP1584将适配器提供的12V-24V直流电稳定到5V给STM32和后续的驱动芯片供电。这里有个坑这个5V电源的纹波一定要小最好在输出电容上并联一个104的瓷片电容滤除高频噪声否则可能会干扰STM32的ADC采样精度导致电流检测不准。驱动级全桥MOSFET的栅极驱动需要独立的电源。我选用了一颗半桥驱动芯片IR2104S。它自带自举电路可以用单一电源驱动一个桥臂的上管和下管。关键点在于自举电容和二极管的选择自举电容通常用10uF的电解电容并联一个0.1uF的瓷片电容二极管要选用快恢复二极管如1N4148确保在高频开关下能快速续流。3.2 功率与谐振电路这是能量传输的“心脏”。MOSFET选型耐压要高于输入电压的2倍以上如输入12V选30V以上导通电阻Rds(on)要尽可能小如10mΩ以内以降低导通损耗和发热。我选用的是AO3400PMOS和AO3401NMOS配对便宜好用。谐振电容必须选用高频、低ESR等效串联电阻、高耐压的CBB电容或NP0瓷介电容千万不能用普通的电解电容或涤纶电容它们在高频下的损耗极大会严重发热并降低Q值导致效率暴跌。电容值需要根据线圈电感量精确计算公式为 f 1 / (2π√LC)。可以先用电感表测出线圈电感再计算所需电容。线圈设计线圈是天线其形状圆形、方形、匝数、线径、绕制方式单层、多层、以及是否有磁芯如铁氧体磁片都直接影响耦合系数和传输距离。对于DIY最简单有效的方法是直接购买成品的Qi标准线圈模块它们已经优化好了电感和Q值。如果想自己绕可以用利兹线多股细线绞合来减少高频趋肤效应带来的损耗。3.3 采样与保护电路电流采样在输入总回路上串联一个毫欧级的采样电阻如0.01Ω/3W用STM32的ADC采集电阻两端的电压差再根据欧姆定律算出电流。这里必须使用差分放大电路如用运放INA199将微弱的电压信号放大到ADC的量程范围内如0-3.3V。采样电阻的功率一定要够否则一上大电流就会烧毁。电压相位检测用于实现异物检测和通信。一种常见方法是用一个小的电流互感器CT感应线圈电流将其转换成电压信号再用一个电压比较器如LM393将其整形成方波。将这个方波和驱动PWM的方波一起送入STM32的输入捕获通道通过测量两者的相位差可以判断负载状态的变化。布局与布线要点强弱电分离数字地MCU部分、模拟地采样放大部分、功率地MOSFET和线圈部分要采用单点共地通常用0欧电阻或磁珠在一点连接避免功率部分的大电流噪声窜入敏感的采样电路。大电流路径从输入电源到MOSFET再到线圈的路径要尽可能短、粗用铺铜的方式处理以减少寄生电阻和电感带来的损耗。高频路径PWM驱动信号线、连接到线圈的走线都属于高频信号线要远离模拟采样线并尽量短。可以在驱动芯片输出端串接一个几欧姆的小电阻有助于减缓信号边沿减少振铃和EMI。4. 软件逻辑构建STM32的代码如何让硬件“活”起来硬件是躯体软件是灵魂。STM32的程序需要精准地协调各个外设实现稳定的能量传输和智能控制。4.1 外设初始化与基础驱动首先使用STM32CubeMX进行图形化配置可以事半功倍。时钟树将系统时钟设置为最高72MHz确保定时器有足够的计数频率来产生精确的PWM。定时器TIM1配置为中央对齐模式PWM生成通道1和通道1N互补、通道2和通道2N分别驱动全桥的两个桥臂。关键参数预分频器PSC和自动重载值ARR共同决定PWM频率。例如72MHz主频想要150kHz的PWM则计数频率可先预分频到72MHz/172MHzARR设置为 (72MHz / 150kHz) / 2中央对齐模式需除以2 ≈ 240。死区时间Dead Time根据MOSFET的开关速度设置通常200-500ns在CubeMX里直接填入纳秒数即可自动计算寄存器值。ADC配置用于电流和电压采样的通道为规则组使用定时器触发如用TIM2的更新事件触发实现固定频率的自动采样不占用CPU资源。开启DMA将采样结果直接搬运到内存数组中。串口UART用于调试信息打印方便观察系统状态、电压电流值、故障代码等。4.2 核心控制逻辑与状态机整个充电过程应该由一个清晰的状态机来管理这是程序结构清晰、运行稳定的保证。我设计的状态机大致如下状态IDLE待机 ├── 条件检测到有物体放置通过ADC采样到的输入电流微小变化判断 ├── 动作开启低占空比PWM进入“ping”阶段 └── 跳转- PINGING 状态PINGING探测 ├── 条件检测接收端反馈的信号如通过相位检测解码出设备身份 ├── 动作如果是合法设备则协商功率如5W/10W └── 跳转- CHARGING如果是异物或无响应- ERROR 状态CHARGING充电 ├── 动作根据协商的功率设定目标电流/电压值。运行闭环PID控制根据ADC采样的实际电流与目标电流的差值动态调整PWM占空比实现恒流/恒压充电。同时周期性执行FOD计算。 ├── 条件1FOD检测到异常 │ └── 跳转- ERROR ├── 条件2接收端发送“充电结束”信号或设备被移除电流降至阈值以下 │ └── 跳转- IDLE └── 条件3ADC检测到过流或过压 └── 跳转- ERROR 状态ERROR错误 ├── 动作立即关闭PWM输出通过LED或串口指示错误类型如FOD错误、过流错误。 ├── 条件错误状态持续一段时间或人工复位 └── 跳转- IDLE这个状态机在main函数的while(1)循环中不断查询和切换逻辑非常清晰。4.3 PID闭环控制实现在CHARGING状态下我们需要让输出功率稳定在设定值。以恒流充电为例我们控制的目标是让采样电流等于目标电流。// 简化版PID增量式算法示例 float PID_Calculate(float target, float actual) { static float integral 0, last_error 0; float error target - actual; integral error; // 积分项 // 积分限幅防止积分饱和 if(integral INTEGRAL_MAX) integral INTEGRAL_MAX; if(integral -INTEGRAL_MAX) integral -INTEGRAL_MAX; float derivative error - last_error; // 微分项 last_error error; float output KP * error KI * integral KD * derivative; // 输出限幅对应PWM占空比范围 if(output OUT_MAX) output OUT_MAX; if(output OUT_MIN) output OUT_MIN; return output; } // 在定时中断中调用 void TIM2_IRQHandler() { // 假设TIM2触发ADC采样 if(ADC采样完成) { float actual_current ADC_GetCurrent(); // 获取实际电流 float duty_cycle_adjust PID_Calculate(target_current, actual_current); // 调整PWM占空比 __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, DEFAULT_DUTY duty_cycle_adjust); } }调试心得PID参数的整定是个细致活。KP比例决定了响应速度太大会振荡太小则响应慢。KI积分用于消除静差但容易引起超调。KD微分能抑制振荡。我的经验是先设KI和KD为0从小到大调KP直到系统出现轻微振荡然后取这个值的60%左右。然后加入一点KI观察稳态误差是否消除。最后微调KD来平滑响应。整个过程最好通过串口实时绘制电流曲线来看非常直观。4.4 通信与FOD算法通信解码Qi标准的基础通信是通过负载调制实现的。接收端通过并联/断开一个额外的负载轻微改变自身的谐振点从而引起发射端线圈电压和电流的相位/幅度变化。发射端通过持续监控线圈电压经过分压和滤波后ADC采样或专门的相位检测电路输出来解码这些变化。这需要编写一个简单的数字解调程序识别出长/短“通-断”脉冲进而解析出数据包。FOD实现一个简化的FOD思路是计算“传输损耗”。发射端可以精确测量输入电压Vin和输入电流Iin从而计算输入功率Pin。同时接收端通过通信协议会上报它接收到的电压Vout和电流Iout输出功率Pout。那么损耗功率 Ploss Pin - Pout。如果Ploss超过一个阈值例如在特定传输距离和功率等级下正常效率为70%那么30%的损耗是合理的如果Ploss大到对应效率低于50%就可以怀疑有异物存在。注意这种方法依赖于接收端准确上报功率对于不支持通信的简单接收器不适用。另一种更通用的方法是监测线圈的等效阻抗变化异物会导致阻抗发生特定变化这需要通过测量电压和电流的相位差来推算实现起来更复杂。5. 调试、优化与实测从“能响”到“好用”的漫长之路板子焊好程序烧录第一次上电的心情总是忐忑的。大概率它不会马上正常工作调试阶段才是真正成长的开始。5.1 上电“烟花”与静态检查我的第一次上电就伴随着一股青烟——一个MOSFET炸了。教训深刻。之后我养成了严格的静态检查习惯万用表蜂鸣档在不上电的情况下仔细检查电源正负极是否短路每个MOSFET的DS、GS之间是否短路。分步上电先用可调电源将电压限流调到很低比如5V/0.1A慢慢给板子供电观察电流读数。如果电流异常增大立刻断电。没问题再逐步提高电压和电流限值。先测控制再测功率先不接功率部分线圈和MOSFET只给STM32和驱动芯片供电用示波器测量PWM输出波形是否正确死区时间是否正常。确认控制信号无误后再连接功率部分。5.2 动态波形观测与问题定位示波器是调试电力电子电路的“眼睛”。问题1PWM波形有严重振铃。这会导致MOSFET开关损耗剧增甚至误导通。解决在MOSFET的栅极串联一个10-22Ω的电阻或者在GS之间并联一个10k的放电电阻和一个小电容几十皮法可以有效地阻尼振荡。问题2线圈两端电压波形不是漂亮的正弦波而是畸变严重。这通常意味着谐振频率不对或者驱动能力不足。解决用LC表重新测量线圈电感计算并更换谐振电容。检查驱动芯片的电源电压是否足够通常要高于MOSFET的开启电压自举电容是否充电充分。问题3ADC采样值跳动大控制不稳。这通常是电源噪声或地线干扰。解决确保模拟部分的电源经过了LC滤波。采样电阻的走线要尽量短并做成差分走线。在采样信号进入ADC之前可以加一个RC低通滤波截止频率略高于信号频率。在软件上可以采用多次采样取平均的算法。5.3 效率与发热优化一个充电器好不好效率和温升是硬指标。效率测试在输入输出端同时接入功率计或高精度万用表在不同负载如空载、0.5A、1A下记录输入功率和输出功率计算效率。我的第一版效率只有60%发热严重。优化点1同步整流。接收端传统的二极管整流桥压降大约0.7V*2损耗惊人。将其替换为用MOSFET实现的同步整流电路由接收端的MCU控制可以大幅降低损耗轻松提升效率10%以上。优化点2MOSFET选型与散热。将普通MOSFET换为更低Rds(on)的型号。如果发热依然明显必须加装散热片。PCB布局时就要为MOSFET预留出敷铜散热区域甚至安装散热片的位置。优化点3谐振参数微调。用示波器和电流探头观察线圈电流波形微调谐振电容的值使电流波形尽可能接近正弦波且幅值在所需功率下达到最大。这需要反复试验。5.4 安全性与可靠性验证这是产品化的最后一步也是对自己和他人负责。过载测试短时间输出超过额定功率50%的负载看保护电路是否迅速动作关闭输出。短路测试在输出端瞬间短路看是否能立即关断并进入错误状态且不会损坏任何器件。异物测试放置不同大小、材质的金属物体硬币、钥匙、铝箔在充电区域观察FOD功能是否能可靠触发并报警。长时间老化测试让充电器在额定功率下连续工作数小时监测其温升和输出稳定性。我用热成像仪观察发现驱动芯片和某个MOSFET是热点通过优化布局和增加散热后得到了改善。经过几轮迭代我最终实现的这个基于STM32的无线充电器在5V/1A输出时端到端效率可以达到75%以上使用同步整流支持基础的异物检测并且可以通过串口指令动态调整输出功率。虽然性能比不上顶尖的商业产品但整个过程中对电磁理论、开关电源、嵌入式闭环控制、PCB设计、调试排错的全链路实践其收获远远超过了一个成品充电器本身。它现在不仅是我桌面上一个实用的充电工具更是一个随时可以打开、修改、实验的活生生的教学平台。如果你也对硬件和嵌入式感兴趣强烈建议你从这样一个项目开始亲手触摸电子的脉搏感受代码控制能量的魅力。