真正的从项目中的经验,不是单纯的配置引脚测试。希望对大家有帮助。 最近一个项目,需要 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被短路后,电流表瞬间上升了,激动死我了,果断把这个电阻拆了,验证确实有效。
|