STM32L476低功耗


低功耗设计
低功耗方法

基本知识

STM32L4系列支持超低功耗,可以让MCU在需要的时候进入SLEEP,STOP0,STANDBY,SHUTDOWN等低功耗模式。降低功耗,配合适当的唤醒管理和外设防漏电措施,可以大幅延长电池供电的系统使用时间。
其中最常用的是STOP2模式和STANDBY模式,本文进入的是STOP2模式,使用LPTIM定时唤醒。
Stop2模式外设状况

STOP2模式注意事项

  1. 系统时钟仅保留LSI和LSE,仅有LPTIM1和LPUART以及RTC能够继续工作,所以定时唤醒只能通过LPTIM1或RTC
  2. SRAM和寄存器的值都保留,可以被NVIC中的中断唤醒,包括Systick系统计时中断,所以进入前一定要关闭Systick定时中断,平均唤醒时间7us,唤醒后立刻执行中断处理函数然后从进入STOP2模式语句的下一句处继续执行
  3. 唤醒后系统的时钟源默认为HSI,需要在进入前设置唤醒后的时钟,唤醒后按需要重新初始化时钟和外设
  4. MCU理论待机电流1.3uA,一节500mA的3.7V锂电池可以待机43年。实际上因为外设漏电和开发板作为系统的整体损耗,远远达不到这个值,而且L476RG-neucleo开发板通过3.3V管脚供电的时候会点亮板子上的LED1和LED3,不论有没有进入STOP模式,造成了很多消耗.如果要做真正的低功耗,在设计板子的时候就要考虑各处的供电,线性稳压器LDO也要使用低损耗的。

配置过程

LPTIM定时器和调试用串口设置

  1. 在CubeMX打开LPTIM1并进行如下设置
    LPTIM1设置
  2. 打开USART2,作为调试串口

代码

串口重定向

int fputc(int ch, FILE *fp)  // 串口调试的重定向函数,将printf输出重定向到串口2
{
 if (fp == &__stdout)
 {
  if (ch == '\n')
  {
   // 自动添加\r
   while ((USART2->ISR & USART_ISR_TXE) == 0); // 等待TDR可写入
   USART2->TDR = '\r';
  }
  while ((USART2->ISR & USART_ISR_TXE) == 0);
  USART2->TDR = ch;
 }
 return ch;
}

定时器中断回调函数

void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim) // LPTIM定时器的超时函数
{
  /* 清除中断标志位已经在IRQHandler中被执行 */
 HAL_LPTIM_MspDeInit(&hlptim1);  // 关闭LP定时器
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 打开LED灯
 SystemClock_Config(); // 配置系统时钟
 SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; // 打开Systick的中断
 SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; // 退出中断时不再自动进入低功耗模式
 printf("In the EXTI to wake up!");
}

自定义的Enter函数,用于配置低功耗及时间,并最后进入低功耗模式

void EnterSTOP2Mode()  // 自定义的Enter函数
{
  /* 进入STOP2之前的准备 */
  printf("Start to enter Stop2 mode");
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // 关闭LED灯
  __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);  // 设定唤醒后的时钟源
  HAL_LPTIM_MspInit(&hlptim1);  // 打开定时器
  HAL_LPTIM_TimeOut_Start_IT(&hlptim1, 65535, 65535); // 开始计时 休眠4s   (1/32KHz)*65535*预分频2
  __HAL_RCC_PWR_CLK_ENABLE();  // 打开电源控制时钟
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |0| SysTick_CTRL_ENABLE_Msk;  // 关闭系统Systick计时中断 
  HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);  // 进入STOP2模式
}

测试例子

int main(void)
{
  HAL_Init();
  
  SystemClock_Config();

  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_LPTIM1_Init();

 printf("MCU start!\n");
 for(int i=0;i<10;i++)   // 快速闪烁LED,表示板子正常启动
 {
 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
 HAL_Delay(300);
 }

  while (1)
  {
  EnterSTOP2Mode();
  printf("Run mode");  // 唤醒后 执行完定时器的中断从进入语句后继续执行
  for(int i=0;i<8;i++)  
  {
   printf(".");
   HAL_Delay(500);
  }
  }
}

功率实测

参数配置

由于每个人的实测开发环境不一样,个人所测只能作为参考
基本参数:

  • Power Regulator Voltage Scale: 1
  • VDD电压3.3V
  • GPIO仅打开PA5
  • USART2打开
  • LPTIM1打开(LSI作为时钟源)
  • 将所有不用的GPIO口设为模拟输入
  • 时钟配置
    SYSCLK:48MHz (一个平衡的频率,再高就要使用PLL CLOCK,功耗大大增加)
    由MSI作为时钟源(MSI是L4,F4,H7等高端系列的内置可调RC时钟源,能够降低时钟所消耗的功耗,F1系列上没有)
    在这里插入图片描述
    在这里插入图片描述

实测结果

工作模式下, 2.1mA左右
STOP2模式, 1.9uA,还是非常给力的,不过这只是单片机的功耗,整机功耗待测试。
在这里插入图片描述


文章作者: Allen Hong
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Allen Hong !
  目录