STMCU小助手
发布时间:2021-11-17 22:01
|
STM32L0低功耗应用 STM32L0支持7种低功耗模式,本文重点讨论停止(STOP)模式。 2 z! E, C" M- p0 z" D Y( L l* b 首先介绍几点影响功耗的因素。4 \/ ?: Q$ D. z' P8 b( [1 G 1.IO口的状态,不用的IO口设置成模拟输入。 2.时钟,时钟越低功耗越低。 3.外设,禁用不使用的外设。 4.PLL是一个耗电大户,如果做低功耗还是把PLL禁用,直接HSE/HSI/MSI到SYSCLK。% P: u! A+ I0 X4 Q# | 5.内核电压,根据不同的运行速度和VDD电压调节动态调压器,达到速度与功耗的平衡。 官方描述如下: ' a; U9 W* H! U
2 i H' H: @+ D7 p* V! @; e1 Q 使用下面这个函数调节内核电压
1.睡眠模式9 R4 \0 N" _7 w* a. z 睡眠模式下只有CPU停止工作,所有外设继续工作,任何中断或者事件都能唤醒CPU,此时约16MHz/1mA。# v5 X5 G+ }' {" G/ x7 ~ 9 _. y9 c' O% l/ s( y( ? 2.低功耗运行模式8 I0 H, j6 K( |# x+ c6 r 低功耗运行模式使用 内部MSI RC振荡器为低速模式(最大工作频率131kHz),内部调压器在低功率模式下,时钟频率和可用外设都有限制。仅当 电压调节器 处于范围 2 时,才能进入低功耗运行模式。 3.低功耗睡眠模式( ?, b A9 x) E 进入睡眠模式时,调整内部调压器为低功率模式,时钟频率和可用外设都有限制;一个典型的例子是计时器以32kHz的速度运行。当事件或中断触发唤醒时,系统将恢复到运行模式,并打开调节器% N9 h1 Q& `! H6 p ( e$ q6 Z. @( X1 I1 u 4.带RTC的停止模式8 N' h- l+ q$ A 停止模式在保持RAM和寄存器内容以及实时时钟的同时,实现了最低的功耗。Vcore域中的所有时钟都被停止禁用PLL、MSI RC、HSE和HSI。LSE或LSI仍在运行。调压器处于低功率模式。一些具有唤醒功能的外围设备可以使HSI在停止模式下检测它们的 触发唤醒的动作。& g6 g$ H; f- I) [+ d9 F 设备可以被外部中断在3.5us内唤醒,处理器会进入唤醒中断后恢复现场。也可以被PVD中断,比较事件(如果此外设使能),RTC alarm/tamper/timestamp/wakeupevents, USB/USART/I2C/LPUART/LPTIMER 唤醒事件唤醒。 唤醒后需要重新配置时钟。' t/ R J0 \1 I# q* z. h. X5 i 5.不带RTC的停止模式+ B6 J5 ~+ j7 E8 d3 X 停止模式在保持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待机模式1 K- e$ v$ V) r& n- Q 关闭内部电压调节器,从而关闭整个Vcore。PLL MSI HIS HSE 都被关闭,LSE/LSI在运行。- Y* R0 x5 v* T( X% _- S. \: Y: E 除了备用电路中的寄存器外(wakeup logic, IWDG,RTC, LSI, LSE Crystal 32 KHz oscillator, RCC_CSR register),RAM和寄存器内容都丢失了。 设备会在以下情况在60us内被唤醒9 G( W \. Q" W3 g0 Z 1.外部引脚复位, G; F6 c7 c$ H 2.IWDG复位 3.唤醒引脚上升沿4 f! V" X4 A/ k2 t& `: ? ?* \ 4.RTC Alarm tamper timestamp Wakeup 事件0 _- U/ r3 @0 g8 X1 Y. E) l 7.不带RTC待机模式3 s3 f2 p _' ^# n( x, R 关闭内部电压调节器,从而关闭整个Vcore。PLL MSI HIS HSE LSE LSI都被关闭。/ q; ~& v v' s 除了备用电路中的寄存器外(wakeup logic, IWDG,RTC, LSI, LSE Crystal 32 KHz oscillator, RCC_CSR register),RAM和寄存器内容都丢失了。 设备会在以下情况在60us内被唤醒5 f8 N% Q, y; j+ S1 A: x- l7 I: A 1.外部引脚复位 2.唤醒引脚上升沿7 i3 ]9 U; c" G3 |7 d RTC 和IWDG 的时钟源进入停止或者待机模式不会自动停止。0 A: O f/ `( {- E 进入STOP模式% L) Z8 Z! n; A# A 停止模式基于 Cortex®-M0+ 深度睡眠模式与外设时钟门控。调压器既可以配置为正常模式,也可以配置为低功耗模式。在停止模式下,VCORE 域中的所有时钟都会停止,PLL、MSI、HSI16 和 HSE RC 振荡器也被禁止。内部 SRAM 和寄存器内容将保留。 要使停止模式下的功耗最低,内部 Flash 也进入低功耗模式。Flash 处于掉电模式时,将器件从停止模式唤醒将需要额外的启动延时。( K! B9 ^5 L) d f3 F 要使停止模式下的功耗最低,可在进入停止模式前关闭 VREFINT、BOR、PVD 和温度传感器。退出停止模式后,可以使用 PWR_CR 寄存器中的 ULP 位通过软件重新打开它们。4 y9 r* u- O8 j8 y k. Y ! L& o$ @( G* i 在停止模式下,所有 I/O 引脚的状态与运行模式下相同。 & `# ]( p! C( Z0 | 要求6 y8 d5 Y, [/ }( X' i! h 8 ], {6 ~( C: ]( z( Y – 没有中断(对于 WFI)或事件(对于 WFE)挂起。/ m5 Z: I2 M: t e; L – 将 Cortex®-M0+ 系统控制寄存器中的 SLEEPDEEP 位置 12 z! W) [. F( M7 j2 u- Y – 电源控制寄存器 (PWR_CR) 中的 PDDS 位 = 0 – 电源控制/状态寄存器 (PWR_CSR) 中的 WUF 位 = 0 – 通过配置 RCC_CFGR 寄存器中的 STOPWUCK 位退出停止模式时,选& i% }2 C* b' E5 W. k 择 MSI 或 HSI16 RC 振荡器作为系统时钟。6 }$ ?% ^2 _% j( K3 Q 注: 要进入停止模式,所有 EXTI 线挂起位(在第 13.5.6 节:EXTI 挂起6 j* ]+ m, U, B9 x, ?# h 寄存器 (EXTI_PR) 中)、所有外设中断挂起位、RTC 闹钟(闹钟 A 和闹钟 B)、RTC 唤醒、RTC 入侵和 RTC 时间戳标志位必须复 位。否则将忽略进入停止模式这一过程,继续执行程序。4 c, O. ^5 e. I$ V 4 N( k% a/ [3 _9 s# g 下面咱们来看下寄存器描述8 @+ s5 h9 V& G. W& _ 6 `+ T$ o T2 @6 a A. G 系统控制寄存器中的 SLEEPDEEP 位1 Q, o. ]( q* [. L# |7 g! H: ]4 J7 b4 p6 D 我在ARM-CortexM0 权威指南上找到的
+ o$ ^3 U: \" u5 |* I S (PWR_CR) PDDS位:掉电深度睡眠 (Power-down deepsleep) 此位由软件置 1 和清零。 0:器件在 CPU 进入深度睡眠时进入停止模式。调压器处于低功耗模式。5 |8 N6 B _" ?, W/ x 1:器件在 CPU 进入深度睡眠时进入待机模式。 (PWR_CSR) WUF 位% a( J- }; G: l2 g' ~, D 该位通过硬件置 1,并且只能通过系统复位或通过将 PWR 电源控制寄存器 (PWR_CR) 中的7 i; R) `5 _6 X7 s8 g) o/ k+ N5 k CWUF 位置 1 清零 0:未发生唤醒事件 1:收到唤醒事件,可能来自 WKUP 引脚、RTC 闹钟(闹钟 A 和闹钟 B)、RTC 入侵事0 I& C# z$ \* Y; ^" M 件、RTC 时间戳事件或 RTC 唤醒事件。- }6 t+ O+ g: \ 注: 如果使能 WKUP 引脚(将 EWUPx (x=1, 2, 3) 位置 1)时 WKUP 引脚已为高电平,系% ?6 P' A0 z) X 统将检测到另一唤醒事件。 * N4 ^7 O3 \2 X; X 然后还要配置选择唤醒后的时钟源/ Y7 N; }2 A! y9 H& B p 通过此函数
唤醒后如果需要,记得重新配置时钟。 9 A, u- @8 M& T( M8 O1 m2 j" q4 A$ v LPUART在DMA模式下唤醒STOP7 v9 D" s- D+ S3 X9 c" O" B 不讨论怎么实现DMA,只讨论唤醒SOTP模式。 首先咱们来看官方描述 : r& Q+ ?$ N1 g$ G. |6 R ~+ m
* g- A' r3 Z& Y- a2 L% h% f 我使用的是LSE时钟 9 E% _. C; J9 ?8 ] M 其实官方手册有这样一段描述; i A) Y) [# [: d( ?; ^7 H O 当 DMA 用于接收时,它必须在进入停止模式前禁止,并在退出停止模式后重新使能。 从停止模式唤醒功能并非在所有模式下均可用。例如,该功能在 SPI 模式下不起作用,因为 SPI 仅在主模式下工作。) r) a# c" n) E" P! h 也就是说要在进入STOP模式前禁止DMA。这里不是去操作DMA的寄存器去禁止DMA,而是在LPUART里面的寄存器DMAR位禁止即可。9 D$ r- J# q) G+ Q& w LPUART_CR3(DMAR位), F x! N7 F7 [9 O+ k) |. X 位 6 DMAR:DMA 使能接收器 (DMA enable receiver)- I# T" W4 K( F3 K 此位由软件置 1/复位。 1:针对接收使能 DMA 模式 0:针对接收禁止 DMA 模式5 l; S2 r" [4 f6 }9 t) n ; p6 i7 E) \3 R) |0 l 进入停止模式的步骤 1.禁止DMA,记得在唤醒后在串口唤醒中断里面重新使能DMA即可(其实使用HAL库是有点小BUG,会导致无法重新使能,后面会说(看串口中断回调函数)) l, k0 T! T. r 2.确认串口忙标志为0) B1 X8 b3 Z2 J. L) ? 3.确认串口做好接受数据准备 4.选择唤醒模式(接受完成唤醒,起始位唤醒,地址匹配唤醒)8 t" _4 t" w/ L4 e8 h8 A/ i 5.配置串口使能唤醒中断,使能停止模式唤醒 ' K1 c6 o8 ]8 t' y4 h- l2 C 下面介绍要使用的函数( I" ~* ?' b) T; A
**然后在串口唤醒中断里面使能DMA即可 串口唤醒中断回调函数$ W) a9 G+ U, l' m8 s
记得唤醒之后稍微延时一下,让串口数据接受完成在进入停止模式,不然数据会乱。+ ^; R1 _ L. Q1 b) Z' s; D( w& V **下面重点来了** 这里稍微不注意就会发现 我唤醒之后接受到的数据怎么老是少第一个字节 经过我测试发现; A7 Y# G" Y; l1 w+ E 是有一个设置的问题 下面看函数和寄存器描述
置 1 时,VREFINT 在低功耗模式下关闭。通过复位 RCC_APB1RSTR 寄存器中的 PWRRST 位不会复位该位。当该位置 1 时,寄存器 LCD_CR 的 LCDEN 位不能置 1。; ]2 L' r* e4 ^( N2 r& e( `8 H 0:VREFINT 在低功耗模式下打开 1:VREFINT 在低功耗模式下关闭 + @9 O9 k8 j1 ], Z- O6 d* l 当我们调用HAL_PWREx_EnableUltraLowPower();使能超低低功耗模式/ I1 ~/ g j& a' s 此时你使用9600(不包括9600)以下的波特率就不会少第一个字节 但是你的波特率在9600及以上,收到的数就会少第一个字节; b% Z% Q, v H; k$ q V 但是我们能不能在超低功耗模式下唤醒,波特率超过9600情况下怎么办呢?0 I" D3 J' q" M1 g 还有一个函数和寄存器描述
PWR_CR 位 10 FWU:快速唤醒 (Fast wakeup)9 K+ {% r, k' t# D: z/ e3 Q z5 _ 此位与 ULP 位结合使用。2 h3 q5 x( P( {/ h" }% n 如果 ULP = 0,则忽略 FWU 如果 ULP = 1 且 FWU = 1:从低功耗模式退出时忽略 VREFINT 启动时间。当 VREFINT 重新就 绪时,通过 PWR_CSR 寄存器中的 VREFINTRDYF 标志加以指示。9 Z, `) e$ T( R$ l- O) G A; X 如果 ULP = 1 且 FWU = 0:仅当 VREFINT 就绪(其启动时间后)时,才会从低功耗模式退+ s4 j' t0 u L# K 出。通过复位 RCC_APB1RSTR 寄存器中的 PWRRST 位不会复位该位。 0:仅当 VREFINT 就绪时,才会退出低功耗模式+ h/ r) P& q" v" x; l5 g 1:退出低功耗模式时忽略 VREFINT 启动时间: N5 ]" A: F( A8 U6 s* [1 f: Y0 @ # l1 Y6 w3 v4 A e7 k; u3 w 就是醒的时候不等待 VREFINT稳定,但是可能会影响ADC,这样在超低功耗模式下就能快速唤醒不丢第一个字节了 仅在9600下测试不会丢,其他未测- Q1 m n, w5 ^: D, ? 3 M1 N! d E) j* Y/ v 当然如果你不使能超低功耗模式,那就造吧。$ `8 E* m0 f8 W! s 最近一直在搞Linux,这个博客写了快一年了,都忘记了。有时间把RTC和LPTIM也更上。实测功耗在0.8uA左右。 |
微信公众号
手机版