Почему STM32L0 сразу просыпается из режима Standby?
Обновлено Редакция GAW
В Standby у STM32L0 отключается ядро и пропадает содержимое ОЗУ, а выход из режима — это сброс: программа начинается сначала, а флаг SBF подсказывает, что был сон (термин «Режим Standby»). Если же микроконтроллер «просыпается» мгновенно, причина почти всегда в условиях входа из табл. 40 RM0377.
Условия входа и типичные ошибки
| Условие по RM0377 | Ошибка | Результат |
|---|---|---|
| WUF = 0 | флаг остался от прошлого события | Standby не наступает или сразу выход |
| Флаг источника RTC сброшен | висит ALRAF или WUTF | то же |
| EWUPx включают при низком уровне на WKUP | включили при высоком | дополнительное событие, мгновенный выход |
| PDDS = 1 и SLEEPDEEP = 1 | PDDS = 0 | вместо Standby — Stop |
Важная тонкость — порядок. Бит CWUF сбрасывает WUF не сразу, а через два такта системной частоты, а включение EWUPx при высоком уровне на выводе тут же ставит WUF снова. Поэтому вывод пробуждения включают раньше, чем сбрасывают флаг:
// Standby entry order for STM32L0 (RM0377, 6.3.10, 6.4.1, 6.4.2)
while (GPIOA->IDR & GPIO_IDR_ID0) { } // WKUP pin must be low first
PWR->CSR |= PWR_CSR_EWUP1; // enable wakeup pin
PWR->CR |= PWR_CR_CWUF | PWR_CR_PDDS; // clear WUF, select Standby
(void)PWR->CR; // let CWUF take effect
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
Какой вывод корпуса соответствует WKUP1–WKUP3, указано в даташите конкретного STM32L0; в примере взят PA0, проверьте его для своей микросхемы. Если пробуждение идёт от RTC, перед входом сбрасывают флаг будильника или таймера пробуждения в RTC_ISR.
Как отличить причины
Поставьте в начало main() чтение флагов. SBF в PWR_CSR показывает, что Standby действительно был. Источник пробуждения показывает WUF в том же PWR_CSR — регистр не сбрасывается при выходе из Standby, — а для RTC уточняют флаг в RTC_ISR: будильник, таймер пробуждения, tamper или метка времени. Флаги сброса в RCC_CSR говорят только о причине сброса, например вывод NRST или IWDG (термин «Флаги сброса»). Если SBF = 0, вход в Standby был проигнорирован, и программа после WFI просто пошла дальше. Если для задачи достаточно сохранить ОЗУ, проще использовать Stop — что мешает низкому току там, разобрано в ответе «Почему STM32L0 потребляет много тока в Stop». Обзор семейства — на странице STM32L0.
Похожие вопросы
Как программа узнаёт, что проснулась из Standby?
По флагу SBF в PWR_CSR: его ставит аппаратура, а сбрасывает только сброс по питанию или запись бита CSBF. Проверьте SBF в начале main(), примите решение и сбросьте флаг, иначе после обычного сброса кнопкой программа решит, что снова вышла из Standby.
Почему после пробуждения бит EWUP1 снова равен нулю?
Выход из Standby — это системный сброс, а EWUPx по RM0377 сбрасываются системным сбросом. Поэтому вывод пробуждения включают заново перед каждым входом в Standby.
Можно ли разбудить STM32L0 из Standby спадом на выводе?
Выводы WKUP у STM32L0 реагируют только на нарастающий фронт: с битом EWUPx вывод подтягивается к земле, и пробуждает переход в высокий уровень. Для кнопки, замыкающей на землю, нужна инверсия снаружи или другой источник пробуждения, например RTC.
Источники
- STMicroelectronics. RM0377 Reference manual: Ultra-low-power STM32L0x1 advanced Arm-based 32-bit MCUs, Rev 10 — разд. 6.3.10: в Standby выводы в высокоимпедансном состоянии, кроме сброса, WKUP1–WKUP3 и выводов RTC; выход — сброс NRST, сброс IWDG, нарастающий фронт на WKUP, будильник, tamper, метка времени RTC; после выхода программа стартует как после сброса, флаг SBF показывает Standby; табл. 40: вход при SLEEPDEEP = 1, PDDS = 1, WUF = 0 и сброшенном флаге источника RTC; разд. 6.4.1: CWUF сбрасывает WUF через 2 такта системной частоты, CSBF сбрасывает SBF; разд. 6.4.2: EWUP1–EWUP3 (биты 8–10) переводят вывод в режим входа с подтяжкой к земле, сбрасываются системным сбросом; WUF ставится по выводу WKUP и по событиям RTC (будильник, tamper, метка времени, таймер пробуждения), PWR_CSR не сбрасывается при выходе из Standby; примечание к WUF: если EWUPx включают при высоком уровне на WKUP, детектируется дополнительное событие пробуждения
- STMicroelectronics. cmsis-device-l0, Include/stm32l053xx.h (commit 7b7ae8c) — PWR_CR_PDDS — бит 1, PWR_CR_CWUF — бит 2, PWR_CR_CSBF — бит 3; PWR_CSR_WUF — бит 0, PWR_CSR_SBF — бит 1, PWR_CSR_EWUP1 — бит 8
Нашли ошибку?
Смотрите также
- Режим StandbyСамый экономный режим STM32: ядро обесточено, выход через сброс
- STM32L0Cortex-M0+, до 32 МГц, малое потребление: L010, L0x1, L0x2 с USB, L0x3 с ЖКИ — линейки и распиновки
- Почему STM32L0 потребляет много тока в режиме Stop?DBG_STOP, ULP = 0, LPSDSR = 0, цифровые входы и висящие флаги EXTI
- Флаги причины сбросаКак узнать, почему перезапустился микроконтроллер
- WFI и WFEКоманды ожидания прерывания и события для входа ядра в сон