... #define SWITCH_GPIO GPIOA #define SWITCH_PIN 7 ... #define BUTTON_GPIO GPIOA #define BUTTON_PIN 0 ...
Le montage modifié.
Quelques petites choses à savoir avant d'envoyer le code:
1 #define BUTTON_EXTICR_IDX (BUTTON_PIN / 4)
2 #define BUTTON_EXTICR_VAL AFIO_EXTICR1_EXTI0_PA // 1 == 1 + (BUTTON_PIN / 4), 0 == BUTTON_PIN, A == BUTTON GPIO
3 #define BUTTON_EXTI_PR EXTI_PR_PR0 // 0 == BUTTON_PIN
4 #define BUTTON_FTSR EXTI_FTSR_TR0 // F == Falling, 0 == BUTTON_PIN
5 #define BUTTON_HANDLER EXTI0_IRQHandler // cf STM32-base-master/startup/STM32F1xx/STM32F103xB.s
6 #define BUTTON_IMR EXTI_IMR_MR0 // 0 == BUTTON_PIN
7 #define BUTTON_IRQn EXTI0_IRQn // 0 == BUTTON_PIN
8
9 #define APB2_EN RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN // GPIOA + AFIO
...
enum STATES { INIT = 0, RED, ORANGE, GREEN, EMERGENCY };
...
gpio_pin_init(BUTTON_GPIO, BUTTON_PIN, I_PU_PD);
...
__disable_irq();
AFIO->EXTICR[BUTTON_EXTICR_IDX] = BUTTON_EXTICR_VAL;
EXTI->IMR |= BUTTON_IMR;
EXTI->FTSR |= BUTTON_FTSR;
NVIC_EnableIRQ(BUTTON_IRQn);
__enable_irq();
...
else if (state == EMERGENCY) {
SWITCH_GPIO->ODR ^= 1 << SWITCH_PIN; // toogle state
}
...
void
BUTTON_HANDLER(void) {
EXTI->PR |= BUTTON_EXTI_PR; // Reset irq
if (state == EMERGENCY) {
state = RED;
SWITCH_GPIO->BSRR = 1 << SWITCH_PIN; // PIN high SWITCH on
ORANGE_GPIO->BSRR = 1 << ORANGE_PIN; // PIN high ORANGE off
RED_GPIO->BRR = 1 << RED_PIN; // PIN low RED on
}
else {
if (state == RED) {
RED_GPIO->BSRR = 1 << RED_PIN; // PIN high RED off
}
else if (state == GREEN) {
GREEN_GPIO->BSRR = 1 << GREEN_PIN; // PIN high GREEN off
}
state = EMERGENCY;
ORANGE_GPIO->BRR = 1 << ORANGE_PIN; // PIN low ORANGE on
}
systick_irqs = 0;
}
Même si ici cela ne s'impose pas, la mise en place de l'interruption est encadrée par les fonctions __disable_irq et __enable_irq afin qu'une éventuelle autre interruption ne vienne pas interrompre le code.
Le code complet: https://gitlab.com/dsx/blue-pill/-/tree/master/stm32f103c8t6/00_gpios_ext_irq