Как обычно определим векторы обработчиков прерываний:
0, /*!%5 RCC */
exti0_irq_handler, /*!%6 EXTI Line0 */
0, /*!%7 EXTI Line1 */
0, /*!%29 TIM3 */
tim4_irq_hanlder, /*!%30 TIM4 */
0, /*!%31 I2C1 Event */
Теперь приступим к самим обработчикам.
Обработчик exti0 мы возмем из Мигание светодиодов со сменой режима от внешнего прерывания немного доработов его:
/* exti0 irq handler */
void exti0_irq_handler(void) {
if (EXTI->PR | EXTI_PR_PR0) {
/* change leds */
LED_PORT->ODR ^= GREEN_LED | RED_LED;
/* clear pending irq */
EXTI->PR |= EXTI_PR_PR0;
}
/* disable exti0 interrupt */
EXTI->IMR &= ~EXTI_IMR_MR0;
}
Также добавим обработчик для таймера №4:
/* timer4 irq handler */
void tim4_irq_hanlder(void) {
if (TIM4->SR & TIM_SR_UIF) {
/* switch leds */
LED_PORT->ODR ^= ALL_LEDS;
/* clear status bit */
TIM4->SR &= ~TIM_SR_UIF;
/* enable exti0 interrupt */
EXTI->IMR |= EXTI_IMR_MR0;
}
}
В это обработчике мы меняем состояние все светодиодо, а заодно активируем прерывание exti0 которое мы деактивировали в обработчике exti0(борьба с дребезгом контактов).