Note/임베디드 노트
외부인터럽트 정리 및 실습 코드
유니_
2020. 11. 27. 12:20
인터럽트 사용을 위해 설정해주어야 할 것은 크게 3가지 이다.
1. GPIO Configuration : 인터럽트 인풋으로 사용할 GPIO 설정 (GPIO)
2. EXTI_Configuration : 외부 인터럽트 라인 설정 (EXTI)
3. NVIC_Configuration : 인터럽트 우선순위 및 채널 설정 (NVIC)
Step :
1. 인풋으로 사용할 핀의 GPIO를 설정한다.
+) 여기선 Port B의 핀9번을 GPIO 인풋으로 사용하고, LED테스트를 위해 핀0~7은 아웃풋으로 사용한다.
2. 외부인터럽트를 설정한다.
1) 인터럽트를 인풋에 필요한 AFIO에 클럭을 공급한다.
2) 인풋으로 설정한 GPIO B9를 인터럽트로 설정한다.
3) 인터럽트 모드를 설정한다.
4) 트리거를 폴링 엣지로 설정한다.
5) 인터럽트 라인을 9번으로 설정한다. (핀넘버가 9번이기 때문이다.)
6) 해당 인터럽트 라인의 펜딩비트를 클리어하고 레지스터 설정을 한다.
3. 인터럽트 우선순위 및 채널 설정을 한다.
1) IRQ채널을 EXTI9_5로 설정한다.
2) 최우선순위 를 설정한다.
3) 두번째 우선순위를 설정한다.
4) IRQ채널을 Enable 시킨다.
4. EXTI9_5 채널의 핸들러 함 수를 작성한다.
1) ETXI_Line9 의 인터럽트를 사용하고 싶기 때문에 내부적으로 EXTI_Line9의 상태를 읽어와 분기한다.
5. 메인문 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include "stm32f10x.h"
#include "utils.h"
volatile uint8_t EXTI9_5_Flag =0;
void EXTI9_5_IRQHandler() //인터럽트 서브루틴
{
if(EXTI_GetITStatus(EXTI_Line9) !=RESET)
{
EXTI9_5_Flag = !EXTI9_5_Flag;
EXTI_ClearITPendingBit(EXTI_Line9);
}
}
void NVIC_Configuration()
{
NVIC_InitTypeDef NVIC_InitStructure; //NVIC_InitStructure라는 이름의 구조체 생성
// Enable the TIM2 Channel 2 Interrupt
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn ; //EXTI9_5로 채널 설정
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //최우선순위 설정
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //두번째 우선순위 설정
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ채널을 사용할지 설정
NVIC_Init(&NVIC_InitStructure); //해당 레지스터에 값 저장
}
void GPIO_Configuration()
{
GPIO_InitTypeDef GPIO_InitStructure; //GPIO_InitStructure라는 이름의 구조체 생성
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //포트B에 클럭신호를 제공
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //핀9로 구성
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //해당 핀을 풀업 인풋으로 설정
GPIO_Init(GPIOB, &GPIO_InitStructure); //해당 레지스터에 값 저장
GPIO_InitStructure.GPIO_Pin = 0x000f; //핀0 ~ 7로 구성
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //해당 핀을 PP아웃으로 설절
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO속도를 50MHz로 설정
GPIO_Init(GPIOB, &GPIO_InitStructure); //해당 레지스터에 값 저장
}
void EXTI_Configuration()
{
EXTI_InitTypeDef EXTI_InitStructure; //EXTI_InitStructure라는 구조체 생성
// Enable SYSCFG's APB interface clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //인터럽트레지스터에 클럭신호 제공
// Connect EXTI Line12 to PB12 pin
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9); //포트B의 9번 핀을 인터럽트로 사용
// Configure EXTI line12
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //인트럽트 모드로 설정
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //폴링 엣지로 설정
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //인터럽트를 사용함으로 설정
EXTI_InitStructure.EXTI_Line = EXTI_Line9; //인터럽트 라인을 EXTI_LIN9로 설정
EXTI_ClearITPendingBit(EXTI_Line9); //펜딩비트 클리어
EXTI_Init(&EXTI_InitStructure); //해당 레지스터에 값 저장
}
int main()
{
NVIC_Configuration();
GPIO_Configuration();
EXTI_Configuration();
while(1)
{
if(EXTI9_5_Flag == 0)
{
GPIO_WriteBit(GPIOB,0x000f, 1);
}
else
{
GPIO_WriteBit(GPIOB,0x000f, 0);
Delay_ms(200);
GPIO_WriteBit(GPIOB,0x000f, 1);
Delay_ms(200);
}
}
}
|
cs |