GD32F303低功耗处理,降低频率。进入低功耗后电流偏大处理。
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比较好一点。

更多推荐



所有评论(0)