EXTI는 External Interrupt의 약자로 인터럽트 Interrupt란 CPU(프로세스)가 프로그램을 실행하고 있을 때 입출력 하드웨어 등의 장치 등에서 예외상항이 발생하여 처리가 필요한 경우 프로세서에게 알려 처리할 수 있도록 하는 기능이다.
STM32F42시리즈는 다음과 같은 EXTI 구조를 가지고 있다.
각각의 PA0~PH0 핀이 EXTI0 에 연결되고 PA1~PH1이 EXTI1에 연결되는 식이다.
따라서 PD0번과 PC0번을 동시에 EXTI 용도로 설정할 수 없다.

EXTI0 - EXIT4 는 개별 NVIC 인터페이스를 가지고 EXTI5 - EXTI9번은 같은 그룹으로 묶이고 그리고 EXTI10 - EXTI15는 같은 그룹으로 묶여 NVIC에 연결된다.


콘덴서가 없을 경우 아래와 같이 노이즈가 발생

<Trigger siganls 이란>
인터럽트를 Rising Edge를 설정하였는데 인터럽트 신호가 LOW레벨에서 HIGH레벨로 변하는 순간을 감지하여 인터럽트를 발생시킵니다.
감지는 Rising, Falling, Rising and Falling으로 설정할 수 있습니다.

//EXTI Rising edge trigger detection
#define GPIO_MODE_IT_RISING (MODE_INPUT | EXTI_IT | TRIGGER_RISING)
//EXTI FALLING edge trigger detection
#define GPIO_MODE_IT_FALLING (MODE_INPUT | EXTI_IT | TRIGGER_FALLING)
//EXTI mode Rising/Falling edge trigger detection
#define GPIO_MODE_IT_RISING_FALLING (MODE_INPUT | EXTI_IT | TRIGGER_RISING | TRIGGER_FALLING)
//@brief This function handles EXTI line0 interrupt.
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
//@brief This function handles EXTI line3 interrupt.
void EXTI3_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_3)
{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
}
if(GPIO_Pin == GPIO_PIN_15)
{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);
}
if(GPIO_Pin == GPIO_PIN_4)
{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
}
if(GPIO_Pin == GPIO_PIN_10)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
}
}
전역변수 선언구간에 인터럽트가 발생하면 on/off해 줄 플래그 선언
/* USER CODE BEGIN PV */
GPIO_PinState flag_sw1 =0;
GPIO_PinState flag_sw2 =0;
GPIO_PinState flag_sw3 =0;
GPIO_PinState flag_sw4 =0;
/* USER CODE END PV */
GPIO_Pin 이 매개변수로 들어오면 핀 1,2,3,4가 같은 LED를 제어하기 때문에 충돌이 일어나지 않도록 다른플래그는 끄고 해당하는 플래그만 켜는 식으로 구성된다.
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_0){
flag_sw2 = 0;
flag_sw3 = 0;
flag_sw4 = 0;
flag_sw1 = 1;
}
else if(GPIO_Pin == GPIO_PIN_1){
flag_sw1 = 0;
flag_sw3 = 0;
flag_sw4 = 0;
flag_sw2 = 1;
}
else if(GPIO_Pin == GPIO_PIN_2){
flag_sw1 = 0;
flag_sw2 = 0;
flag_sw4 = 0;
flag_sw3 = 1;
}
else if(GPIO_Pin == GPIO_PIN_3){
flag_sw1 = 0;
flag_sw2 = 0;
flag_sw3 = 0;
flag_sw4 = 1;
}
}
/* USER CODE END 0 */
Led 점멸이동을 위한 변수 선언
/* USER CODE BEGIN 2 */
uint16_t ledLocation = 0x01;
/* USER CODE END 2 */
while문 내
/* USER CODE BEGIN WHILE */
while (1)
{
if(flag_sw1==1){
ledLocation <<= 1;
if(ledLocation > 0x80) ledLocation = 0x1;
HAL_GPIO_WritePin(GPIOD, ledLocation, 1);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOD, ledLocation, 0);
}
else if(flag_sw2==1){
ledLocation >>= 1;
if(ledLocation < 1) ledLocation = 0x80;
HAL_GPIO_WritePin(GPIOD, ledLocation, 1);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOD, ledLocation, 0);
}
else if(flag_sw3==1){
GPIOD->ODR = 0xff;
}
else if(flag_sw4==1){
GPIOD->ODR = 0x00;
}
}
Ref
https://louie0724.tistory.com/361
https://eteo.tistory.com/70
https://embedded-lab.com/blog/stm32-external-interrupt/
https://velog.io/@audgus47/EXIT-External-interrupt
https://www.youtube.com/watch?v=t9nuAqMAR6c&list=PLUaCOzp6U-RqMo-QEJQOkVOl1Us8BNgXk&index=9
https://workking.tistory.com/28