Как разбудить STM32L0 из Stop таймером RTC?
Обновлено Редакция GAW
У RTC в STM32L0 есть отдельный таймер пробуждения — 16-битный счётчик, который считает вниз и в режиме Stop. Его удобно использовать для периодического опроса датчиков: микроконтроллер спит, а RTC будит его через заданное время.
Какой период можно получить
Флаг WUTF ставится каждые WUT + 1 тактов выбранного источника:
| WUCKSEL | Такт при LSE 32,768 кГц | Диапазон периода | Пример: 10 с |
|---|---|---|---|
| 000, RTC/16 | 2048 Гц | до 32 с, шаг 488 мкс | WUT = 20 479 |
| 011, RTC/2 | 16 384 Гц | от 122 мкс, шаг 61 мкс | не помещается в 16 бит |
| 100, ck_spre | 1 Гц | от 1 с до 18 ч | WUT = 9 |
| 110, ck_spre + 2¹⁶ | 1 Гц | от 18 до 36 ч | — |
Значения WUT в примерах — наш расчёт по формуле. Частота ck_spre 1 Гц получается делителями PREDIV_A и PREDIV_S, их подбирает калькулятор RTC STM32.
Порядок настройки
// RTC wakeup every 10 s from ck_spre = 1 Hz (RM0377, 22.4.6, 22.4.7)
RTC->WPR = 0xCA; RTC->WPR = 0x53; // unlock RTC registers
RTC->CR &= ~RTC_CR_WUTE;
while (!(RTC->ISR & RTC_ISR_WUTWF)) { }
RTC->WUTR = 9; // (9 + 1) s
RTC->CR = (RTC->CR & ~RTC_CR_WUCKSEL) | RTC_CR_WUCKSEL_2; // 100: ck_spre
RTC->CR |= RTC_CR_WUTIE | RTC_CR_WUTE;
RTC->WPR = 0xFF; // lock again
EXTI->IMR |= EXTI_IMR_IM20;
EXTI->RTSR |= EXTI_RTSR_RT20; // rising edge wakes from Stop
До этого RTC должен быть включён: снят бит защиты домена DBP, запущен LSE или LSI, выбран источник RTCSEL и включён RTCEN. Если LSE не встаёт, начните с ответа «Почему не запускается кварц LSE на STM32L0». В обработчике прерывания сбрасывают флаг WUTF и флаг линии 20 в EXTI_PR — как устроены линии внешних прерываний, описано в термине «EXTI». Другие особенности семейства — на странице STM32L0.
Похожие вопросы
Чем таймер пробуждения лучше будильника RTC?
Будильник срабатывает на заданное время календаря, а таймер пробуждения — периодически, сам перезагружаясь значением из RTC_WUTR. Для опроса датчика раз в 10 секунд таймер проще: его не нужно перенастраивать после каждого срабатывания.
Почему микроконтроллер просыпается только один раз?
Скорее всего, не сброшен флаг WUTF в RTC_ISR или флаг линии 20 в EXTI_PR. Таймер перезагружается сам, но, пока WUTF установлен, новый фронт на линии EXTI не возникает. Оба флага сбрасывают в обработчике прерывания RTC.
Можно ли тактировать RTC от LSI вместо кварца?
Можно, выбрав LSI битами RTCSEL в RCC_CSR, но период пробуждения будет таким же неточным, как сам RC-генератор LSI. Для пробуждения раз в несколько секунд это обычно приемлемо, для часов — нет.
Источники
- STMicroelectronics. RM0377 Reference manual: Ultra-low-power STM32L0x1 advanced Arm-based 32-bit MCUs, Rev 10 — разд. 22.4.6: 16-битный перезагружаемый счётчик пробуждения, расширяется до 17 бит; от RTCCLK/2…/16 при LSE — период от 122 мкс до 32 с с разрешением 61 мкс; от ck_spre 1 Гц — от 1 с до 18 ч при WUCKSEL[2:1] = 10 и до 36 ч при 11; счёт продолжается в режимах малого потребления, флаг WUTF сбрасывают программно; разд. 22.4.7: порядок — сбросить WUTE, дождаться WUTWF, записать WUT и WUCKSEL, установить WUTE; разд. 22.4.7: снятие защиты — 0xCA, затем 0x53 в RTC_WPR; разд. 22.7.6: WUTF ставится каждые (WUT + 1) тактов ck_wut, WUT = 0 при RTC/2 запрещено; разд. 22.7.3: WUCKSEL 000 — RTC/16, 001 — RTC/8, 010 — RTC/4, 011 — RTC/2, 10x — ck_spre, 11x — ck_spre и +2¹⁶; разд. 6.3.11: пробуждение из Stop таймером — линия EXTI 20 по нарастающему фронту и прерывание WUTIE
- STMicroelectronics. cmsis-device-l0, Include/stm32l053xx.h (commit 7b7ae8c) — RTC->WPR (смещение 0x24), RTC->WUTR (0x14); RTC_CR: WUCKSEL — биты 2:0, WUTE — бит 10, WUTIE — бит 14; RTC_ISR: WUTWF — бит 2, WUTF — бит 10; EXTI_IMR_IM20 и EXTI_RTSR_RT20 — бит 20
Нашли ошибку?
Смотрите также
- Часы RTC STM32PREDIV_A, PREDIV_S, PRL, калибровка CALP/CALM и CAL, уход в с/сут
- RTCСчётчик времени в режимах сна: источники такта, счётчик и календарь
- STM32L0Cortex-M0+, до 32 МГц, малое потребление: L010, L0x1, L0x2 с USB, L0x3 с ЖКИ — линейки и распиновки
- Почему не запускается кварц LSE 32,768 кГц на STM32L0?DBP не установлен, LSEDRV = 00, gmcrit кварца выше Gm_crit_max
- EXTI — внешние прерывания STM32Линии, которые превращают фронт на выводе в прерывание или событие