一、什么是无线充电无线充电也称为感应充电或非接触式充电设备无需通过传统电缆连接电源只需与无线充电发射线圈靠近即可实现充电。应用在桌面的场景可以提高桌面的整洁度在公共场所可以提供便携式服务。其工作原理发射端TX电源提供直流电 → 桥式逆变器全桥/半桥把直流斩成高频方波 → 经谐振网络线圈 L 串联谐振电容 C形成高频交变电流 → 在空间建立交变磁场。接收端RX线圈处于交变磁场中感应出高频交流电压 → 同步整流 → 直流稳压 → 给负载充电。以 WPC Qi 标准为例工作频率覆盖约 110 kHz ~ 205 kHz按功率等级分为 BPP5 W、EPP10~15 W。两个线圈之间除了传能量还要传数据用于协商协议接收端到发射端调制方式ASK负载调制RX通过改变自身负载-发射阻抗变化-TX线圈检测电流/电压变化获取数据可以通过ASK向TX发送信号强度包SS、识别包 ID、配置包 CFG、控制误差包 CE、结束包 RP 等。发射端到接收端调制方式FSK调频通过调频向RX发送频率/功率调整指示。发射端在通讯过程要做的事情1、通过报文识别RX端的设备信息2、通过获取到的信息控制给出去多大功率3、通过PWM控制桥臂调整输出的功率。二、发射端的工作逻辑本文用CH248的15W通用版本的工程举例协议流程模拟 PING → 数字 PING → 识别配置 → 协商 → 功率传输 → 结束/异常由库libWirelessPower.a实现用户层可以通过这些回调参与控制调用顺序由协议库掌控用户代码只填回调 app_cfg_init() → 上电参数配置死区、9V/12V、低功耗、是否弹窗 ↓ (模拟PING / 数字PING / 识别配置) get_cur_q_ref() → 异物判定阈值 get_isen_state() → PING 期间的电流判定 qi_ce_handle() → 功率传输阶段处理 RX 的 CE 误差包 qi_rp_handle() → 动态 FOD功率损耗法异物检测 ntc_check() / vhv_check() / over_isen_check() / osc_check() → 各类保护 led_rdy2work() / led_full() / led_rdy2full() / led_tog() → 状态灯 blind_callback() / remove_device()1.异物检测Q值检测 / 检测PING过程电流待机时发射端周期性发出很短的探测脉冲通过测量线圈的谐振电压Q值判断上面有没有物体、是不是金属异物。阈值随输入电压档位变化。void get_cur_q_ref(uint16_t meas) { if(pwm_ctrl.bit_watch_mode 0) { if(volt_state.bit_fastcharge 0) expt.q_value_ref Q_VALUE_LTHRD; else expt.q_value_ref Q_VALUE_HTHRD; if(volt_state.bit_highvol) expt.q_value_ref Q_VALUE_HHTHRD; } ... }Q值判断阈值可以在user_proc.h文件中修改。//实测6.95uH68n300n 127K/320K重点是兼顾苹果耳机观察苹果耳机过温后感应到的值不灵敏 // 5V空载84/45耳机3mm Q值66,阈值设70苹果手表3mm Q值27,设置35 // 9V空载76/48耳机3mm Q值60,阈值设64; 苹果手表3mm Q值34,设置38 // 12V空载105/67,耳机3mm Q值83,阈值设90; 苹果手表3mm Q值45,设置53 #define Q_VALUE_LTHRD 70 /* 5V下判断的阈值 */ /* 如果待机报错,可以查看当前ADC值来适配 */ #define Q_VALUE_HTHRD 64 /* 9V下判断阈值 */ #define Q_VALUE_HHTHRD 90 /* 12V下判断阈值 */ #define Q_VALUE_WTH_LTHRD 35 #define Q_VALUE_WTH_HTHRD 38 #define Q_VALUE_WTH_HHTHRD 53当线圈上有放置金属时Q值检测就会减小Q 值被金属拉低到阈值以下之后会触发FOD。另一个独立的判据是 PING 电流法数字 PING 时如果电流远大于正常设备金属会大量吸能直接判异物if( adc_temp max_rmv_isen ) /* 电流超过 1.6A/0.8A 阈值 */ { expt.fod_cnt | 0x80; if(expt.fod_cnt0x40) expt.fod_cnt 0x80; expt.fod_cnt; /* 连续多次命中 → 累积判定 */ ... }线圈谐振电压、输入电流、输入电压、NTC 温度全部靠 ADC 轮询采样通道切换逻辑void adc_set_osc( void ) { ADC1-RSQR3 ADC_Channel_OSC; } /* 线圈谐振电压 */ void adc_set_isen( void ) { ADC1-RSQR3 ADC_Channel_ISP; } /* 输入电流(ISP脚) */ void adc_set_vhv( void ) { ADC1-RSQR3 ADC_Channel_VHV; } /* 输入电压(20%分压) */ void adc_set_ntc( void ) { GPIOA-CFGLR ~0x0F000000; /* PA6 模拟输入 */ ADC1-RSQR3 ADC_Channel_NTC; }2. 数字 PING → 识别 → 配置 → 协商电压数字 PING 给线圈足量能量后RX 被唤醒并依次回包信号强度包 SS告知耦合强度→ 识别包 ID/ 扩展识别包→ 配置包 CFG自身最大功率能力。发射端从 CFG 得知对方是 5 W / 10 W / 15 W 档从而确定限功率上限#define MAX_WATT_LIMIT 341000 /* 22W 22000 * 15.5 */ #define MAX_AP_WATT_LIMIT 186000 /* 12W 12000 * 15.5 苹果 127K 定频模式 */ #define MAX_WATCH_WATT_LIMIT 46500 /* 3W 3000 * 15.5 手表 */随后进入协商阶段RX 请求更高电压以提高效率发射端按配置决定给 9 V 还是 12 Vvoid app_cfg_init( void ) { usercfg.bit_vhv12_prefer 0; /* 默认请求9V电压置1则优先请求12V */ usercfg.pwm_dead_time 5; /* 桥臂死区时间 5/48 us ≈ 104ns */ usercfg.pwm_dt_forword 3; /* 另一侧半桥的独立死区用于压缩死区 */ ... }3. 功率传输CE 包 → PID → 调频/调占空比这是闭环的核心。RX 每个控制周期返回一个 CEControl Error包对比输出和需要的功率。符号决定加功率还是减功率slow_adj 0; pwm_ctrl.bit_power_dir 0; if(dat 0x80) /* 最高位为符号负值请求降功率 */ { dat 0-dat; pwm_ctrl.bit_power_dir 1; }在调节之前先做安全钳位顺序很关键先欠压、再过流最后才允许按 CE 调功率adc_set_vhv(); vs_temp adc_sample_x4(); if(vs_temp uvlo_thrdvalue) { pwm_ctrl.bit_power_dir 1; power_proc(1); } /* 欠压 → 降功率 */ else { adc_set_isen(); is_temp adc_start(); if(pwm_ctrl.bit_127k_mode) max_isen MAX_AP_WATT_LIMIT/vs_temp; /* 苹果 127K 定频模式 */ else max_isen is_watch_device() ? (MAX_WATCH_WATT_LIMIT/vs_temp) : (MAX_WATT_LIMIT/vs_temp); /* 限功率 限流*mA */ if(max_isen MAX_ISEN_LIMIT) max_isen MAX_ISEN_LIMIT; /* 硬件物理上限 2.3A */ if(is_temp max_isen) { pwm_ctrl.bit_power_dir 1; power_proc(1); } /* 过流 → 降功率 */ else { ... 按 CE 调功率pid_process(dat); } }注意MAX_WATT_LIMIT/vs_temp是把功率上限换算成电流上限而ADC_V*ADC_I的单位就是毫瓦——所以限功率最终落在限流上这也是输入电压越高、允许的输入电流越小的原因。调功率的具体动作由库函数power_proc()/pid_process()执行最终表现为改变桥臂的开关频率必要时叠加占空比调节。在库中还提供了打印能直接观察到调功结果is_temp 48000/(TIM1-ATRLR1); printf(freq:%d ,is_temp); if(pwm_ctrl.bridge_mode BIT_BR_MODE_HALF) { is_temp bridge_duty_get(); is_temp is_temp*100/(TIM1-ATRLR1); printf(duty:%d half,is_temp); /* 半桥调占空比 */ } else { is_temp bridge_duty_get(); is_temp is_temp*100/(TIM1-ATRLR1); printf(duty:%d full,is_temp); /* 全桥调频率为主 */ }4. 保护过温降功率、过压、动态 FOD、异常移除过温是两级处理超过 80 ℃ 直接停机超过 70 ℃ 只把输出功率压到 5.5 W 以内回到 60 ℃ 以下再解锁adc_set_ntc(); adc_temp adc_start(); adc_ntc_release(); /* PA6 切回推挽复用 LED */ if(adc_temp NTC_TRIG_VALUE) { expt.bit_ntc_trig 1; remove_device(); } else if(adc_temp NTC_ADJ_VALUE) expt.bit_ntc_lock 1; /* 限功率点 */ else expt.bit_ntc_lock 0; /* 解锁 */动态 FOD功率损耗法同时测量输入功率UI和 RX 上报的接收功率RP两者之差就是凭空消失的功率超过阈值即认为是金属异物发热ui_mw get_input_power_in_mw(); /* 采样输入电压、电流算得 mW */ if(ui_mw MIN_FOD_PWR) /* 小功率时不准不计算 */ { loss_th (ui_mw*4)/15 1666; /* 允许损耗门限随功率线性放宽 */ rp_mw dat * 39; /* 5W档10W/15W 依次 78 / 117 */ dt_mw ui_mw - rp_mw; if(dt_mw loss_th) { expt.fod_cnt; if(expt.fod_cnt FOD_CHECK_MAXCNT) /* 连续 3 次异常才判 FOD */ { expt.bit_is_thing 0; return 1; /* 触发 FOD */ } } else expt.fod_cnt 0; }此外还有输入欠压/过压vhv_check()13.3 V 以上或 3.8 V 以下停机、实时过流over_isen_check()超 2.4 A 直接降功率、线圈谐振电压限幅osc_check()1.8 V 锁定限幅 / 2 V 直接停机。5. 结束与异常充电完成收到充满/结束包 RP、温度/电压触发保护、异物触发 FOD、设备被移走都会回到待机重新 PING。静态 FOD 还有超时 2 分钟重试或死等移除两种策略由usercfg.bit_fod_notry选择。
阅读完成 · 觉得有帮助?