stm32-외부 인터럽트
※이 문서에는 오류가 있을 수 있습니다.
STM32F4은 23개의 외부 인터럽트 이벤트 소스(edge-detector 회로)를 가지고있다.
모든 GPIO 핀을 외부인터럽트로 사용할 수 있다.
(외부인터럽트핀이 지정되어 있는 CPU와 달리,
데이터 시트에는 외부인터럽트용 핀이 따로 표시되어 있지 않다. )
GPIO를 외부인터럽트로 사용할 수 있다. (모든 핀을 외부인터럽트로 사용할 수 는 없다)
인터럽트 핸들러함수는 EXTI0_IRQn,EXTI1_IRQn,EXTI2_IRQn,
EXTI3_IRQn,EXTI4_IRQn,EXTI9_5_IRQn,EXTI15_10_IRQn등이 있다.
EXTI_Line0~EXTI_Line22
edge-detector 회로의 개수(외부인터럽트의 최대 개수)
동시에 사용가능한 외부 인터럽트의 개수는 23개
(그러나, EXTI_PinSource 중복으로 사실상 16개(?))
부연설명:나머지 16~21번은 특정 용도로 지정되어 있다.
• EXTI line 16 is connected to the PVD output
• EXTI line 17 is connected to the RTC Alarm event
• EXTI line 18 is connected to the USB OTG FS Wakeup event
• EXTI line 19 is connected to the Ethernet Wakeup event
• EXTI line 20 is connected to the USB OTG HS (configured in FS) Wakeup event
• EXTI line 21 is connected to the RTC Tamper and TimeStamp events
• EXTI line 22 is connected to the RTC Wakeup event
• EXTI line 23 is connected to the LPTIM1 asynchronous event
EXTI_PinSource0~EXTI_PinSource15는 각 포트의 핀번호와 1:1대응된다.
(1포트는 16개)
EXTI_PinSource = interrupt line
예) PB2 <=> EXTI_PinSource2
따라서, 동일한 EXTI_PinSource*을 사용하는 포트는 동시에 사용이 불가능하다.
예) PB2, PC2를 동시에 사용불가
PB2, PC3은 동시에 사용가능
인터럽트 함수는 7개 있음
EXTI 다음 숫자는 line번호(GPIO 핀번호)
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
예) 8,9,10번을 사용하려면, EXTI9_5_IRQHandler,EXTI15_10_IRQHandler2개의함수를사용해야한다.
부연설명 : PA0번은 EXTI0_IRQHandler함수에서 처리해야한다.
PA3번은 EXTI3_IRQHandler함수에서 처리해야한다.
위 그림을 살펴보면, EXTI0은 A~K포트중 1개만 입력받을 수 있다.
void EXTI15_10_IRQHandler(void)
{
if(HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13);
//do somthing
}
}
위의 경우에는 PA5~PK5, ... PA10~PK10번핀들 중에 1개만 입력받을 수 있다.
"입력받은 핀이 PA5인지, PB5인지 어떻게 알 수 있지?"
=>PA5나 PB5나 둘중에 하나만 설정할 수 있다.
결론은 EXTI는 16개 사용가능하다.
IrqHandlerDescription
EXTI0_IRQn | EXTI0_IRQHandler | Handler for pins connected to line 0 |
EXTI1_IRQn | EXTI1_IRQHandler | Handler for pins connected to line 1 |
EXTI2_IRQn | EXTI2_IRQHandler | Handler for pins connected to line 2 |
EXTI3_IRQn | EXTI3_IRQHandler | Handler for pins connected to line 3 |
EXTI4_IRQn | EXTI4_IRQHandler | Handler for pins connected to line 4 |
EXTI9_5_IRQn | EXTI9_5_IRQHandler | Handler for pins connected to line 5 to 9 |
EXTI15_10_IRQn | EXTI15_10_IRQHandler | Handler for pins connected to line 10 to 15 |
인터럽트 함수 내부에서 EXTI_GetITStatus()함수를 사용하여,
어떤 인터럽트가 발생했는지 확인 가능.
(인터럽트 함수 1개는 여러개의 GPIO인터럽트 처리가 가능하다)
예)
#include "stm32f4xx.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_syscfg.h"
#include "misc.h"
//IAR, Keill 소스코드가 달라서 추가
#ifndef EXTI_GetITStatus
#define EXTI_GetITStatus __HAL_GPIO_EXTI_GET_IT
#endif
#ifndef EXTI_ClearITPendingBit
#define EXTI_ClearITPendingBit __HAL_GPIO_EXTI_CLEAR_IT
#endif
#ifndef EXTI_Line0
#define EXTI_Line0 GPIO_PIN_0
#define EXTI_Line1 GPIO_PIN_1
#define EXTI_Line2 GPIO_PIN_2
#define EXTI_Line3 GPIO_PIN_3
#define EXTI_Line4 GPIO_PIN_4
#define EXTI_Line5 GPIO_PIN_5
#define EXTI_Line6 GPIO_PIN_6
#define EXTI_Line7 GPIO_PIN_7
#define EXTI_Line8 GPIO_PIN_8
#define EXTI_Line9 GPIO_PIN_9
#define EXTI_Line10 GPIO_PIN_10
#define EXTI_Line11 GPIO_PIN_11
#define EXTI_Line12 GPIO_PIN_12
#define EXTI_Line13 GPIO_PIN_13
#define EXTI_Line14 GPIO_PIN_14
#define EXTI_Line15 GPIO_PIN_15
#endif
/* 참고
#define EXTI_Line0 ((uint32_t)0x00001)
#define EXTI_Line1 ((uint32_t)0x00002)
...
#define EXTI_Line14 ((uint32_t)0x04000)
#define EXTI_Line15 ((uint32_t)0x08000)
#define EXTI_Line16 ((uint32_t)0x10000)
#define EXTI_Line17 ((uint32_t)0x20000)
#define EXTI_Line18 ((uint32_t)0x40000)
#define EXTI_Line19 ((uint32_t)0x80000)
#define EXTI_Line20 ((uint32_t)0x00100000)
#define EXTI_Line21 ((uint32_t)0x00200000)
#define EXTI_Line22 ((uint32_t)0x00400000)
*/
/* Configure pins to be interrupts */
void Configure_PD0(void)
{
/* Set variables used */
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
/* Enable clock for GPIOD */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Enable clock for SYSCFG */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Set pin as input */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Tell system that you will use PD0 for EXTI_Line0 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);
/* PD0 is connected to EXTI_Line0 */
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
/* Enable interrupt */
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
/* Interrupt mode */
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Triggers on rising and falling edge */
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
/* Add to EXTI */
EXTI_Init(&EXTI_InitStruct);
/* Add IRQ vector to NVIC */
/* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
/* Set priority */
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
/* Set sub priority */
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
/* Enable interrupt */
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
/* Add to NVIC */
NVIC_Init(&NVIC_InitStruct);
}
/* Set interrupt handlers */
/* Handle PD0 interrupt */
void EXTI0_IRQHandler(void)
{
/* Make sure that interrupt flag is set */
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
/* Do your stuff when PD0 is changed */
/* Clear interrupt flag */
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
'C언어,ARM' 카테고리의 다른 글
TRACE 긴 문장 출력시 에러 (0) | 2020.02.15 |
---|---|
Warning: hDC is NULL in ... (0) | 2020.02.08 |
STM32 - GPIO togle (0) | 2020.01.31 |
GetTickCount, GetTickCount64 뭐가 다른가? (1) | 2020.01.19 |
error C2144: 구문 오류 : int'은(는) ';' 다음에 와야 합니다. (0) | 2020.01.18 |