打印
[MM32硬件]

如何用灵动MCU实现双电源状态自动切换与检测?

[复制链接]
20|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我爱台妹mmd|  楼主 | 2025-4-30 11:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用灵动MCU(如 MM32 系列)可实现锂电池 + 适配器双电源的自动切换与状态检测,适用于便携设备、UPS供电、充电管理等场景。关键在于通过 ADC采样检测两路电源电压,再由MCU逻辑控制负载电源路径(如MOS、继电器或电源选择芯片)进行切换。

功能目标
MCU通过ADC采样判断适配器是否插入或充电是否完成,实现:

电源自动选择(如优先适配器)

状态指示(如LED、上报系统)

控制充电、负载连接逻辑

一、典型硬件架构
lua
复制
编辑
   +------------+     +-------------+
   | 适配器 (5V) |────>| D1 (肖特基) |──┐
   +------------+     +-------------+  |
                                         +──> SYS 电源总线 ──> 负载/Vin
   +------------+     +-------------+  |
   | 锂电池 (3.7V) |───> D2 (肖特基) |──┘
   +------------+     +-------------+

   ADC1 ←── 采样适配器电压(分压后)
   ADC2 ←── 采样电池电压(分压后)

   GPIO 控制:MOSFET/充电模块/电源切换芯片
D1/D2:肖特基二极管自动OR,避免电流回流

ADC:采样两个电源输入电压

控制输出:可驱动电源开关、LDO或充电芯片EN脚

二、软件检测逻辑(代码)
c
复制
编辑
#define THRESHOLD_ADAPTER_ON   4.5   // 适配器电压识别阈值
#define THRESHOLD_BATTERY_LOW  3.5   // 电池欠压阈值

bool adapter_online = false;
bool battery_low = false;

void check_power_sources() {
    float v_adapter = read_adapter_voltage();  // ADC + 分压换算
    float v_battery = read_battery_voltage();

    adapter_online = (v_adapter > THRESHOLD_ADAPTER_ON);
    battery_low = (v_battery < THRESHOLD_BATTERY_LOW);

    if (adapter_online) {
        enable_load();         // 连接适配器电源供电
        enable_charging();     // 打开电池充电功能
    } else if (!adapter_online && !battery_low) {
        enable_load();         // 电池直接供电
        disable_charging();
    } else {
        disable_load();        // 欠压保护:关闭负载
        blink_warning_led();
    }
}
三、自动切换机制建议

模式        描述
优先适配器供电        使用肖特基二极管OR电路或MOS切换器,如双P-MOS+互锁控制
MCU控制MOS        采样判断后由GPIO控制MOS导通通断,实现软件控制切换
硬件辅助        可选用专用电源切换芯片(如 AP4310、FS8205 等)实现快速切换
状态输出        LED、蜂鸣器、串口/IO上传当前供电状态
四、供电管理常见问题及建议

问题        建议
电压判断不稳定        增加软件滤波或ADC平均
电池欠压时仍供电        设置保护阈值 + GPIO断开负载
切换瞬间电压抖动        加RC缓冲、电源旁路电容
MCU断电失控        使用双电源LDO或RTC独立供电维持MCU运行
电源反接保护        所有电源输入前加入反接保护二极管
示例:分压读取适配器/电池电压
c
复制
编辑
float read_adapter_voltage() {
    uint16_t adc_val = ADC_Read(ADC_CH_ADAPTER);
    float v_adc = (adc_val / 4095.0f) * 3.3;
    return v_adc * 分压系数;
}

float read_battery_voltage() {
    uint16_t adc_val = ADC_Read(ADC_CH_BATTERY);
    float v_adc = (adc_val / 4095.0f) * 3.3;
    return v_adc * 分压系数;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

71

主题

646

帖子

0

粉丝