STMCU小助手
发布时间:2021-11-17 22:01
|
STM32L0低功耗应用 STM32L0支持7种低功耗模式,本文重点讨论停止(STOP)模式。 首先介绍几点影响功耗的因素。 1.IO口的状态,不用的IO口设置成模拟输入。) d* n# N6 G% G. [ 2.时钟,时钟越低功耗越低。 3.外设,禁用不使用的外设。 4.PLL是一个耗电大户,如果做低功耗还是把PLL禁用,直接HSE/HSI/MSI到SYSCLK。 5.内核电压,根据不同的运行速度和VDD电压调节动态调压器,达到速度与功耗的平衡。 9 L3 D' q! }- d; d7 a 官方描述如下:! s8 z& Y( B5 e/ H ' g1 \; u; k _ H/ {
( p. s* Z7 u5 @8 }7 x; T, L; o
* H( W- Z3 C" L, n3 y1 U* r# a 使用下面这个函数调节内核电压% M% C9 k: H$ R) y8 t1 k ' ?) T/ r2 i/ G
1.睡眠模式% u, B# l' V0 M 睡眠模式下只有CPU停止工作,所有外设继续工作,任何中断或者事件都能唤醒CPU,此时约16MHz/1mA。 9 C6 n( m9 C% z; X$ M# U 2.低功耗运行模式' f; s* G$ Y0 K2 N0 L& v/ O; C 低功耗运行模式使用 内部MSI RC振荡器为低速模式(最大工作频率131kHz),内部调压器在低功率模式下,时钟频率和可用外设都有限制。仅当 电压调节器 处于范围 2 时,才能进入低功耗运行模式。9 p0 k0 u6 H" a- I+ [ 3.低功耗睡眠模式6 @5 d9 U; M9 ~ 进入睡眠模式时,调整内部调压器为低功率模式,时钟频率和可用外设都有限制;一个典型的例子是计时器以32kHz的速度运行。当事件或中断触发唤醒时,系统将恢复到运行模式,并打开调节器0 _9 k" R7 U! M: Q 4.带RTC的停止模式) V" m( r" J4 N- s 停止模式在保持RAM和寄存器内容以及实时时钟的同时,实现了最低的功耗。Vcore域中的所有时钟都被停止禁用PLL、MSI RC、HSE和HSI。LSE或LSI仍在运行。调压器处于低功率模式。一些具有唤醒功能的外围设备可以使HSI在停止模式下检测它们的 触发唤醒的动作。* c' k9 m6 l$ N% F 设备可以被外部中断在3.5us内唤醒,处理器会进入唤醒中断后恢复现场。也可以被PVD中断,比较事件(如果此外设使能),RTC alarm/tamper/timestamp/wakeupevents, USB/USART/I2C/LPUART/LPTIMER 唤醒事件唤醒。 唤醒后需要重新配置时钟。 % h6 H" H1 g, d! v 5.不带RTC的停止模式" v3 R4 q5 e3 v, H3 ^ c- s 停止模式在保持RAM和寄存器内容以及实时时钟的同时,实现了最低的功耗。Vcore域中的所有时钟都被停止禁用PLL、MSI RC、HSE和HSI。LSE或LSI仍在运行。调压器处于低功率模式。一些具有唤醒功能的外围设备可以使HSI在停止模式下检测它们的 触发唤醒的动作。/ A6 c! {) u" Z+ F- L6 u! Q+ U 设备可以被外部中断在3.5us内唤醒,处理器会进入唤醒中断后恢复现场。也可以被PVD中断,比较事件(如果此外设使能),RTC alarm/tamper/timestamp/wakeupevents, USB/USART/I2C/LPUART/LPTIMER 唤醒事件唤醒。 唤醒后需要重新配置时钟。 & S- {0 a' O8 h 6.带RTC待机模式" R) S& I9 l& d# w! d 关闭内部电压调节器,从而关闭整个Vcore。PLL MSI HIS HSE 都被关闭,LSE/LSI在运行。8 i7 C* c$ w0 H! V1 J 除了备用电路中的寄存器外(wakeup logic, IWDG,RTC, LSI, LSE Crystal 32 KHz oscillator, RCC_CSR register),RAM和寄存器内容都丢失了。 设备会在以下情况在60us内被唤醒# K9 P( [( z8 X/ H& k8 K 1.外部引脚复位 2.IWDG复位 3.唤醒引脚上升沿% b l" `2 e3 V- n1 K$ I. Z 4.RTC Alarm tamper timestamp Wakeup 事件& ?9 W# g/ f; B6 t8 M. I: z ' y! h& v! u+ X- _# D1 }3 [6 } 7.不带RTC待机模式 关闭内部电压调节器,从而关闭整个Vcore。PLL MSI HIS HSE LSE LSI都被关闭。 除了备用电路中的寄存器外(wakeup logic, IWDG,RTC, LSI, LSE Crystal 32 KHz oscillator, RCC_CSR register),RAM和寄存器内容都丢失了。2 F" ]) u) v* m$ ?) @5 P8 n% O 设备会在以下情况在60us内被唤醒4 F' T* ^5 R% g+ \: A) _ 1.外部引脚复位 2.唤醒引脚上升沿 RTC 和IWDG 的时钟源进入停止或者待机模式不会自动停止。 进入STOP模式 停止模式基于 Cortex®-M0+ 深度睡眠模式与外设时钟门控。调压器既可以配置为正常模式,也可以配置为低功耗模式。在停止模式下,VCORE 域中的所有时钟都会停止,PLL、MSI、HSI16 和 HSE RC 振荡器也被禁止。内部 SRAM 和寄存器内容将保留。. _5 i" Z% v/ g, i+ C b! @ 要使停止模式下的功耗最低,内部 Flash 也进入低功耗模式。Flash 处于掉电模式时,将器件从停止模式唤醒将需要额外的启动延时。9 M" \& t0 V1 y3 @7 m# X. b 要使停止模式下的功耗最低,可在进入停止模式前关闭 VREFINT、BOR、PVD 和温度传感器。退出停止模式后,可以使用 PWR_CR 寄存器中的 ULP 位通过软件重新打开它们。 5 p2 I5 r! B$ Y 在停止模式下,所有 I/O 引脚的状态与运行模式下相同。0 T! y' R( I/ ~! U' [$ f/ \ 要求 – 没有中断(对于 WFI)或事件(对于 WFE)挂起。7 g- k6 Q* r' J; S* ^& [. `% S – 将 Cortex®-M0+ 系统控制寄存器中的 SLEEPDEEP 位置 11 c9 u. `& r9 }+ I6 s – 电源控制寄存器 (PWR_CR) 中的 PDDS 位 = 0 – 电源控制/状态寄存器 (PWR_CSR) 中的 WUF 位 = 0; |) x1 i5 c( N" w- A – 通过配置 RCC_CFGR 寄存器中的 STOPWUCK 位退出停止模式时,选0 k& r" n5 r+ m! B# }- W 择 MSI 或 HSI16 RC 振荡器作为系统时钟。 注: 要进入停止模式,所有 EXTI 线挂起位(在第 13.5.6 节:EXTI 挂起 寄存器 (EXTI_PR) 中)、所有外设中断挂起位、RTC 闹钟(闹钟 A 和闹钟 B)、RTC 唤醒、RTC 入侵和 RTC 时间戳标志位必须复1 S" A% X- ?5 e) B: e9 t- O 位。否则将忽略进入停止模式这一过程,继续执行程序。$ W* @ X- r y/ s( W) Z 下面咱们来看下寄存器描述' E; M/ [7 Y4 T3 X- C# A ' U1 G! C; Z0 B/ a 系统控制寄存器中的 SLEEPDEEP 位 我在ARM-CortexM0 权威指南上找到的
# V, y3 k! X3 ~+ M% a3 A (PWR_CR) PDDS位:掉电深度睡眠 (Power-down deepsleep) 此位由软件置 1 和清零。 0:器件在 CPU 进入深度睡眠时进入停止模式。调压器处于低功耗模式。 1:器件在 CPU 进入深度睡眠时进入待机模式。5 N4 Z$ ?( b1 ^2 ~6 f (PWR_CSR) WUF 位 该位通过硬件置 1,并且只能通过系统复位或通过将 PWR 电源控制寄存器 (PWR_CR) 中的 CWUF 位置 1 清零% G* _$ L# E" s/ O9 U: y4 a3 ]# P 0:未发生唤醒事件. ?* Q* j8 w( P$ ` 1:收到唤醒事件,可能来自 WKUP 引脚、RTC 闹钟(闹钟 A 和闹钟 B)、RTC 入侵事# h* P* x' J& z 件、RTC 时间戳事件或 RTC 唤醒事件。& F# @4 A) a' i. G 注: 如果使能 WKUP 引脚(将 EWUPx (x=1, 2, 3) 位置 1)时 WKUP 引脚已为高电平,系 统将检测到另一唤醒事件。1 t& U! f! }. P6 o$ o4 e . J! d$ _- G( T8 r0 f 然后还要配置选择唤醒后的时钟源 通过此函数 I, m" D7 W5 x& m- H% Y
唤醒后如果需要,记得重新配置时钟。, F' x' A, g& u* A* ]/ v, W 7 j4 N' T4 h) N3 t w LPUART在DMA模式下唤醒STOP ^4 L4 U! W* ], N2 c. [( E 不讨论怎么实现DMA,只讨论唤醒SOTP模式。 首先咱们来看官方描述 # P- t1 P/ `5 U1 |
9 L+ u& f( X e# A, p6 J 我使用的是LSE时钟, H; b6 d" Y7 J9 S0 z' F- N5 ? 其实官方手册有这样一段描述( ~; a% D( B3 e" }5 ^ x! Y 当 DMA 用于接收时,它必须在进入停止模式前禁止,并在退出停止模式后重新使能。 从停止模式唤醒功能并非在所有模式下均可用。例如,该功能在 SPI 模式下不起作用,因为 SPI 仅在主模式下工作。 也就是说要在进入STOP模式前禁止DMA。这里不是去操作DMA的寄存器去禁止DMA,而是在LPUART里面的寄存器DMAR位禁止即可。 ^2 }, c6 g9 \5 L LPUART_CR3(DMAR位) Y9 X, N- v+ Z4 ` 位 6 DMAR:DMA 使能接收器 (DMA enable receiver)0 w! w6 u" V4 Q3 Z$ K( g 此位由软件置 1/复位。 1:针对接收使能 DMA 模式 0:针对接收禁止 DMA 模式0 i4 _" f9 U/ a6 F% W9 k7 `1 M 进入停止模式的步骤 1.禁止DMA,记得在唤醒后在串口唤醒中断里面重新使能DMA即可(其实使用HAL库是有点小BUG,会导致无法重新使能,后面会说(看串口中断回调函数)) 2.确认串口忙标志为06 F: ^1 o! S N; z1 i 3.确认串口做好接受数据准备8 v# @$ U `5 e0 @* C) p- F- t 4.选择唤醒模式(接受完成唤醒,起始位唤醒,地址匹配唤醒) 5.配置串口使能唤醒中断,使能停止模式唤醒1 ~7 D5 A! M/ f1 p: T1 q R* {$ L' _ 1 W! j7 _5 m+ b+ Z 下面介绍要使用的函数
**然后在串口唤醒中断里面使能DMA即可 串口唤醒中断回调函数
记得唤醒之后稍微延时一下,让串口数据接受完成在进入停止模式,不然数据会乱。; T! C7 j. e) Y6 b **下面重点来了** 这里稍微不注意就会发现 我唤醒之后接受到的数据怎么老是少第一个字节 经过我测试发现 是有一个设置的问题 下面看函数和寄存器描述
置 1 时,VREFINT 在低功耗模式下关闭。通过复位 RCC_APB1RSTR 寄存器中的 PWRRST6 H9 O, ~/ j- M6 \) ~ 位不会复位该位。当该位置 1 时,寄存器 LCD_CR 的 LCDEN 位不能置 1。: g) e7 U8 V% t# i# M- S2 r; n' N% e 0:VREFINT 在低功耗模式下打开. B2 f& r$ v2 {! x9 F& s. t4 p/ o9 O 1:VREFINT 在低功耗模式下关闭 ) Q. [+ C: j: ^9 q 当我们调用HAL_PWREx_EnableUltraLowPower();使能超低低功耗模式 此时你使用9600(不包括9600)以下的波特率就不会少第一个字节 但是你的波特率在9600及以上,收到的数就会少第一个字节 但是我们能不能在超低功耗模式下唤醒,波特率超过9600情况下怎么办呢?$ S+ R! a: f1 I8 | 还有一个函数和寄存器描述
PWR_CR 位 10 FWU:快速唤醒 (Fast wakeup) 此位与 ULP 位结合使用。- E+ U& [8 l7 p" v 如果 ULP = 0,则忽略 FWU9 [) L& Q# s3 N: Q+ k, v 如果 ULP = 1 且 FWU = 1:从低功耗模式退出时忽略 VREFINT 启动时间。当 VREFINT 重新就. X/ ~2 ?9 {9 ^ 绪时,通过 PWR_CSR 寄存器中的 VREFINTRDYF 标志加以指示。1 Y6 r5 B2 T2 _ h 如果 ULP = 1 且 FWU = 0:仅当 VREFINT 就绪(其启动时间后)时,才会从低功耗模式退& Y6 C; q" ]: S/ I! ]' E! a 出。通过复位 RCC_APB1RSTR 寄存器中的 PWRRST 位不会复位该位。 0:仅当 VREFINT 就绪时,才会退出低功耗模式- {' A" y% M3 C I& N0 G 1:退出低功耗模式时忽略 VREFINT 启动时间2 t! g) q0 z H5 }* w2 x 就是醒的时候不等待 VREFINT稳定,但是可能会影响ADC,这样在超低功耗模式下就能快速唤醒不丢第一个字节了 仅在9600下测试不会丢,其他未测6 Z ?. v6 @6 t7 z4 r) p4 M 当然如果你不使能超低功耗模式,那就造吧。0 r9 P: @' O0 t, Z; f( P, i 最近一直在搞Linux,这个博客写了快一年了,都忘记了。有时间把RTC和LPTIM也更上。实测功耗在0.8uA左右。 5 _# r/ ?( Z z" T d0 O2 E . ]" }6 x( g( k$ Z 1 R8 R" S( H: G7 O$ n |
微信公众号
手机版