Продолжим разбираться с прерываниями, начало чему положено в заметке 4.1.
В кубе мы выбрали линии, по которым будут приходить события, для дальнейшей их обработки в прерывании. Так же мы определили эти события – изменение сигнала с 0 на 1. Как теперь это пойманное изменение сигнала, которое пришло по выбранной линии, обработать?
Как писалось в заметке 4.1, существует две возможности обработки:
-
External Event – обработка событий
Отличаются они между собой тем, что, в первом случае, вызывается обработчик прерывания, а во втором только устанавливается флаг. Нужно так же добавить, что каждое прерывание вызывается событием, но не каждое событие вызывает прерывание.
Разберем более подробней External Interrupt, так как в заметке 4.1, с помощью куба, мы уже сконфигурировали выводы на внешние прерывания.
При появлении события на линии, выполнение основной программы приостанавливается и запускается обработчик прерываний на этой линии.
Для stm32f10х, при работе с прерываниями от GPIO, имеются 7 обработчиков:
идивидуально обрабатываются линии с 0 по 4-ю, а линии с 5-й по 9-ю и с 10-й по 15-ю объеденены в два обработчика соответственно. Итого имеем:
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
Если микроконтроллер конфигурировали через куб, то эти обработчики создались автоматически. Находятся они в файле stm32f1xx_it.c.
Именно в этих обработчиках мы и прописываем то, что должно выполнится при появлении события на соответствующей линии.
Для того, что бы ни лазить по файлам в поиске обработчиков и что бы они всегда были под рукой, создадим и добавим в проект файл interrupt_gpio.h со следующим содержанием:
#ifndef INTERRUPT_GPIO_H_
#define INTERRUPT_GPIO_H_
void interrupt_PB0(){
}
void interrupt_PB1(){
}
#endif /* INTERRUPT_GPIO_H_ */
В файле stm32f1xx_it.c добавим наши созданные функции:
Таким образом, у нас получилась переадресация.
ОБРАТИТЕ ВНИМАНИЕ! В обработчиках я добавил еще по одной функции: HAL_NVIC_ClearPendingIRQ(EXTI0_IRQn);
Дело в том, что при наступлении события, перед вызовом обработчика, поднимается соответствующий флаг, который нужно очистить после обработки прерывания, что собственно и делает добавленная функция.
Теперь укажем, что будет происходить при наступлении нужного события.
Ранее, в заметке 3, нами был создан файл beg_ogon.h. Добавим его в проект и изменим interrupt_gpio.h, таким образом, что при нажатии кнопки на PB0 «огонь» будет бежать в одну сторону, а при нажатии кнопки на PB1 – в другую:
Ну и для того, что бы посмотреть наглядно как все это работает, в файл main.c добавим мигание светодиода на PA0.
Жмем «F7».