이전 포스팅이 궁금하다면?
이번 포스팅에서는 interrupt(인터럽트)에 대해 알아보도록 하겠다. interrupt를 사전에 검색해 보면 '방해하다'라는 뜻으로 나온다.
단어 그대로 CPU의 동작을 방해한다는 의미다. 좀 더 자세히 설명해 보면..
CPU(MCU안에 있는 core)가 동작하던 중 하드웨어에서 어떤 입력(본 포스팅에서는 스위치, interrupt의 형태는 다양하다. UART, ADC, SPI, I2C 등등.)이 들어오면 interrupt가 발생하게 된다. 그럼 CPU의 동작이 멈추고 interrupt service routine이 실행된다. 이걸 그림으로 설명하면
CPU에서 명령을 처리하다가 외부에서 interrupt가 발생하면 interrupt vector table로 이동한다. interrupt에도 처리에 우선순위가 있다. 만약 동시다발적으로 interrupt가 발생하면 여기서 정해진 우선순위에 맞춰 interrupt를 수행한다.
ISR(Interrupt Service Routine)에서는 그림과 같은 순서로 명령을 처리하고, 여기에 사용자가 추가한 코드가 수행된다.
더 자세한 내용은 위키백과를 참고하기 바란다 ^^
https://ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8
그럼 B-L475E-IOT01A1에서 interrupt를 활성화하고 처리하는 방법을 알아보자!
우선 사용하고자 하는 핀의 설정을 확인
PC13번이 GPIO_EXTI13번으로 설정되어 있다. 여기서 EXTI란? External Interrupt의 약자다. 즉 외부 인터럽트로 설정되어 있다는 뜻이다.
왼쪽 메뉴에 NVIC라는 메뉴에 들어가면 활성화된 interrupt table을 확인할 수 있다. 그중 EXTI Line[15:10] interrupts가 보일 것이다. Enabled 체크박스에 체크가 되어있는지 확인하자. 그 옆에 숫자는 interrupt 우선순위인데 현재는 하나의 interrupt만 사용하기 때문에 굳이 우선순위를 지정하지 않아도 된다.
여기까지 확인했으면 application.c로 이동해 코드를 작성해 보자!
생각보다 어렵지 않다. 외부에서 interrupt가 발생하면 callback 함수가 호출된다.
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 함수는 ST의 HAL 드라이버에 미리 작성되어 있다. 따라가다 보면 어떻게 등록되어 있는지 나오는데.. 이건 패스.
아무튼 저렇게 작성하고 임의의 변수를 하나 만들어서 동작을 확인해 보자.
디버깅 시작! line 번호 앞에 파란색 부분을 더블클릭하면 오른쪽 그림과 같이 break point가 잡힌다. 인터럽트가 발생하면 저 부분에서 동작이 멈춘다.
최초에 디버깅을 시작하고 Run을 누르면 저부분에서 한번 break가 걸릴 텐데 무시하고 다시 run을 누른다.(최초에 인터럽트를 활성화시키면서 한번 걸리는 것 같다.)
자 그럼 이제 스위치를 눌러보자.
이렇게 멈출 것이다. 음. 그럼 여러 개의 스위치가 달려있다면 어떻게 구분이 가능할까? 당연히 가능하다.
HAL_GPIO_EXTI_Callback 함수의 매개변수를 이용하면 된다.
interrupt가 발생해 callback 함수가 호출되면 매개변수는 interrupt 번호에 해당하는 위치의 bit 만 1로 되어있다. 현재 스위치가 연결된 PORT13 번은 GPIO_EXTI13번이기 때문에 14번째 bit만 1이 되어있을 거다. break가 걸려있는 상태에서 우측에 MCU상태, 변수 상태를 나타내 주는 창을 확인해 보자.
callback 함수의 매개변수인 GPIO_Pin의 값이 dec 값으로 8192인 것을 확인할 수 있고, 아래 창에 Bin값도 표시가 되어있다.
10 0000 0000 0000 이렇게 끊어서 확인하면 보기 쉽다. 14번째 bit가 1인 것을 확인할 수 있다. 그럼 이제 다시 코드를 작성해 보자.
위와 같이 작성하고 flag 변수에 break 걸고 디버깅을 해보면 아까와는 다르게 Run을 누르자마자 callback 함수에서 멈추지 않는 것을 확인할 수 있다.
if문에서 GPIO_Pin 값을 확인해 EXTI13 interrupt가 발생한 경우만 flag를 1로 만들고 있기 때문에.
- 끝 -
다음 포스팅이 궁금하다면?
'Hardware&Firmware > STmicroelectronic(STM)' 카테고리의 다른 글
[STM32] 9. B-L475E-IOT01A1 개발보드 드라이버 활용방법(B-L475E-IOT01A1 개발보드 활용하기) (0) | 2022.04.11 |
---|---|
[STM32] 8. UART(B-L475E-IOT01A1 개발보드 활용하기), HAL 드라이버, LL 드라이버 (0) | 2022.04.08 |
[STM32] 6. GPIO 제어하기-입력(B-L475E-IOT01A1 개발보드 활용하기) (17) | 2022.04.05 |
[STM32] 5. GPIO 제어하기-출력(B-L475E-IOT01A1 개발보드 활용하기) (0) | 2022.04.04 |
[STM32] 4. STM32CubeIDE 사용방법(B-L475E-IOT01A1 개발보드 활용하기) (0) | 2022.04.01 |