CH57x-CH59x低功耗同时外设保持修改示例

继上篇:CH57x,CH58x,CH59x等BLE芯片的休眠回调作用及使用方法 介绍了蓝牙低功耗回调的作用和原理,其是使用SLEEP休眠方式,如果我们需要在低功耗的同时,让外设保持,则需要做一点修改,使用IDLE睡眠方式:

修改例子中CH58x_LowPower函数,如下:

/*******************************************************************************
 * @fn          CH58x_LowPower
 *
 * @brief       启动睡眠
 *
 * @param       time  - 唤醒的时间点(RTC绝对值)
 *
 * @return      state.
 */
__HIGH_CODE
uint32_t CH58x_LowPower(uint32_t time)
{
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
    volatile uint32_t i;
    uint32_t time_tign, time_sleep, time_curr;
    unsigned long irq_status;

    time_tign = time;//IDLE方式只需要提前1us唤醒,可忽略不计

    SYS_DisableAllIrq(&irq_status);
    time_curr = RTC_GetCycle32k();
    // 检测睡眠时间
    if (time_tign < time_curr) {
        time_sleep = time_tign + (RTC_MAX_COUNT - time_curr);//防止RTC溢出
    } else {
        time_sleep = time_tign - time_curr;//设置RTC唤醒触发值,绝对值
    }

    // 若睡眠时间小于最小睡眠时间或大于最大睡眠时间,则不睡眠
    if ((time_sleep < SLEEP_RTC_MIN_TIME) || 
        (time_sleep > SLEEP_RTC_MAX_TIME)) {
        SYS_RecoverIrq(irq_status);
        return 2;
    }

    RTC_SetTignTime(time_tign);//设置RTC中断触发时间
    R8_RTC_FLAG_CTRL = (RB_RTC_TMR_CLR | RB_RTC_TRIG_CLR);

#if(DEBUG == Debug_UART0) // 使用其他串口输出打印信息需要修改这行代码
    while((R8_UART0_LSR & RB_LSR_TX_ALL_EMP) == 0)
    {
        __nop();
    }
#endif
    // LOW POWER-sleep模式
    if(!(R8_RTC_FLAG_CTRL&RB_RTC_TRIG_FLAG))//WFE形式依赖RTC唤醒事件,此时无法进入中断,替代原先RTC_Flag的判断
    {
        LowPower_Idle_WFE();
        SetSysClock( SYSCLK_FREQ );
        R8_RTC_FLAG_CTRL = (RB_RTC_TMR_CLR | RB_RTC_TRIG_CLR);
        SYS_RecoverIrq(irq_status);//醒来后执行完代码,恢复中断时进入中断
        HSECFG_Current(HSE_RCur_100); // 降为额定电流(低功耗函数中提升了HSE偏置电流)
        return 0;
    }
    SYS_RecoverIrq(irq_status);//醒来后执行完代码,恢复中断时进入中断
#endif
    return 3;
}

平均功耗如下,存在idle睡眠底电流1.9mA,期间存在电流起伏是由于蓝牙定时唤醒广播:

image

 

原先SLEEP方式,平均电流如下,此模式下外设无法正常运行,同时底电流更低,约12ua:

image

 

posted @ 2026-02-11 16:04  oTvTo  阅读(62)  评论(0)    收藏  举报