Перейти к содержанию

EXTI — контроллер внешних прерываний STM32

Кнопка на выводе PA0 должна вызвать прерывание, а датчик на PB5 — разбудить микроконтроллер. В STM32 за это отвечает не NVIC, а отдельный блок EXTI: он следит за фронтами на выводах и внутренних сигналах и передаёт запрос дальше.

Обновлено Редакция GAW

EXTI (external interrupt/event controller, контроллер внешних прерываний и событий) — блок микроконтроллеров STM32, который следит за фронтами на выводах GPIO и на нескольких внутренних сигналах и превращает их в запрос прерывания для NVIC или в событие, будящее ядро. У каждой линии свой выбор фронта и своя маска; у STM32F4 линий 23 (RM0090, разд. 12.2.1). Приоритет и разрешение самого прерывания по-прежнему задаёт NVIC — EXTI только формирует запрос.

Линии и выводы

Линий для выводов 16: линия n обслуживает выводы с номером n всех портов — PAn, PBn, PCn и так далее, но к линии в каждый момент подключён один порт. Его выбирает четырёхбитное поле EXTIn в регистрах SYSCFG_EXTICR1…SYSCFG_EXTICR4 (RM0090, разд. 12.2.5). Остальные линии STM32F4 подключены к внутренним сигналам:

ЛинияИсточник
16выход PVD
17будильник RTC (Alarm)
18пробуждение USB OTG FS
19пробуждение Ethernet
20пробуждение USB OTG HS (в режиме FS)
21Tamper и TimeStamp RTC
22пробуждение RTC (Wakeup)

Отдельные векторы есть только у линий 0–4 (EXTI0…EXTI4); линии 5–9 делят вектор EXTI9_5, линии 10–15 — EXTI15_10. У других серий состав линий и регистр выбора порта свои. У STM32F1 линий 19, а у connectivity line — 20 (RM0008, разд. 10.2); порт выбирают регистры AFIO_EXTICR1…4 (перед этим включают тактирование AFIO), а внутренние линии такие: 16 — PVD, 17 — будильник RTC, 18 — пробуждение USB, 19 — пробуждение Ethernet у connectivity line (RM0008, разд. 10.2.5).

Как настроить

Порядок настройки прерывания по выводу — по RM0090 (разд. 12.2.4; регистры SYSCFG — разд. 9.2):

  1. включить тактирование SYSCFG (бит SYSCFGEN в RCC_APB2ENR) и выбрать порт в SYSCFG_EXTICR;
  2. выбрать фронт в EXTI_RTSR (нарастающий) и EXTI_FTSR (спадающий), можно оба;
  3. снять маску линии в EXTI_IMR;
  4. разрешить и настроить вектор линии в NVIC.

Когда выбранный фронт приходит, ставится бит линии в EXTI_PR и уходит запрос в NVIC. Бит сбрасывают записью единицы. Запрос можно создать и программно — записью в EXTI_SWIER. Вместо прерывания линию можно включить как событие (маска EXTI_EMR): тогда она будит ядро из WFE, а флаг ожидания не ставится (разд. 12.2.3). Это удобно в режимах сна, когда обработчик не нужен. Готовые примеры кода и разбор векторов — в статье «Прерывания STM32».

Не путать

  • С NVIC: NVIC — контроллер прерываний ядра Cortex-M с приоритетами, EXTI — периферийный блок STM32 перед ним.
  • С внешними прерываниями AVR (INT0, INT1, PCINT): идея та же, но у AVR выводы закреплены за векторами жёстко, без выбора порта; см. прерывание по изменению вывода.

Частые вопросы

Можно ли получить отдельные прерывания от PA0 и PB0?

Нет. Линия EXTI 0 обслуживает выводы с номером 0 всех портов, но в каждый момент к ней подключён только один порт — его выбирает поле EXTI0[3:0] в регистре SYSCFG_EXTICR1 (RM0090, разд. 12.2.5). Если нужны два независимых прерывания, источники разводят на выводы с разными номерами, например PA0 и PB1.

Почему обработчик EXTI вызывается снова и снова?

Флаг ожидания в EXTI_PR сам не снимается: его сбрасывают записью единицы в соответствующий бит (RM0090, разд. 12.2.4). Наш вывод: если обработчик этого не сделал, запрос остаётся активным, и после выхода из обработчика прерывание наступает снова. У общих векторов EXTI9_5 и EXTI15_10 в обработчике сначала читают EXTI_PR, чтобы понять, какая линия сработала.

Чем событие EXTI отличается от прерывания?

Прерывание идёт в NVIC и вызывает обработчик, а флаг в EXTI_PR ставится. Событие — короткий импульс, который только будит ядро из режима WFE; флаг ожидания при этом не ставится, и сбрасывать ничего не нужно (RM0090, разд. 12.2.3). Включают их разными масками: EXTI_IMR для прерываний, EXTI_EMR для событий.

Источники

  1. STMicroelectronics. RM0090 Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439, Rev 21 — разд. 12.2.1 — у каждой линии свой фронт и маска, до 23 линий; 12.2.3 — пробуждение из WFE через линию в режиме события, флаг ожидания при этом не ставится; 12.2.4 — настройка RTSR/FTSR и IMR, запрос сбрасывается записью 1 в EXTI_PR, программный запрос через EXTI_SWIER; 12.2.5 — 16 линий для выводов, порт выбирают поля EXTIx[3:0] в SYSCFG_EXTICR1…4, линии 16–22: PVD, RTC Alarm, USB OTG FS Wakeup, Ethernet Wakeup, USB OTG HS Wakeup, RTC Tamper/TimeStamp, RTC Wakeup; 12.1.3, таблица векторов — отдельные EXTI0…EXTI4 и общие EXTI9_5, EXTI15_10; 6.3.14 — бит SYSCFGEN в RCC_APB2ENR
  2. STMicroelectronics. RM0008 Reference manual: STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx, Rev 21 — разд. 10.2 — до 20 детекторов фронтов у connectivity line и 19 у остальных; 10.2.5 — 16 линий для выводов, порт выбирают поля EXTIx[3:0] в AFIO_EXTICR1…4, до этого включают тактирование AFIO в RCC_APB2ENR; линии 16–19: PVD, RTC Alarm, USB Wakeup, Ethernet Wakeup (только connectivity line)

Нашли ошибку?