Событие обновления таймера (update event)
Запись нового значения в ARR или PSC таймера STM32 не всегда действует сразу. Большая часть регистров таймера буферизована: новое значение ждёт особого момента — события обновления, которое обычно совпадает с переполнением счётчика.
Обновлено Редакция GAW
Событие обновления (update event, UEV) — момент, когда таймер STM32 переносит предзагруженные значения регистров в теневые, которые реально управляют счётом. Обычно оно наступает при переполнении счётчика (при счёте вверх — переход от ARR к нулю), а также может быть вызвано программно битом UG в TIMx_EGR. В этот момент применяются новый период ARR (если включена его предзагрузка), новый предделитель PSC и значения CCRx каналов с предзагрузкой, а в TIMx_SR ставится флаг UIF (RM0090, разд. 17.3.1–17.3.2).
Что обновляется
| Регистр | Когда новое значение начинает действовать |
|---|---|
| ARR | сразу при ARPE = 0, по UEV при ARPE = 1 |
| PSC | всегда только по UEV |
| CCRx | сразу при OCxPE = 0, по UEV при OCxPE = 1 |
| RCR (TIM1, TIM8) | по UEV; UEV наступает раз в RCR + 1 переполнений |
Буферизация нужна, чтобы смена периода или заполнения не порвала текущий период ШИМ: новые значения вступают в силу на границе периода. Частота событий обновления при счёте вверх — fCNT / (ARR + 1), где fCNT — частота после предделителя; подобрать PSC и ARR помогает калькулятор таймера.
Управляющие биты
- UG (TIMx_EGR) — программное событие обновления: применяет PSC и ARR и обнуляет счётчик. HAL для STM32F4 вызывает его при каждой настройке таймера (TIM_Base_SetConfig).
- UDIS (TIMx_CR1) — запрещает события обновления, пока программа пишет несколько связанных регистров; счётчик при этом продолжает обнуляться.
- URS (TIMx_CR1) — при URS = 1 бит UG обновляет регистры, но не ставит UIF, и лишнего прерывания нет.
- UIF (TIMx_SR) — флаг события; вместе с UIE даёт прерывание обновления, с UDE — запрос DMA.
Где это видно на практике
Прерывание по UEV — основа периодических задач: при 84 МГц на входе, PSC = 8399 и ARR = 9999 оно случается раз в секунду (наш расчёт: 84 000 000 / 8400 / 10 000 = 1 Гц). Регистры каналов, которые обновляются по тому же событию, описаны в статье о канале захвата/сравнения, а режимы счёта — в статье «Таймеры STM32».
Частые вопросы
Почему новый предделитель начинает работать не сразу?
Регистр TIMx_PSC буферизован: записанное значение применится только на следующем событии обновления (RM0090, разд. 17.3.1). Чтобы применить его немедленно, после записи генерируют событие программно — битом UG в TIMx_EGR. Счётчик при этом обнуляется.
Почему прерывание обновления срабатывает сразу после запуска таймера?
Частая причина — программное событие UG при настройке: при URS = 0 оно ставит флаг UIF (RM0090, разд. 17.3.2), и как только прерывание разрешат, обработчик вызовется. Флаг сбрасывают перед разрешением прерывания или пишут UG при URS = 1. HAL v1.8.5 для STM32F4 так и делает: в TIM_Base_SetConfig перед битом UG ставится URS.
Включать ли предзагрузку ARR?
Если период меняют на ходу — да. При ARPE = 0 новое значение ARR действует сразу, и запись значения меньше текущего счётчика пропустит совпадение: счётчик дойдёт до конца диапазона. При ARPE = 1 новый период начнётся с границы текущего (RM0090, разд. 17.3.1). Это наш вывод из описания предзагрузки.
Источники
- STMicroelectronics. RM0090 Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439, Rev 21 — разд. 17.3.1 — ARR предзагружается, содержимое переходит в теневой регистр сразу или по UEV в зависимости от ARPE; UEV — при переполнении (антипереполнении), если UDIS = 0, и программно; счётчик стартует через такт после CEN; PSC буферизован и применяется на следующем UEV; 17.3.2 — с повторителем UEV через RCR + 1 переполнений; бит UG генерирует UEV; UDIS запрещает UEV; при URS = 1 UG даёт UEV без флага UIF; при UEV обновляются RCR, теневой ARR и буфер PSC, ставится UIF; 17.4.7 — OCxPE: CCRx загружается в активный регистр по событию обновления
- STMicroelectronics. STM32CubeF4 HAL driver v1.8.5, stm32f4xx_hal_tim.c — функция TIM_Base_SetConfig: после записи ARR, PSC и RCR ставит URS, чтобы не взвести UIF, и генерирует событие обновления битом UG — новые значения применяются сразу
Нашли ошибку?
Смотрите также
- Предделитель таймераPrescaler: делитель тактов перед счётчиком таймера
- Таймеры STM32Тактирование, PSC/ARR, ШИМ, мёртвое время, захват, энкодер, OPM, синхронизация
- Канал захвата/сравненияРегистр CCRx таймера: запоминает счётчик или сравнивается с ним
- Таймер AVR и STM32Предделитель, OCRnA, PSC и ARR под частоту, мёртвое время, энкодер
- ПрерываниеЗапрос периферии, вектор и обработчик прерывания