提示:本文内容仅供学习参考。Author: Jonnie Walker CGC
目录
前言
最近在做一个低功耗项目,所以应用了这个低功耗开关机电路,就此将其分享给大家!
具体功能描述请看往下看。
一、电路的设计指标?
静态电流 (I_q) 关机状态下的漏电流,理想值应 < 5 u A。
导通压降 (V_{drop}) 电源流过开关管(如 P-MOS)产生的损耗,由 R_{DS(on)} 决定。
输入电压范围 需匹配电池电压(如锂电 3.7V - 4.2V)。
逻辑电平 开机维持信号必须与 MCU 的逻辑电平(3.3V 或 5V)匹配。
其实也可以选择专业POWER管理IC。
二、硬件电路基本描述
图1

- 核心元件与信号路径
-
Q21(S8050):NPN型三极管,作为电子开关使用。
-
Powk:一个单刀双掷开关,用于手动触发。
- D34, D33, D1 (1N5819WS):肖特基二极管,用于单向导通和防止反向电流。
- Q4、Q5 (AO3401):P沟道MOSFET,用于电源路径的通断控制(选择静态电流小的)。
- R203上拉电阻、R1下拉电阻,确保MOSFET栅极在无驱动时可靠关断与导通。
- R205限流电阻,控制Q21的基极电流。
- R204:上拉电阻,为GPIO-KEY信号提供默认稳定高电平。
(1)手动开机/唤醒功能(Powk按键)
- 当Powk按下时,触点1-2导通, GPIO-KEY 信号被拉低。
- 这个低电平信号可以被MCU检测到,作为开机/唤醒的触发信号。
(2)电池供电路径控制
-
BAT-OUT:电池正极输入。
-
GPIO-POWER:使能控制信号输入(开机后需要MCU维持逻辑电平)。
-
当 GPIO-POWER 为高电平时:
- 电流经R205(R168释放Q4寄生电容能量),使Q21基极获得足够电流,Q21导通。
2. Q21导通后,其集电极(连接到Q4的栅极)被拉低。
3. Q4和Q5是P沟道MOSFET,栅极(G)为低电平时,源极(S)和漏极(D)之间导通。
4. 电池正极 BAT-OUT经Q4输出,同时经Q5连接到系统 VCC ,为整个系统供电。
- 当 GPIO-POWER 为低电平时:
-
Q21基极无电流,Q21截止。
-
Q4的栅极通过R203被上拉到 BAT-OUT ,MOSFET关断,电池供电被切断。(Q5通过R1下拉默认一直处于导通状态)
(3)二极管的作用
-
D33:防止 GPIO-KEY 信号被 BAT+-OUT倒灌,确保按键触发的独立性。
-
D34:防止Q21导通时, BAT-OUT 的电压倒灌到按键电路,保护Powk和相关元件。
-
D1:防止电压倒灌,隔离保护相关元件。
开关机电路:从源头切断整个系统的供电。对于需要放置数月不充电的电池供电设备,物理级的电源切断是必须的。
二、软件基本描述
软件基于ESP32设计的。思想是一样的!做一些调整即开加入自己的项目中。
Arduino代码:
cpp
/*
* 一键开关机电路控制程序
* 硬件连接:
* - GPIO_POWER (IO10): 连接 Q21 的基极电阻,高电平维持供电
* - GPIO_KEY (IO11): 连接按键检测点,低电平表示按键按下
*/
const int PIN_POWER_LATCH = 10; // GPIO_POWER
const int PIN_BUTTON_DET = 11; // GPIO_KEY
// 关机所需的长按时间(毫秒)
const unsigned long SHUTDOWN_TIME = 2000;
void setup() {
// 1. 【最关键】立即将维持引脚设为高电平,完成自锁
// 这一步必须放在 setup 的最前面
pinMode(PIN_POWER_LATCH, OUTPUT);
digitalWrite(PIN_POWER_LATCH, HIGH);
// 2. 初始化按键检测引脚
pinMode(PIN_BUTTON_DET, INPUT); // 电路已有外部上拉 R204
Serial.begin(115200);
Serial.println("系统已上电并完成自锁");
}
void loop() {
static unsigned long buttonPressStart = 0;
static bool isPressing = false;
// 读取按键状态(按下为 LOW)
if (digitalRead(PIN_BUTTON_DET) == LOW) {
if (!isPressing) {
// 记录按下的初始时间
buttonPressStart = millis();
isPressing = true;
Serial.println("检测到按键按下...");
}
// 如果按下时间超过预设阈值
if (millis() - buttonPressStart > SHUTDOWN_TIME) {
executeShutdown();
}
} else {
if (isPressing) {
isPressing = false;
Serial.println("按键已松开");
}
}
// 正常的系统逻辑
// ...
}
void executeShutdown() {
Serial.println("执行关机序列...");
// 可以在这里添加保存数据、关闭外设的操作
delay(500);
// 释放维持信号,Q21 截止 -> Q4 截止 -> 系统断电
digitalWrite(PIN_POWER_LATCH, LOW);
// 进入死循环等待彻底断电
while (true) {
delay(100);
}
}
ESP-IDF(v5.0及以上版本)代码:
cpp
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
// 引脚定义(根据电路图)
#define GPIO_POWER_LATCH GPIO_NUM_10 // IO10
#define GPIO_KEY_DET GPIO_NUM_11 // IO11
#define SHUTDOWN_HOLD_TIME_MS 2000 // 长按 2 秒关机
static const char *TAG = "POWER_CTRL";
/**
* 核心逻辑:关机执行函数
*/
void execute_system_shutdown() {
ESP_LOGI(TAG, "正在执行关机,释放 LATCH 引脚...");
// 可以在此处添加:保存 NVS 数据、关闭传感器、断开 Wi-Fi 等操作
vTaskDelay(pdMS_TO_TICKS(500));
// 释放维持信号(拉低 IO10)
gpio_set_level(GPIO_POWER_LATCH, 0);
// 进入死循环等待硬件断电
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
/**
* 按键检测任务
*/
void power_key_monitor_task(void *pvParameters) {
uint32_t press_duration = 0;
const uint32_t interval = 50; // 每 50ms 检测一次
while (1) {
// 读取按键状态(按下为 0,因为有 D34 和 Powk 接地)
if (gpio_get_level(GPIO_KEY_DET) == 0) {
press_duration += interval;
if (press_duration >= SHUTDOWN_HOLD_TIME_MS) {
execute_system_shutdown();
}
} else {
press_duration = 0; // 松开则重置计数
}
vTaskDelay(pdMS_TO_TICKS(interval));
}
}
void app_main(void) {
// 1. 【核心:第一时间自锁】配置 GPIO_POWER 为输出并拉高
gpio_config_t io_conf_power = {
.pin_bit_mask = (1ULL << GPIO_POWER_LATCH),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_conf_power);
gpio_set_level(GPIO_POWER_LATCH, 1); // 锁定电源
ESP_LOGI(TAG, "电源已锁定,系统初始化中...");
// 2. 配置 GPIO_KEY 为输入
// 注意:电路中 R204 已经是外部上拉,所以这里配置为浮空输入即可
gpio_config_t io_conf_key = {
.pin_bit_mask = (1ULL << GPIO_KEY_DET),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_conf_key);
// 3. 创建按键监控任务
xTaskCreate(power_key_monitor_task, "power_key_task", 2048, NULL, 5, NULL);
// 这里可以开始你原本的业务逻辑(比如初始化传感器、飞行控制算法等)
while (1) {
// ESP_LOGI(TAG, "系统运行中...");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
总结
这个电路是一个电池供电系统的POWER管理与唤醒电路需要配合软件才能正常工作,主要实现以下功能:
-
手动开机/唤醒:通过Powk按键拉低 GPIO-KEY 信号,通知MCU进行开机或唤醒操作。
-
自动电源控制:通过 GPIO-POWER 信号控制Q21的导通/截止,进而控制Q4一个MOSFET的通断,实现电池供电的自动开启和关闭。
-
电源路径隔离:通过肖特基二极管和MOSFET,有效隔离了按键电路、电池供电电路和系统供电电路,防止电流倒灌和误触发。
简单来说,这是一个由按键触发和外部信号控制的电池供电开关电路,常见于需要低功耗待机和一键开机的便携式设备中。
感谢你能看到这里,希望本文对你有帮助!你的点赞将是我坚持动力。
