목차
1. 배경
2. 보드 구성 및 소스코드
3. 실습결과
1. 배경
EXTI는 외부 인터럽트라는 뜻입니다.
인터럽트는 CPU의 효율이 떨어지지 않고
특정 이벤트들을 처리할 수 있도록 도와줍니다.
또한, 다른 방식보다 처리 속도가 굉장히 빠르기 때문에
사용을 위해 알아둘 필요가 있습니다.
2. 보드 구성 및 소스코드
기본적으로, Board Select 선택 시 불필요한 기능이 포함되어
코드가 길어지고 보기 불편합니다.
따라서 MCU 방법으로 직접 세팅하겠습니다.
기본 상태에서 코딩이 필요한 부분만을 언급할 예정이며,
자세한 것은 첨부된 파일을 참고하시면 됩니다.
- 보드 세팅
- NVIC 세팅
NUCLEO-F429ZI 매뉴얼을 참고하여
몇 가지 실험할 포트만 활성화하였습니다.
또한, 인터럽트 사용을 위해 NVIC 설정을 해주었습니다.
- 인터럽트 신호 선택
PC13으로 연결된 USER 버튼으로 인터럽트를 일으키겠습니다.
HAL_GPIO_EXTI_IRQHandler 함수를 블록 씌우고 F3을 누르면,
다음과 같은 함수를 확인할 수 있고,
아래에 있는 HAL_GPIO_EXTI_Callback 함수는 weak 처리되어 있습니다.
이제 이 함수를 main.c로 가져와 커스텀합니다.
- EXTI_Callback
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13)
{
EXTI_flag = 1;
}
}
/* USER CODE END 4 */
위와 같이 버튼이 눌렸을 때 flag를 1로 주어 main 함수에서 활용할 수 있도록 합니다.
- Main
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
switch (currentState)
{
case STATE_SEG_DISPLAY:
if (EXTI_flag == 1)
{
currentState = STATE_EXTI_PROCESS;
EXTI_flag = 0;
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
// last_tick = HAL_GetTick();
}
else
{
// if (HAL_GetTick() - last_tick >= 1000)
// {
GPIOD->BSRR = seg[segment_index];
segment_index = (segment_index + 1) % 10;
HAL_Delay(1000);
// last_tick = HAL_GetTick();
// }
}
break;
case STATE_EXTI_PROCESS:
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
currentState = STATE_SEG_DISPLAY;
// last_tick = HAL_GetTick(); // 상태가 복귀될 때 시간 재설정
break;
}
/* USER CODE END WHILE */
대기상태로 기다리다가, EXTI_flag 신호가 들어오면 EXTI Process로 전이합니다.
PB0, PB7, PB14 (LED들)을 차례대로 키고 끈 뒤, 다시 작업으로 복귀합니다.
flag가 0인 경우에는, FND의 숫자가 계속 증가하도록 하는데,
아래와 같이 변수로 정의해 둔 것을 사용합니다.
자세한 7-segment 설명은 생략합니다.
tick의 경우는 인터럽트 이후 시간을 기다렸다가 갈 건지 등을 조절하기 위해 만들었습니다만,
굳이 사용하지 않겠습니다.
- PV
/* USER CODE BEGIN PV */
typedef enum {
STATE_SEG_DISPLAY,
STATE_EXTI_PROCESS
} StateType;
StateType currentState = STATE_SEG_DISPLAY;
volatile uint8_t EXTI_flag = 0;
volatile uint8_t segment_index = 0;
// volatile uint32_t last_tick = 0;
uint32_t seg[10] = {
0x003f00c0, // 0
0x000600f9, // 1
0x005b00a4, // 2
0x004f00b0, // 3
0x00660099, // 4
0x006d0092, // 5
0x007d0082, // 6
0x002700d8, // 7
0x007f0080, // 8
0x006f0090 // 9
};
/* USER CODE END PV */
3. 실습결과
시간에 따라 FND가 증가하다가,
버튼을 누르면 인터럽트에 의해 LED가 차례대로 켜지고,
다시 증가합니다.
'Embedded' 카테고리의 다른 글
ARM Cortex M4 core - (6) PWM을 활용한 주파수 변형 (악보연주) (0) | 2024.09.04 |
---|---|
ARM Cortex M4 core - (5) RTC 알람시계 (0) | 2024.09.04 |
ARM Cortex M4 core - (4) ADC를 활용한 스위치 Voltage확인 (0) | 2024.09.04 |
ARM Cortex M4 core - (3) UART 키보드로 LED제어 (0) | 2024.09.04 |
ARM Cortex M4 core - (1) GPIO로 LED 동작 (0) | 2024.09.04 |