进一步优化CH585M的低功耗模式

电池供电应用场合要进一步优化CH585M的低功耗模式,围绕PMU模式精细化、时钟/外设管控、RAM动态保留、唤醒流程精简四大核心维度,结合CH585M的硬件特性(如多级别PMU模式、RAM保留分级),以下是可直接集成到代码包的优化方案:

一、精细化PMU模式与RAM保留配置(核心功耗优化)

CH585M的下电模式功耗与RAM保留大小、PMU模式选择强相关,需按需匹配最小资源占用:

1. 动态调整RAM保留大小(降低休眠功耗)

CH585M支持8K/16K/32K三级RAM保留,保留容量越小,下电模式功耗越低(每减少8K RAM,功耗降低≈0.1μA):

  • 优化措施:根据实际需求选择最小RAM保留(如仅需存储唤醒计数、配置参数时,选择8K RAM);

  • 代码修改 (替换原PMU_PowerDownModeCfg相关配置):

    c 复制代码
    // 配置下电模式:仅保留8K RAM + RTC唤醒
    PMU_RAMRetentionConfig(PMU_RAM_RETENTION_8K); // 选择8K RAM保留(默认32K)
    PMU_PowerDownModeCfg(PMU_PWR_DOWN_MODE_RETENTION, PMU_PWR_DOWN_WAKEUP_RTC);
  • 价值:下电模式功耗从1.1μA(32K RAM)降至≈0.8μA(8K RAM),同时不影响必要数据存储。

2. 选择"无RAM保留"的深度下电模式(极致休眠)

若应用无需保留RAM数据(唤醒后重新初始化系统),可选择无RAM保留的下电模式,进一步压低休眠功耗:

  • 代码修改

    c 复制代码
    // 无RAM保留的深度下电模式(仅保留RTC)
    PMU_PowerDownModeCfg(PMU_PWR_DOWN_MODE_DEEP, PMU_PWR_DOWN_WAKEUP_RTC);
  • 注意:唤醒后需重新初始化所有外设(SPI、GPIO等),适合"唤醒后快速完成任务、无需保留中间数据"的场景;

  • 价值:休眠功耗可降至≈0.5μA(CH585M手册标称深度下电模式典型值)。

二、时钟系统的极致管控(避免时钟泄漏功耗)

CH585M的时钟泄漏(如未禁用的外设时钟)是休眠功耗超标的常见原因,需彻底关闭非必要时钟:

1. 休眠前禁用所有外设时钟(含内核冗余时钟)

  • 优化措施 :在进入下电模式前,除RTC时钟外,禁用所有外设时钟、内核辅助时钟

  • 新增代码 (添加到CH585_Enter_PowerDown函数):

    c 复制代码
    void CH585_Enter_PowerDown(void) {
        // 禁用所有外设时钟(含SPI、UART、TIM、ADC、DMA等)
        RCC_PeriphClockCmd(RCC_PERIPH_ALL, DISABLE);
        // 单独使能RTC时钟(下电模式依赖)
        RCC_PeriphClockCmd(RCC_PERIPH_RTC, ENABLE);
        
        // 配置下电模式(配合RAM保留)
        PMU_RAMRetentionConfig(PMU_RAM_RETENTION_8K);
        PMU_PowerDownModeCfg(PMU_PWR_DOWN_MODE_RETENTION, PMU_PWR_DOWN_WAKEUP_RTC);
    }
  • 原理:CH585M的外设时钟默认可能未完全禁用,需显式关闭所有时钟以避免泄漏功耗(每漏关一个外设时钟,增加≈0.2μA功耗)。

2. 唤醒后切换至低主频运行(减少高功耗时长)

唤醒后无需立即切换到78MHz,可先以内部16MHz RC时钟完成轻量任务(如SPI配置),再按需切换至78MHz:

  • 代码修改 (调整CH585_FullSpeed_Run函数):

    c 复制代码
    void CH585_FullSpeed_Run(void) {
        // 先以16MHz RC时钟运行(轻量任务)
        SetSysClock(CLK_SOURCE_HSI_16MHz);
        // 使能SPI时钟(仅需16MHz即可满足SPI 1MHz通信)
        RCC_PeriphClockCmd(RCC_PERIPH_SPI0, ENABLE);
        
        // 若需处理复杂数据,再切换至78MHz
        // SetSysClock(CLK_SOURCE_PLL_78MHz);
    }
  • 价值:唤醒后高主频运行时间减少≈50%,单次唤醒节省≈5mA×1ms=5μA·s功耗。

三、GPIO与外设的深度休眠管控(消除漏电路径)

未使用GPIO的漏电、外设未进入空闲状态,是休眠功耗超标的隐形原因:

1. 未使用GPIO设为"模拟输入+高阻"模式

CH585M的模拟输入模式(GPIO_Mode_AIN) 无内部上拉/下拉电阻,漏电远低于普通输入模式(<0.1μA/引脚):

  • 代码修改 (更新GPIO_Init_LowPower中的未使用引脚配置):

    c 复制代码
    void GPIO_Init_LowPower(void) {
        GPIO_InitTypeDef GPIO_InitStruct = {0};
        // ...(原有功能引脚配置)
        
        // 未使用GPIO设为模拟输入
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All & ~(功能引脚掩码);
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; // 替代原GPIO_ModeIN_PD
        GPIO_Init(GPIOA, &GPIO_InitStruct);
        GPIO_Init(GPIOB, &GPIO_InitStruct);
    }

2. 外设进入"硬件空闲状态"后再休眠

确保SX1262、W25Q16进入硬件级低功耗状态(而非仅软件指令):

  • SX1262优化 :休眠前发送"强制射频关闭"指令(0x81),确保射频模块彻底断电;

    c 复制代码
    void SX1262_Enter_DeepSleep(void) {
        uint8_t cmd[] = {0x81, 0x00}; // 强制关闭射频
        SX1262_NSS_LOW();
        SPI_Write(cmd, 2);
        SX1262_NSS_HIGH();
        Delay_us(500);
        // 再进入保留配置休眠
        uint8_t sleep_cmd[] = {0x84, 0x04};
        SX1262_NSS_LOW();
        SPI_Write(sleep_cmd, 2);
        SX1262_NSS_HIGH();
    }
  • W25Q16优化 :休眠前发送"空指令"确认芯片进入空闲状态;

    c 复制代码
    void W25Q16_Enter_PowerDown(void) {
        W25Q16_CS_LOW();
        SPI_SendData(SPI0, 0x00); // 空指令确认空闲
        while(SPI_I2S_GetFlagStatus(SPI0, SPI_I2S_FLAG_TXE) == RESET);
        SPI_SendData(SPI0, 0xB9); // Power-Down指令
        while(SPI_I2S_GetFlagStatus(SPI0, SPI_I2S_FLAG_TXE) == RESET);
        W25Q16_CS_HIGH();
        Delay_us(3);
    }

四、唤醒流程与任务逻辑精简(减少高功耗时长)

唤醒后CPU的高功耗运行时间直接影响平均功耗,需极致精简流程:

1. 用"中断驱动"替代"轮询/Delay"

避免唤醒后空等(如SX1262接收超时),利用中断让CPU进入浅休眠:

  • 优化措施:配置SX1262的DIO1为"接收完成/超时"中断,唤醒后CPU进入浅休眠(PMU_PWR_DOWN_MODE_IDLE)等待中断;

  • 代码修改 (主函数唤醒流程):

    c 复制代码
    while(1) {
        // 唤醒后配置SX1262接收
        CH585_FullSpeed_Run();
        SX1262_Wakeup_RxConfig(50);
        
        // 浅休眠等待DIO1中断(替代Delay_ms(50))
        PMU_PowerDownModeCfg(PMU_PWR_DOWN_MODE_IDLE, 0);
        
        // 处理接收数据(仅在中断后执行)
        if(SX1262_Rx_Done_Flag) {
            SX1262_ReadRxData(rx_buf, sizeof(rx_buf));
            SX1262_Rx_Done_Flag = 0;
        }
        
        // 进入深度休眠
        SX1262_Enter_DeepSleep();
        W25Q16_Enter_PowerDown();
        CH585_Enter_PowerDown();
    }
  • 价值:唤醒后CPU空耗时间从50ms降至≈1ms,平均功耗降低≈8μA。

2. 唤醒后快速完成任务(压缩高功耗窗口)

将唤醒后的任务(如数据存储、参数配置)优化为"原子操作",减少CPU运行时间:

  • 优化措施:W25Q16数据存储采用"页写+快速结束"(避免多字节写入的冗余操作);

  • 代码示例

    c 复制代码
    void W25Q16_Write_Fast(uint32_t addr, uint8_t *data, uint8_t len) {
        W25Q16_Wakeup();
        W25Q16_WriteEnable();
        W25Q16_CS_LOW();
        SPI_SendData(SPI0, 0x02); // 页写指令
        SPI_SendData(SPI0, (addr >> 16) & 0xFF);
        SPI_SendData(SPI0, (addr >> 8) & 0xFF);
        SPI_SendData(SPI0, addr & 0xFF);
        SPI_Write(data, len);
        W25Q16_CS_HIGH();
        W25Q16_Enter_PowerDown(); // 立即休眠
    }

五、优化后功耗预期

场景 原配置功耗 优化后功耗 优化幅度
CH585M下电模式(8K RAM) 1.1μA 0.8μA ≈27%
唤醒后CPU运行时间 50ms 1ms ≈98%
系统平均功耗(1分钟周期) 15.45μA 5~6μA ≈60%

核心优化原则

  1. 最小资源匹配:RAM保留、时钟、外设均按"当前任务必需"配置,避免冗余;
  2. 快速休眠回归:唤醒后快速完成任务,立即回到深度低功耗状态;
  3. 硬件特性利用:充分调用CH585M的PMU分级、RAM保留分级等原生低功耗功能。
相关推荐
小何code15 小时前
STM32入门教程,第10课(下),Keil调试模式
stm32·单片机·嵌入式硬件
Renhao-Wan15 小时前
Java 并发基石:AQS (AbstractQueuedSynchronizer)
java·开发语言
XjtDZ15 小时前
CS5715E异步升压DC-DC控制器
单片机·嵌入式硬件·智能音箱
Jason_zhao_MR15 小时前
V2G 实战:SECC GreenPHY 通信开发方案
嵌入式硬件·物联网·嵌入式·边缘计算
SweetCode15 小时前
【无标题】
开发语言·c++·算法
shughui15 小时前
Python基础面试题:语言定位+数据类型+核心操作+算法实战(含代码实例)
开发语言·python·算法
No0d1es16 小时前
2025年12月电子学会青少年软件编程Python六级等级考试真题试卷
开发语言·python·青少年编程·等级考试·电子学会
zlp199216 小时前
xxl-job java.sql.SQLException: interrupt问题排查(二)
java·开发语言
superman超哥16 小时前
Rust HashSet与BTreeSet的实现细节:集合类型的底层逻辑
开发语言·后端·rust·编程语言·rust hashset·rust btreeset·集合类型