关于stm32f030 低功耗 stop模式的5.6uA 程序配置

真正的从项目中的经验,不是单纯的配置引脚测试。希望对大家有帮助。

最近一个项目,需要 stm32f030K6 单片机低功耗,3种模式的区别哪儿都有介绍我就不再赘述了,我需要stop 模式,外部是5个按键,每个按下都能将单片机唤醒。

刚开始功耗休眠为200uA,经过几天查找,发现时钟芯片第二脚不能加上拉(可是手册上推荐的有这个上拉啊,好郁闷)。然后功耗就降到了60uA,然后接下来,就怎么也降不下来了。

我先贴正确的代码:

void Sleep_IO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  //
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  //
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);  //
	
	/*初始化GPIOA*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_9|GPIO_Pin_10|
                                 GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_15;												   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|
                                  GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;	   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_WriteBit(GPIOB,GPIO_Pin_0,Bit_RESET);
	GPIO_WriteBit(GPIOB,GPIO_Pin_1,Bit_RESET);
	GPIO_WriteBit(GPIOB,GPIO_Pin_3,Bit_RESET);
	GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_RESET);
	GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_RESET);
	

	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2|GPIO_Pin_8|GPIO_Pin_6|GPIO_Pin_7;	   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
	ZI2C_SCL_O(1);
	ZI2C_SDA_O(1);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;	   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
  GPIO_Init(GPIOF, &GPIO_InitStructure);


void Sleep_Con(void)
{
	ADC_Cmd(ADC1, DISABLE);	        						//失能ADC
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);	
	ADC_DeInit(ADC1);

	USART_DeInit(USART1);
	USART_Cmd(USART1,DISABLE);                              //失能串口

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE );
	
	TIM_Cmd(TIM14, DISABLE);                                //停止计数
	TIM_Cmd(TIM3, DISABLE);
	TIM_CtrlPWMOutputs(TIM3, DISABLE);	                    //PWM输出關
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,DISABLE);    //关闭TIM3  时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,DISABLE);    //关闭TIM14  时钟

	RCC_HSI14Cmd(DISABLE);
	RCC_LSICmd(DISABLE);
	RCC_LSEConfig(RCC_LSE_OFF);								//关外部时钟

	Sleep_IO_Init();										//IO 初始化

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
	PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
	sleepdelaycnt = 0;                                     //被唤醒后,休眠延时清0,
}

1. 我在程序中用到的外设有 UART1、TIM14、PWM(TIM3-CH4)、ADC、模拟IIC,这个我没见到其他人用这么多的 *_*,确定引脚和外围之间没有漏电流了。我当时的程序没有 ADC_DeInit(ADC1); 这句话,无意中加上后,居然瞬间降到了30uA,不知道为啥,明明我都把它的时钟关过了啊。不过算是有效。

2. 管脚配置:  不管将管脚配成 输入下拉、模拟输入下拉、还是推挽输出低,功耗不会降低一点,所以我觉得只要是不与外围形成压差,配成什么模式无所谓,我觉得为了抗干扰可以设成推挽输出低。当然还有模拟 IIC,不管你是输入上拉还是推挽高,功耗也是一样的。

3. 继续查问题,是我的供电芯片问题。手册是1uA,我居然信了。我原来测功耗是供5V(包括了电源芯片),最后实在没辙了才怀疑芯片,拆掉供电芯片,单片机供3.3V,(此时整个世界都安静了)5.6uA,说明我的外围电流做的还是可以的,没有漏电流。这个电源芯片太坑了。

所以我写这篇文章,希望对大家有所帮助吧,每个人遇到问题的地方都不一样,静下来慢慢找。

另外告诉大家一个技巧,在查找外围漏电时候用到的。我把那些上拉电阻、下拉电阻、限流电阻一个个用镊子短路一会儿(看好不要把3.3-GND短路了啊,),观察电流有没有变化。如果没有变化说明不是这个的原因,我在排查时钟芯片那个管脚上拉电阻就是用的这个方法。那个10K被短路后,电流表瞬间上升了,激动死我了,果断把这个电阻拆了,验证确实有效。

猜你喜欢

转载自blog.csdn.net/zjp1234zjp/article/details/81173062