Микроконтроллер STM32 F1xx обеспечивает до 20 возможных источников EXTI (внешних прерываний); хотя во многих случаях различные источники имеют один вектор прерывания. Возможные источники и их соответствующее событие / вектор (для STM32 F100):
Event Source Vector
EXT0 PA0-PG0 EXT0_IRQHandler
EXT1 PA1-PG1 EXT1_IRQHandler
EXT2 PA2-PG2 EXT2_IRQHandler
EXT3 PA3-PG3 EXT3_IRQHandler
EXT4 PA4-PG4 EXT4_IRQHandler
EXT5 PA5-PG5 EXT9_5_IRQHandler
… … …
EXT15 PA15-PG15 EXT1_10_IRQHander
EXT16 PVD PVD_IRQHandler
EXT17 RTC Alarm RTC_WKUP
EXT18 USB Wakeup not on STM32 F100
EXT19 Ethernet Wakeup not on STM32 F100
Обратите внимание, что только один из PAx-PGx, где x равен 1-15, может быть настроен в качестве источника EXTI в любой момент. В случае, когда несколько источников EXTI совместно используют обработчик, ожидающие прерывания могут быть определены по чтению ожидающего регистра EXTI_PR. Кроме того, любой источник EXTI можно «запустить» с помощью программного обеспечения, установив соответствующий бит в «регистре событий программного прерывания» EXTI_SWIER.
Настройка внешнего прерывания состоит из нескольких этапов:
- Настройте NVIC для соответствующего вектора.
- Для выводов GPIO настройте соответствующий регистр AFIO_EXTICRx, чтобы выбрать правильный вывод (например, PA0).
- Установите условие триггера (падение / повышение или оба).
- Установите соответствующий бит в регистре маски события.
Все это может быть выполнено с использованием стандартных периферийных библиотечных модулей stm32f10x_nvic. и stm32f10x_exti. Например, чтобы настроить PA0 (подключенный к «пользовательской кнопке» на плате) для запуска прерывания по переднему фронту:
// Connect EXTI0 to PA0 GPIO_EXTILineConfig ( GPIO_PortSourceGPIOA , GPIO_PinSource0 ); // Configure EXTI0 line // see stm32f10x_exti .h EXTI_InitStructure . EXTI_Line = EXTI_Line0 ; EXTI_InitStructure . EXTI_Mode = EXTI_Mode_Interrupt ; EXTI_InitStructure . EXTI_Trigger = EXTI_Trigger_Rising ; EXTI_InitStructure . EXTI_LineCmd = ENABLE; EXTI_Init (& EXTI_InitStructure ); // Configure NVIC EXTI0_IRQn ...
Базовый обработчик должен проверить состояние прерывания и очистить все ожидающие биты;
void EXTI0_IRQHandler ( void ){ if ( EXTI_GetITStatus ( EXTI_Line0 ) != RESET){ ... EXTI_ClearITPendingBit ( EXTI_Line0 ); } }
Источники EXTI также можно настроить в «режиме события». В этом режиме они не генерируют прерывания, а генерируют внутреннее событие, которое можно использовать для выхода процессора из спящего режима. Например, инструкция WFE может использоваться программным обеспечением для входа в спящий режим, который может быть завершен событием на любой линии EXTI в режиме события.
Используя представленные фрагменты кода, можно написать простую программу, которая реагирует на события нарастающих фронтов (отпускание кнопок) на PA0, переключая led3. При написании кода вы, вероятно, заметите, что в зависимости от того, как вы отпустите кнопку, оно часто будет вести себя не так, как ожидалось.
Следующая цитата из справочного руководства является подсказкой для понимания того, что происходит:
Примечание. Внешние линии пробуждения запускаются по фронту, на этих линиях не должно быть сбоев. Если во время записи регистра EXTI_FTSR возникает спад на внешней линии прерывания, ожидающий бит не будет установлен.
Кнопки и переключатели печально известны своим «дребезгом» — при нажатии кнопки контакты не разделяются чисто, что приводит к многочисленным пикам. Это можно увидеть на осциллограмме ниже, которая иллюстрирует фактическое поведение, записанное на осциллографе — верхняя кривая показывает напряжение на PA0, когда кнопка нажата, и нижняя кривая, когда кнопка отпущена.
Решение состоит в том, чтобы добавить отключающую цепь, которая служит в качестве фильтра нижних частот для удаления быстро меняющихся сигналов (глюков). На рисунке показана простая схема отключения, состоящая из резистора и конденсатора. Поскольку к плате подключен понижающий резистор, подключенный к кнопке, предлагаемая схема является неоптимальной, но устраняет глюки, как показано на осциллограмме.