STM32F030C8T6 STOPMODE低功耗设计经验分享

最近做了一个项目,由锂电池供电,用到了STM32F030的低功耗设计,经过对比选择了STOP模式,用按钮中断唤醒,

void enter_stop_mode(void)//进入停止模式
{
	SysTick->CTRL = 0x00;//关闭定时器
    SysTick->VAL = 0x00;//清空val,清空定时器	
	OLED_Clear();	
	OLED_Display_Off();	
	TIM_Cmd(TIM2, DISABLE);
	TIM_Cmd(TIM3, DISABLE);
	TIM_CtrlPWMOutputs(TIM2, DISABLE);	                    //PWM输出关	
	ADC_Cmd(ADC1, DISABLE);	        						//失能ADC
	I2C_Cmd(I2C1, DISABLE);//失能IIC	
	EXIT_KEY_Init();//配置外部中断	
	PowerSW_Init();
 	PowerSW_ON();   //关外围电源		
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);//开电源管理时钟
	PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
}

第一次程序运行后电流为2mA左右,然后开始一点点查电流,先将用到的端口设为输出并根据负载电路的不同设了上拉或下拉,通电后电流还是2mA左右,没有任何变化,改为输入也没有降低。后来试了进入STANDBYMode模式,因为这个模式所有的外设端都停止工作的,并且是高阻状态

PWR_WakeUpPinCmd(PWR_WakeUpPin_1,ENABLE);  //使能唤醒管脚功能
	PWR_ClearFlag(PWR_FLAG_WU);
    PWR_EnterSTANDBYMode();   //进入待机(standby)模式

此时电流一下降到了450uA,太兴奋了!。由于WAKEUP口未引出,无法唤醒,还是用不了这个模式只能用STOP模式,只能再查原因。那对比前面的端口设置猜想电流肯定时从某个端口漏掉的,只是我没关掉,于是将所有端口都设为模拟模式并进入STOP模式测试,只留了中断引脚

GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);	
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;												   
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_Init(GPIOF, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //中断引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; 
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);

此时电流直接为500uA,于是每个端口单独关闭,看到低是那个端口漏的电流,结果才发现是A1口,这个口之前作ADC采样口的,之前想着关闭了ADC应该不会有电流了,并没有把它设为高阻态,谁想它这边漏了1.5mA。我又将没用到的端口CDF全设为高阻态,电流又降到450uA,这边就很奇怪,明明这些端口都没有接负载,都是悬空的,但还是有50uA漏掉了。

throttlestop设定不了功耗_throttlestop设定不了功耗

450uA还是有点高,我在外设电源处加入了一个MOSFET开关,所有外设电源由VCCSW提供,进入STOP模式时将外设电源全部关闭

throttlestop设定不了功耗_单片机_02

再测试电流降为10uA,其本达到设计要求了,用300mAH的锂电池供电,10uA待机电流理论上可以用3年。

结论:低功耗设计中,虽未用到的端口未接负载,但仍要设为模拟状态(端口为高阻态),其它设输入输出上下拉都没用。STANDBYMode模式默认端口全部设为高阻状态,不需单独设,但STOP模式要程序中设置。

由于是锂电池供电,在正常运行中电流也希望尽可能小,我在测试时发现运行电流在20~50mA之前变动,且没有规律,后来查找终于发现问题出在蜂鸣器控制回路,其驱动电路如下:

throttlestop设定不了功耗_throttlestop设定不了功耗_03


LS61为无源蜂鸣器,BEEP引脚由TIM2通道的PWM控制,程序中判断响时时长够了就停止TIM2,这样设计看似没问题,但就是这个原因导至电流增大了一倍。原因就是BEEP输出的是PWM信号,高低电平按设定的频率交替变化,但是当停止TIM2时,这个高低电平是随机的,有时候是高电平,这时Y1是导通的,而TIM2又停止了,不会再转为低电平,BEEP-R61-Y1-GND这个回路就一直是导通的,这就造成了电流白白浪费,后来在程序中加入判断语 句,当响时时长够且PWM输出低电平时才停定时器,再测试电流一直在20mA左右,再没有到过50mA,说明问题根本解决了。