你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32L0系列单片机低功耗(STOP)使用+RTC唤醒+LPUART(DMA方式)唤醒+LPTIM唤醒

[复制链接]
STMCU小助手 发布时间:2021-11-17 22:01
STM32L0低功耗应用
STM32L0支持7种低功耗模式,本文重点讨论停止(STOP)模式。

首先介绍几点影响功耗的因素。
1.IO口的状态,不用的IO口设置成模拟输入。
2.时钟,时钟越低功耗越低。
3.外设,禁用不使用的外设。
4.PLL是一个耗电大户,如果做低功耗还是把PLL禁用,直接HSE/HSI/MSI到SYSCLK。
5.内核电压,根据不同的运行速度和VDD电压调节动态调压器,达到速度与功耗的平衡。

官方描述如下:

2019032812515659.png


20190328125306295.png


使用下面这个函数调节内核电压

  1. #define PWR_REGULATOR_VOLTAGE_SCALE1   PWR_CR_VOS_0
  2. #define PWR_REGULATOR_VOLTAGE_SCALE2   PWR_CR_VOS_1
  3. #define PWR_REGULATOR_VOLTAGE_SCALE3   PWR_CR_VOS
  4.   *            @arg PWR_REGULATOR_VOLTAGE_SCALE1: Regulator voltage output Scale 1 mode,
  5.   *                                                System frequency up to 32 MHz.
  6.   *            @arg PWR_REGULATOR_VOLTAGE_SCALE2: Regulator voltage output Scale 2 mode,
  7.   *                                                System frequency up to 16 MHz.
  8.   *            @arg PWR_REGULATOR_VOLTAGE_SCALE3: Regulator voltage output Scale 3 mode,
  9.   *                                                System frequency up to 4.2 MHz

  10. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
复制代码

1.睡眠模式
睡眠模式下只有CPU停止工作,所有外设继续工作,任何中断或者事件都能唤醒CPU,此时约16MHz/1mA。

2.低功耗运行模式
低功耗运行模式使用 内部MSI RC振荡器为低速模式(最大工作频率131kHz),内部调压器在低功率模式下,时钟频率和可用外设都有限制。仅当 电压调节器 处于范围 2 时,才能进入低功耗运行模式。

3.低功耗睡眠模式

进入睡眠模式时,调整内部调压器为低功率模式,时钟频率和可用外设都有限制;一个典型的例子是计时器以32kHz的速度运行。当事件或中断触发唤醒时,系统将恢复到运行模式,并打开调节器

4.带RTC的停止模式
停止模式在保持RAM和寄存器内容以及实时时钟的同时,实现了最低的功耗。Vcore域中的所有时钟都被停止禁用PLL、MSI RC、HSE和HSI。LSE或LSI仍在运行。调压器处于低功率模式。一些具有唤醒功能的外围设备可以使HSI在停止模式下检测它们的 触发唤醒的动作。
设备可以被外部中断在3.5us内唤醒,处理器会进入唤醒中断后恢复现场。也可以被PVD中断,比较事件(如果此外设使能),RTC alarm/tamper/timestamp/wakeupevents, USB/USART/I2C/LPUART/LPTIMER 唤醒事件唤醒。 唤醒后需要重新配置时钟。

5.不带RTC的停止模式
停止模式在保持RAM和寄存器内容以及实时时钟的同时,实现了最低的功耗。Vcore域中的所有时钟都被停止禁用PLL、MSI RC、HSE和HSI。LSE或LSI仍在运行。调压器处于低功率模式。一些具有唤醒功能的外围设备可以使HSI在停止模式下检测它们的 触发唤醒的动作。
设备可以被外部中断在3.5us内唤醒,处理器会进入唤醒中断后恢复现场。也可以被PVD中断,比较事件(如果此外设使能),RTC alarm/tamper/timestamp/wakeupevents, USB/USART/I2C/LPUART/LPTIMER 唤醒事件唤醒。 唤醒后需要重新配置时钟。

6.带RTC待机模式
关闭内部电压调节器,从而关闭整个Vcore。PLL MSI HIS HSE 都被关闭,LSE/LSI在运行。
除了备用电路中的寄存器外(wakeup logic, IWDG,RTC, LSI, LSE Crystal 32 KHz oscillator, RCC_CSR register),RAM和寄存器内容都丢失了。
设备会在以下情况在60us内被唤醒
1.外部引脚复位
2.IWDG复位
3.唤醒引脚上升沿
4.RTC Alarm tamper timestamp Wakeup 事件

7.不带RTC待机模式
关闭内部电压调节器,从而关闭整个Vcore。PLL MSI HIS HSE LSE LSI都被关闭。
除了备用电路中的寄存器外(wakeup logic, IWDG,RTC, LSI, LSE Crystal 32 KHz oscillator, RCC_CSR register),RAM和寄存器内容都丢失了。
设备会在以下情况在60us内被唤醒
1.外部引脚复位
2.唤醒引脚上升沿
RTC 和IWDG 的时钟源进入停止或者待机模式不会自动停止。

进入STOP模式
停止模式基于 Cortex®-M0+ 深度睡眠模式与外设时钟门控。调压器既可以配置为正常模式,也可以配置为低功耗模式。在停止模式下,VCORE 域中的所有时钟都会停止,PLL、MSI、HSI16 和 HSE RC 振荡器也被禁止。内部 SRAM 和寄存器内容将保留。
要使停止模式下的功耗最低,内部 Flash 也进入低功耗模式。Flash 处于掉电模式时,将器件从停止模式唤醒将需要额外的启动延时。
要使停止模式下的功耗最低,可在进入停止模式前关闭 VREFINT、BOR、PVD 和温度传感器。退出停止模式后,可以使用 PWR_CR 寄存器中的 ULP 位通过软件重新打开它们。

在停止模式下,所有 I/O 引脚的状态与运行模式下相同。

要求

– 没有中断(对于 WFI)或事件(对于 WFE)挂起。
– 将 Cortex®-M0+ 系统控制寄存器中的 SLEEPDEEP 位置 1
– 电源控制寄存器 (PWR_CR) 中的 PDDS 位 = 0
– 电源控制/状态寄存器 (PWR_CSR) 中的 WUF 位 = 0
– 通过配置 RCC_CFGR 寄存器中的 STOPWUCK 位退出停止模式时,选
择 MSI 或 HSI16 RC 振荡器作为系统时钟。
注: 要进入停止模式,所有 EXTI 线挂起位(在第 13.5.6 节:EXTI 挂起
寄存器 (EXTI_PR) 中)、所有外设中断挂起位、RTC 闹钟(闹钟 A
和闹钟 B)、RTC 唤醒、RTC 入侵和 RTC 时间戳标志位必须复
位。否则将忽略进入停止模式这一过程,继续执行程序。

下面咱们来看下寄存器描述

系统控制寄存器中的 SLEEPDEEP 位
我在ARM-CortexM0 权威指南上找到的
2019032814102030.png


(PWR_CR) PDDS位:掉电深度睡眠 (Power-down deepsleep)
此位由软件置 1 和清零。
0:器件在 CPU 进入深度睡眠时进入停止模式。调压器处于低功耗模式。
1:器件在 CPU 进入深度睡眠时进入待机模式。

(PWR_CSR) WUF 位
该位通过硬件置 1,并且只能通过系统复位或通过将 PWR 电源控制寄存器 (PWR_CR) 中的
CWUF 位置 1 清零
0:未发生唤醒事件
1:收到唤醒事件,可能来自 WKUP 引脚、RTC 闹钟(闹钟 A 和闹钟 B)、RTC 入侵事
件、RTC 时间戳事件或 RTC 唤醒事件。
注: 如果使能 WKUP 引脚(将 EWUPx (x=1, 2, 3) 位置 1)时 WKUP 引脚已为高电平,系
统将检测到另一唤醒事件。

然后还要配置选择唤醒后的时钟源
通过此函数
  1. /**
  2.   * @brief  Macro to configures the wake up from stop clock.
  3.   * @param  __RCC_STOPWUCLK__ specifies the clock source used after wake up from stop
  4.   *   This parameter can be one of the following values:
  5.   *     @arg @ref RCC_STOP_WAKEUPCLOCK_MSI    MSI selected as system clock source
  6.   *     @arg @ref RCC_STOP_WAKEUPCLOCK_HSI    HSI selected as system clock source
  7.   * @retval None
  8.   */
  9.   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
复制代码

唤醒后如果需要,记得重新配置时钟。

LPUART在DMA模式下唤醒STOP
不讨论怎么实现DMA,只讨论唤醒SOTP模式。
首先咱们来看官方描述

20190328142423684.png


我使用的是LSE时钟

其实官方手册有这样一段描述
当 DMA 用于接收时,它必须在进入停止模式前禁止,并在退出停止模式后重新使能。 从停止模式唤醒功能并非在所有模式下均可用。例如,该功能在 SPI 模式下不起作用,因为 SPI 仅在主模式下工作。
也就是说要在进入STOP模式前禁止DMA。这里不是去操作DMA的寄存器去禁止DMA,而是在LPUART里面的寄存器DMAR位禁止即可。
LPUART_CR3(DMAR位)
位 6 DMAR:DMA 使能接收器 (DMA enable receiver)
此位由软件置 1/复位。
1:针对接收使能 DMA 模式
0:针对接收禁止 DMA 模式

进入停止模式的步骤
1.禁止DMA,记得在唤醒后在串口唤醒中断里面重新使能DMA即可(其实使用HAL库是有点小BUG,会导致无法重新使能,后面会说(看串口中断回调函数))
2.确认串口忙标志为0
3.确认串口做好接受数据准备
4.选择唤醒模式(接受完成唤醒,起始位唤醒,地址匹配唤醒)
5.配置串口使能唤醒中断,使能停止模式唤醒

下面介绍要使用的函数

  1. void UratEnterStopMode(UART_HandleTypeDef *UartHandle)
  2. {


  3.   UART_WakeUpTypeDef WakeUpSelection;
  4.   /* make sure that no UART transfer is on-going */
  5.   while(__HAL_UART_GET_FLAG(UartHandle, USART_ISR_BUSY) == SET);
  6.   /* make sure that UART is ready to receive
  7.    * (test carried out again later in HAL_UARTEx_StopModeWakeUpSourceConfig) */   
  8.   while(__HAL_UART_GET_FLAG(UartHandle, USART_ISR_REACK) == RESET);

  9.   /* set the wake-up event:
  10.    * specify wake-up on start-bit detection */
  11.   WakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_STARTBIT;
  12.   if (HAL_UARTEx_StopModeWakeUpSourceConfig(UartHandle, WakeUpSelection)!= HAL_OK)
  13.   {
  14.     Error_Handler();
  15.   }
  16.   HAL_UART_DMAPause(UartHandle);
  17.   printf("HAL_UART_DMAPause\n\r");
  18.   // __HAL_DMA_DISABLE(&hdma_lpuart1_rx);                        //禁止DMA;

  19.   /* Enable the UART Wake UP from stop mode Interrupt */
  20.   __HAL_UART_ENABLE_IT(UartHandle, UART_IT_WUF);

  21.   /* enable MCU wake-up by UART */
  22.   HAL_UARTEx_EnableStopMode(UartHandle);
  23.   /* enter stop mode */
  24.   HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);//进入停止模式
  25.   /* ... STOP mode ... */

  26.   /* at that point, MCU has been awoken: the LED has been turned back on */
  27.   /* Wake Up on start bit detection successful */
  28.   HAL_UARTEx_DisableStopMode(UartHandle);//唤醒后禁止串口唤醒低功耗模式
  29. }
复制代码

**然后在串口唤醒中断里面使能DMA即可
串口唤醒中断回调函数
  1. void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
  2. {

  3. //在这个回调函数之前HAL库的中断里面会改变huart->RxState = HAL_UART_STATE_READY; 导致HAL_UART_DMAResume(huart)不能恢复DMA
  4. //所以此时要 huart->RxState = HAL_UART_STATE_BUSY_RX;  
  5.   huart->RxState = HAL_UART_STATE_BUSY_RX;  
  6.   HAL_UART_DMAResume(huart);

  7.   printf("HAL_UART_DMAResume,receivedata8 is %d\n\r",0);
  8. }
复制代码

记得唤醒之后稍微延时一下,让串口数据接受完成在进入停止模式,不然数据会乱。

**下面重点来了**
这里稍微不注意就会发现 我唤醒之后接受到的数据怎么老是少第一个字节
经过我测试发现
是有一个设置的问题
下面看函数和寄存器描述
  1. /* Enable Ultra low power mode */
  2.    HAL_PWREx_EnableUltraLowPower();  //使能超低功耗,置位PWR_CR ULP位,VREFINT 在低功耗模式下关闭 更低功耗
复制代码
PWR_CR 位 9 ULP:超低功耗模式 (Ultra-low-power mode)
置 1 时,VREFINT 在低功耗模式下关闭。通过复位 RCC_APB1RSTR 寄存器中的 PWRRST
位不会复位该位。当该位置 1 时,寄存器 LCD_CR 的 LCDEN 位不能置 1。
0:VREFINT 在低功耗模式下打开
1:VREFINT 在低功耗模式下关闭

当我们调用HAL_PWREx_EnableUltraLowPower();使能超低低功耗模式
此时你使用9600(不包括9600)以下的波特率就不会少第一个字节 但是你的波特率在9600及以上,收到的数就会少第一个字节
但是我们能不能在超低功耗模式下唤醒,波特率超过9600情况下怎么办呢?
还有一个函数和寄存器描述
  1. /* Enable the fast wake up from Ultra low power mode */
  2.   HAL_PWREx_EnableFastWakeUp();              //使能快速唤醒,不会等待VREFINT就绪,比较快,9600波特率下不会丢数据,不用快速唤醒而且 VREFINT 在低功耗模式下关闭 9600波特率下丢数据 此时只能降低波特率才可以解决
复制代码

PWR_CR 位 10 FWU:快速唤醒 (Fast wakeup)
此位与 ULP 位结合使用。
如果 ULP = 0,则忽略 FWU
如果 ULP = 1 且 FWU = 1:从低功耗模式退出时忽略 VREFINT 启动时间。当 VREFINT 重新就
绪时,通过 PWR_CSR 寄存器中的 VREFINTRDYF 标志加以指示。
如果 ULP = 1 且 FWU = 0:仅当 VREFINT 就绪(其启动时间后)时,才会从低功耗模式退
出。通过复位 RCC_APB1RSTR 寄存器中的 PWRRST 位不会复位该位。
0:仅当 VREFINT 就绪时,才会退出低功耗模式
1:退出低功耗模式时忽略 VREFINT 启动时间

就是醒的时候不等待 VREFINT稳定,但是可能会影响ADC,这样在超低功耗模式下就能快速唤醒不丢第一个字节了
仅在9600下测试不会丢,其他未测

当然如果你不使能超低功耗模式,那就造吧。
最近一直在搞Linux,这个博客写了快一年了,都忘记了。有时间把RTC和LPTIM也更上。实测功耗在0.8uA左右。



收藏 评论0 发布时间:2021-11-17 22:01

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版