GD32F303低功耗有三种模式,睡眠,深度睡眠和待机模式。

上面是唤醒方式和进入指令。

深度睡眠和待机模式的功耗在数据手册有。

深度睡眠和待机模式的静态电流。

进入低功耗模式代码。

//进入睡眠模式
void gd_pum_sleepmode(void)
{
    rcu_periph_clock_enable(RCU_PMU);
    pmu_to_sleepmode(WFI_CMD);//WFI进入待机模式
}


//进入深度睡眠模式
void gd_pum_deepsleepmode(void)
{
    rcu_periph_clock_enable(RCU_PMU);
    pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, PMU_LOWDRIVER_ENABLE, WFI_CMD);//WFI进入待机模式
}

//进入待机模式
void gd_pum_standbymode(void)
{
    rcu_periph_clock_enable(RCU_PMU);
    pmu_to_standbymode();//WFI进入待机模式
}

/--------------------------------------------------------------------------------------------------------------------------------

降低功耗和进入深度睡眠模式后,电流比数据手册的偏大问题处理。

测试时发现一个问题,就是单MCU且IO是浮空状态时,降低主频后,功耗比数据测试上的大几毫安。

正常48M电流应该是7.3-11毫安左右才对,实际的电流是14毫安。

如果直接进入深度睡眠模式,实际测得的电流是1.4毫安,

比数据手册里标注的偏大。

经过测试发现,电流偏大的主要的原因是IO的浮空状态导致的。下面做实验

例:主频48M->主频24M->全部初始化IO->进入深度睡眠->PA0唤醒->重新初始化时钟。

MCU的主频配置在system_gd32f30x.c文件

如果需要配置其他的主频可以模仿这个文件里的函数配置

void gd_rcu_switch_system_clock(void)
{
    uint32_t timeout = 0U;
    uint32_t stab_flag = 0U;

    /* select IRC8M as system clock source, deinitialize the RCU */
    rcu_system_clock_source_config(RCU_CKSYSSRC_IRC8M);//RCU_CKSYSSRC_HXTAL
    rcu_deinit();
    
    /* enable HXTAL */
      RCU_CTL |= RCU_CTL_HXTALEN;

    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
    do{
        timeout++;
        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
    }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));

    /* if fail */
    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
        while(1){
        }
    }

    RCU_APB1EN |= RCU_APB1EN_PMUEN;
    PMU_CTL |= PMU_CTL_LDOVS;


    /* HXTAL is stable */
    /* AHB = SYSCLK */
    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
    /* APB2 = AHB */
    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
    /* APB1 = AHB */
    RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;


    RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0);
    RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0);

    /* CK_PLL = (CK_HXTAL/2) * 9 = 36 MHz */
    RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
    RCU_CFG0 |= RCU_PLL_MUL6;


    // RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4| RCU_CFG0_PLLMF_5);
    // RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL6);

    /* enable PLL and PLL1 */
    RCU_CTL |= RCU_CTL_PLLEN ;

    /* wait until PLL is stable */
    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
    }

        /* enable the high-drive to extend the clock frequency to 120 MHz */
        PMU_CTL |= PMU_CTL_HDEN;
        while(0U == (PMU_CS & PMU_CS_HDRF)){
        }
    
        /* select the high-drive mode */
        PMU_CTL |= PMU_CTL_HDS;
        while(0U == (PMU_CS & PMU_CS_HDSRF)){
        }


        
    /* select PLL as system clock */
    RCU_CFG0 &= ~RCU_CFG0_SCS;
    RCU_CFG0 |= RCU_CKSYSSRC_PLL;

    /* wait until PLL is selected as system clock */
    while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
    }


}
    /* CK_PLL = (CK_HXTAL/2) * 6 = 24 MHz */
    RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
    RCU_CFG0 |= RCU_PLL_MUL6;

最主要是这里,现在配置成了24M,因为我的外部晶振HXTAL是8M的。

初始化测试

​​int main(void)
{
    // uint16_t i;
    // uint16_t adcbuf[10];
    // uint16_t adc,mv;

    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
    gd_systick_config();
    gd_system_delay_ms(3000);

    gd_rcu_switch_system_clock();
    gd_systick_config();
    gd_system_delay_ms(3000);


    pum_gpio_init();
    gd_system_delay_ms(3000);

    gd_gpio_config(GPIOA,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
    nvic_irq_enable(EXTI0_IRQn, 2U, 0U);
    gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_0);
       /* configure key EXTI line */
   exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
   exti_interrupt_flag_clear(EXTI_0);

   gd_pum_deepsleepmode();
   //SystemInit();
   //SystemCoreClockUpdate();
   gd_rcu_switch_system_clock();
   gd_systick_config();
   gd_system_delay_ms(2000);
   gd_pum_deepsleepmode();
}

1.刚开始主频48M时,测得电路14mA,(偏大)

2.主频降到24M时,测得主频是10.5mA,(偏大)

3.初始化IO口,全部设置成模拟量输入,PA0设置成输入中断,测得电流是5.5mA,(正常)

4.进入深度睡眠模式,测得电流是120uA(正常)

5.通过P0中断唤醒,唤醒后MCU系统时钟变成了内部8M,需要重新初始化24M的时钟,测得电流是5.5mA,(正常)。

 

到此一切正常。

假如进入深度睡眠模式后,关闭全部的时钟后电流超过300uA的话,甚至超过1mA的情况下,

把全部的IO都初始化,哪怕没有的IO口。

    rcu_periph_clock_enable(RCU_GPIOD);
    rcu_periph_clock_enable(RCU_GPIOE);
    rcu_periph_clock_enable(RCU_GPIOF);
    rcu_periph_clock_enable(RCU_GPIOG);

我用的GD32F303CB,没有EFG的引脚,刚开始没初始化时,进入深度睡眠时功耗是1.4mA,初始化后是120uA。

上面的测试都是在PCB板子没有漏电流的情况下,测的单独MCU功耗。

//=================================================================

注意:烧录问题,如果PA13和PA14设置成普通IO,导致无法烧录时,断电的情况下,BOOT0引脚给高电平,然后再上电烧录就可以了。

如果是代码一开始不加延迟进入了低功耗导致无法烧录,也是用上面同样的方式。

F303不适合做低功耗,还是用GD32L233比较好一点。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐