1.说明
本文主要叙述在stm32进入stop时如何保持最低功耗的问题,并对部分细节问题进行分析整理。STM32L提供5种低功耗模式:低功耗运行模式、睡眠模式、低功耗睡眠模式、停止模式、待机模式。
待机模式电流最低,但是待机模式时的MCU处于不受控制的状态,所有的IO口都工作在高阻抗的状态的下,只有专门的几个引脚能够将MCU唤醒,而每次唤醒后相当于系统复位,RAM中的数据全部丢失,在外部器件连接的情况下,器件的引脚可能会吸收大量的电流,反而达不到低功耗的要求。
停止模式的功耗仅次于待机模式,在STOP模式下,PLL,HSL,HSE都被停止,RAM和寄存器的值保留。
2.引脚配置
在stop模式下,由于所有的引脚的状态都可以保留,所以需要进行适当的引脚配置才能达到效果。在实际的配置过程中,如果在stm32最小系统中,要在stop模式下保持最低功耗,可将所有的GPIO设置成模拟输入,如果不进行配置,将是默认是浮空输入,此时stop模式的电流很大。在设置的过程中,有几个特殊的引脚需要注意。
对于stm32来说,除了PA,PB,PC每个组有16个GPIO之外,还有PD2,PH0, PH1这三个GPIO。不能错过任何一个引脚的配置,否则功耗会很大。
在所有的引脚配置成GPIO模式后,在stm32最小系统中采用3.3V电压供电,实测电流为0.75uA。但是如果将全部的引脚都配置成模拟输入的GPIO后,将不能正常的使用,根据实际使用的情况,预留9个中断口作为唤醒源。当配置完成之后,可以将电流控制在3.5uA。
降低功耗的控制,主要需要注意的是引脚的上下拉,在有中断引脚上有外设时,可以将引脚配置成浮空输入的模式,不需要配置上下拉。而当该引脚上未接任何外设时,一定需要设置内部的上拉或者下拉,这是比较关键和重要的。
3.通讯类外设的控制
对于stm32内部的通信类的外设,除了设置GPIO的引脚之外,还需要将内部的uart或者i2c或者spi等通信类设备关闭。由于目前只使用了uart,所以在关闭uart可以通过HAL的HAL_UART_MspDeInit(&huart1);函数进行deinit。该函数会关闭中断,清空内部寄存器,并且设置引脚为GPIO模式。所以可以达到降低功耗的目的。
在测试过程中,也遇到了一个问题,就是唤醒后,串口将无法接收和发送数据。刚开始认为休眠时DeInit,唤醒后Init即可,但是还有一个重要的步骤没有做,就是开启串口的中断。
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USART1_IRQn);HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USART2_IRQn);HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USART3_IRQn);
目前三路串口采用的是DMA+空闲中断的方式进行的,所以这里需要重新开启中断才行。
第二个问题就是ADC,当时测试,一采用ADC进行采样后,下次休眠后电流就很大,实测可达到1.8mA,而不采用ADC进行采样的情况下只有38uA。所以ADC也在耗电,ADC不属于通信类的外设,但是采用了DMA,所以需要关闭掉ADC的中断即可HAL_ADC_Stop_IT(&hadc);,一般来说,如果不是采用DMA的方式,非通讯类的外设只需要关掉时钟即可。__HAL_RCC_ADC1_CLK_DISABLE();
4.特殊引脚的控制
有一个引脚也是需要注意,PH0,该引脚以前是作为外部的32k晶振使用,可用作独立看门狗的时钟源,由于该引脚目前作为了GPIO,所以在使用时作为普通的GPIO使用。作为普通的GPIO使用的必要条件是HSE时钟关闭。但是在测试过程中还是遇到一个问题,该引脚配置成模拟输入后,stop模式下的电流仍有800uA,后来经过测试,发现是Debug调试器未关,也就是HAL_DBGMCU_DisableDBGSleepMode();函数没有有调用。所以在测试时电流才有800多uA。
5. 总结
对于降低功耗来说,standy模式功耗最低,但是唤醒源比较少,可以选择stop模式。由于stop模式的引脚状态和断电前保持一致,所以在进入stop之前需要将不需要控制的引脚设置成模拟输入。同时中断引脚设置相应的浮空或者上拉,这时,如果在中断引脚上未接任何的东西,内部需要上拉或者下拉,这样才能保证最低功耗。