software copyright

This commit is contained in:
jiahong
2026-03-22 15:24:40 +08:00
parent e303bb868a
commit 60f336e345
155 changed files with 127262 additions and 0 deletions
@@ -0,0 +1,428 @@
/*
* 自然写智能点阵笔嵌入式固件软件 V1.0
* power_monitor_task.c - 电源监测与低功耗管理任务
*
* 功能说明:
* 1. 电池电压ADC采样与电量百分比估算
* 2. 充电检测与充电状态管理
* 3. 低电量告警与自动关机保护
* 4. 低功耗状态机(Active → Light Sleep → Deep Sleep
* 5. USB充电IC状态监测
*/
#include <stdint.h>
#include <stdbool.h>
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#include "semphr.h"
#include "hal_adc.h"
#include "hal_gpio.h"
#include "power_manager.h"
#include "led_driver.h"
/* ========== 电池参数定义 ========== */
/* 电池满充电压(mV):锂聚合物3.7V标称 */
#define BATTERY_FULL_MV 4200
/* 电池截止电压(mV):低于此值必须关机保护 */
#define BATTERY_CUTOFF_MV 3300
/* 低电量告警阈值(百分比) */
#define LOW_BATTERY_THRESHOLD 10
/* 极低电量关机阈值 */
#define CRITICAL_BATTERY_THRESHOLD 3
/* ADC参考电压(mV */
#define ADC_VREF_MV 3300
/* ADC分辨率(12位) */
#define ADC_MAX_VALUE 4095
/* 电池电压分压比(电阻分压器:R1=100K, R2=100K → 2:1 */
#define BATTERY_DIVIDER_RATIO 2
/* 电压采样滤波窗口大小 */
#define VOLTAGE_FILTER_WINDOW 8
/* 电源监测周期(毫秒) */
#define POWER_MONITOR_PERIOD_MS 5000
/* 自动休眠超时(毫秒):笔静止超过此时间自动进入深度睡眠 */
#define AUTO_SLEEP_TIMEOUT_MS 300000 /* 5分钟 */
/* ========== 电源状态枚举 ========== */
typedef enum {
POWER_STATE_ACTIVE, /* 活跃状态(正常工作) */
POWER_STATE_LIGHT_SLEEP, /* 轻度睡眠(BLE保持连接) */
POWER_STATE_DEEP_SLEEP, /* 深度睡眠(仅保留RTC唤醒) */
POWER_STATE_CHARGING, /* 充电中 */
POWER_STATE_SHUTDOWN /* 关机保护 */
} PowerState;
/* ========== 外部引用 ========== */
extern EventGroupHandle_t g_ble_event_group;
extern SemaphoreHandle_t g_system_mutex;
/* 系统状态结构体(在main.c中定义) */
typedef struct {
bool pen_is_down;
bool ble_connected;
bool is_charging;
uint8_t battery_percent;
uint32_t total_strokes;
uint32_t uptime_seconds;
uint8_t error_flags;
} SystemState;
extern SystemState g_system_state;
/* ========== 静态变量 ========== */
/* 当前电源状态 */
static PowerState s_power_state = POWER_STATE_ACTIVE;
/* 电压采样滤波缓冲区 */
static uint16_t s_voltage_buffer[VOLTAGE_FILTER_WINDOW];
static uint8_t s_voltage_buffer_index = 0;
static bool s_voltage_buffer_full = false;
/* 最后一次活动时间(用于自动休眠判断) */
static uint32_t s_last_activity_time = 0;
/* ========== 电压采样与滤波 ========== */
/**
* 读取电池原始ADC值并转换为电压(mV)
*/
static uint16_t read_battery_voltage_mv(void) {
/* 读取ADC原始值 */
uint16_t adc_raw = hal_adc_read(ADC_CHANNEL_BATTERY);
/* ADC值 → 分压后电压 → 实际电池电压 */
uint32_t voltage_mv = (uint32_t)adc_raw * ADC_VREF_MV / ADC_MAX_VALUE;
voltage_mv *= BATTERY_DIVIDER_RATIO;
return (uint16_t)voltage_mv;
}
/**
* 移动平均滤波
* 对连续采样的电压值取平均,消除ADC噪声
*
* @param new_sample 新采样的电压值(mV
* @return 滤波后的电压值
*/
static uint16_t voltage_filter(uint16_t new_sample) {
s_voltage_buffer[s_voltage_buffer_index] = new_sample;
s_voltage_buffer_index = (s_voltage_buffer_index + 1) % VOLTAGE_FILTER_WINDOW;
if (s_voltage_buffer_index == 0) {
s_voltage_buffer_full = true;
}
uint8_t count = s_voltage_buffer_full ? VOLTAGE_FILTER_WINDOW : s_voltage_buffer_index;
uint32_t sum = 0;
uint8_t i;
for (i = 0; i < count; i++) {
sum += s_voltage_buffer[i];
}
return (uint16_t)(sum / count);
}
/* ========== 电量百分比估算 ========== */
/**
* 根据电池电压估算电量百分比
* 使用分段线性插值模拟锂电池放电曲线
*
* 锂聚合物电池典型放电曲线(近似分段线性):
* 4200mV → 100%
* 4060mV → 90%
* 3920mV → 80%
* 3830mV → 70%
* 3750mV → 60%
* 3680mV → 50%
* 3620mV → 40%
* 3570mV → 30%
* 3500mV → 20%
* 3400mV → 10%
* 3300mV → 0%
*/
static uint8_t estimate_battery_percent(uint16_t voltage_mv) {
/* 放电曲线查找表(电压mV → 百分比) */
static const struct {
uint16_t voltage;
uint8_t percent;
} discharge_curve[] = {
{4200, 100},
{4060, 90},
{3920, 80},
{3830, 70},
{3750, 60},
{3680, 50},
{3620, 40},
{3570, 30},
{3500, 20},
{3400, 10},
{3300, 0}
};
const uint8_t table_size = sizeof(discharge_curve) / sizeof(discharge_curve[0]);
/* 边界检查 */
if (voltage_mv >= discharge_curve[0].voltage) {
return 100;
}
if (voltage_mv <= discharge_curve[table_size - 1].voltage) {
return 0;
}
/* 分段线性插值 */
uint8_t i;
for (i = 0; i < table_size - 1; i++) {
if (voltage_mv >= discharge_curve[i + 1].voltage) {
uint16_t v_high = discharge_curve[i].voltage;
uint16_t v_low = discharge_curve[i + 1].voltage;
uint8_t p_high = discharge_curve[i].percent;
uint8_t p_low = discharge_curve[i + 1].percent;
/* 线性插值 */
uint16_t v_range = v_high - v_low;
uint16_t v_offset = voltage_mv - v_low;
return p_low + (uint8_t)((uint32_t)v_offset * (p_high - p_low) / v_range);
}
}
return 0;
}
/* ========== 充电检测 ========== */
/**
* 检测USB充电状态
* 通过GPIO读取充电IC的状态引脚
*
* @return 0=未充电, 1=充电中, 2=充满
*/
static uint8_t detect_charging_state(void) {
/* STAT1引脚:低电平=充电中,高电平=充满或未充电 */
bool stat1 = hal_gpio_read(GPIO_CHARGE_STAT1);
/* STAT2引脚:低电平=充满 */
bool stat2 = hal_gpio_read(GPIO_CHARGE_STAT2);
/* USB电源检测引脚 */
bool usb_power = hal_gpio_read(GPIO_USB_DETECT);
if (!usb_power) {
return 0; /* USB未连接,未充电 */
}
if (!stat1) {
return 1; /* 充电中 */
}
if (!stat2) {
return 2; /* 充满 */
}
return 0;
}
/* ========== LED状态指示 ========== */
/**
* 根据电源状态和电量更新LED指示
*/
static void update_led_indication(uint8_t battery_percent, uint8_t charge_state) {
if (charge_state == 1) {
/* 充电中:绿色呼吸灯 */
led_set_mode(LED_MODE_BREATH_GREEN);
} else if (charge_state == 2) {
/* 充满:绿色常亮 */
led_set_mode(LED_MODE_SOLID_GREEN);
} else if (battery_percent <= LOW_BATTERY_THRESHOLD) {
/* 低电量:红色慢闪 */
led_set_mode(LED_MODE_BLINK_RED);
} else if (battery_percent <= CRITICAL_BATTERY_THRESHOLD) {
/* 极低电量:红色快闪 */
led_set_mode(LED_MODE_FAST_BLINK_RED);
} else if (g_system_state.ble_connected) {
/* 已连接:蓝色常亮 */
led_set_mode(LED_MODE_SOLID_BLUE);
} else {
/* 未连接:蓝色慢闪 */
led_set_mode(LED_MODE_BLINK_BLUE);
}
}
/* ========== 低功耗管理 ========== */
/**
* 进入轻度睡眠模式
* 关闭不必要的外设,降低CPU频率
* BLE连接保持,可被笔尖触摸或BLE命令唤醒
*/
static void enter_light_sleep(void) {
if (s_power_state == POWER_STATE_LIGHT_SLEEP) {
return;
}
/* 关闭摄像头 */
camera_power_off();
/* 关闭SPI(传感器通信) */
hal_spi_disable(SPI_PORT_1);
/* 降低CPU频率到16MHz */
SystemClock_SetLow();
/* LED关闭 */
led_set_mode(LED_MODE_OFF);
s_power_state = POWER_STATE_LIGHT_SLEEP;
}
/**
* 进入深度睡眠模式
* 关闭所有外设和BLE,仅保留RTC和GPIO唤醒
* 适用于长时间不使用的场景
*/
static void enter_deep_sleep(void) {
/* 断开BLE连接 */
ble_gatt_disconnect();
ble_gatt_stop_advertising();
/* 关闭所有外设 */
camera_power_off();
hal_spi_disable(SPI_PORT_1);
hal_i2c_disable(I2C_PORT_1);
hal_adc_disable(ADC_CHANNEL_BATTERY);
/* 保存系统状态到Flash */
offline_storage_flush();
/* 配置唤醒源(笔尖GPIO中断唤醒) */
hal_gpio_set_wakeup(GPIO_PEN_TIP_PIN, GPIO_WAKEUP_RISING);
/* 进入MCU深度睡眠模式(不应返回) */
hal_enter_deep_sleep();
}
/**
* 从轻度睡眠唤醒,恢复正常工作状态
*/
static void wake_from_light_sleep(void) {
/* 恢复CPU频率 */
SystemClock_Config();
/* 重新使能SPI */
hal_spi_enable(SPI_PORT_1);
s_power_state = POWER_STATE_ACTIVE;
s_last_activity_time = xTaskGetTickCount();
}
/* ========== 电源监测主任务 ========== */
/**
* 电源监测任务(FreeRTOS任务函数)
*
* 运行流程:
* 1. 定期读取电池电压并估算电量
* 2. 检测充电状态
* 3. 低电量告警和自动关机保护
* 4. 更新LED状态指示
* 5. 自动休眠判断
*/
void power_monitor_task(void *pvParameters) {
(void)pvParameters;
TickType_t last_wake_time = xTaskGetTickCount();
s_last_activity_time = last_wake_time;
while (1) {
/* 读取并滤波电池电压 */
uint16_t raw_mv = read_battery_voltage_mv();
uint16_t filtered_mv = voltage_filter(raw_mv);
/* 估算电量百分比 */
uint8_t battery_percent = estimate_battery_percent(filtered_mv);
/* 检测充电状态 */
uint8_t charge_state = detect_charging_state();
/* 更新全局系统状态 */
if (xSemaphoreTake(g_system_mutex, pdMS_TO_TICKS(100)) == pdTRUE) {
g_system_state.battery_percent = battery_percent;
g_system_state.is_charging = (charge_state == 1);
xSemaphoreGive(g_system_mutex);
}
/* 更新LED指示 */
update_led_indication(battery_percent, charge_state);
/* 低电量告警处理 */
if (battery_percent <= LOW_BATTERY_THRESHOLD && charge_state == 0) {
/* 通知上位机低电量 */
xEventGroupSetBits(g_ble_event_group, EVT_LOW_BATTERY);
}
/* 极低电量自动关机保护 */
if (battery_percent <= CRITICAL_BATTERY_THRESHOLD && charge_state == 0) {
enter_deep_sleep();
}
/* 充电状态变化通知 */
if (charge_state > 0) {
xEventGroupSetBits(g_ble_event_group, EVT_CHARGING);
s_power_state = POWER_STATE_CHARGING;
s_last_activity_time = xTaskGetTickCount();
}
/* 自动休眠检查:笔没有书写且BLE空闲超时 */
if (!g_system_state.pen_is_down && charge_state == 0) {
uint32_t idle_time = (xTaskGetTickCount() - s_last_activity_time)
* portTICK_PERIOD_MS;
if (idle_time > AUTO_SLEEP_TIMEOUT_MS) {
if (s_power_state == POWER_STATE_ACTIVE) {
enter_light_sleep();
} else if (idle_time > AUTO_SLEEP_TIMEOUT_MS * 2) {
/* 静止超过10分钟,进入深度睡眠 */
enter_deep_sleep();
}
}
} else {
/* 有活动,重置计时器 */
s_last_activity_time = xTaskGetTickCount();
if (s_power_state == POWER_STATE_LIGHT_SLEEP) {
wake_from_light_sleep();
}
}
/* 休眠到下一个监测周期 */
vTaskDelayUntil(&last_wake_time, pdMS_TO_TICKS(POWER_MONITOR_PERIOD_MS));
}
}
/* ========== 外部查询接口 ========== */
/** 获取当前电量百分比(供其他模块调用) */
uint8_t power_get_battery_percent(void) {
return g_system_state.battery_percent;
}
/** 获取当前电源状态 */
uint8_t power_get_state(void) {
return (uint8_t)s_power_state;
}