十四、外部中断按键点灯
配置流程
一般使用 GPIO 的外部中断功能,都需要有以下几个步骤。
- 开启时钟
- 配置 GPIO 的模式
- 使能 NVIC 中断并配置优先级
- 配置 GPIO 中断
- 使能中断和清除中断标志位
- 编写中断服务函数
STM32 单片机的任意引脚都可以配置为外部中断触发,开发板的按键使用的是 KEY_UP,接到了单片机的 PA0 引脚上,因此我们可以使能 PA0 的外部中断功能。
开启时钟
开启 GPIO 时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
开启中断时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
配置 GPIO 模式
按键配置
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_Init(GPIOA, &GPIO_InitStructure);
2
3
4
5
6
7
8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- 这行代码设置了要配置的 GPIO 引脚为第 0 脚。
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
- 这里将 GPIO 引脚的模式设置为输入模式(
GPIO_Mode_IN
)。
- 这里将 GPIO 引脚的模式设置为输入模式(
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
- 这行代码为 GPIO 引脚配置了下拉电阻(
GPIO_PuPd_DOWN
)。这是在输入模式下常见的配置,用于确保在没有输入信号时,引脚处于已知的低电平状态。
- 这行代码为 GPIO 引脚配置了下拉电阻(
GPIO_Init 将相同的配置应用到 GPIOA 端口的第 0 脚。这意味着 GPIOA 第 0 脚都被配置为输入模式,且都启用了下拉电阻。
配置 GPIO 中断
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
关于每个中断线对应的功能,如图所示。
编写中断服务函数
使能中断之后,如果有中断触发,就会跳转到中断处理函数里面执行。需要编写中断处理函数。首先是中断函数名, 这个是固定的,在 startup_stm32f40xx.s 启动文件中有定义,如图所示。(部分截取)
图 1-4-1
在中断处理函数里需要检测中断标志位是否被置位。
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
这个函数是获取中断标志位。只有一个参数就是中断线。有一个返回值 FlagStatus,返回值的状态为 SET 和 RESET。需要注意的是每次中断执行完毕之后都需要清除一下中断标志位等待下一次中断发生。
中断服务函数编写代码如下:
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
// 处理中断
if( flag ) // LED
{
GPIO_SetBits(GPIOB, GPIO_Pin_2);
flag = 0;
}
else
{
GPIO_ResetBits(GPIOB, GPIO_Pin_2);
flag = 1;
}
printf("Key Press!!!\r\n");
// 清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
实验现象
这一章节的代码
在开发板介绍百度网盘链接中:立创·梁山派·天空星STM32F407VET6开发板资料/第03章软件资料/代码例程/007 外部中断按键点灯。
烧写我们的代码之后,按下一次按键松开,开启 LED,再按下一次按键松开,关闭 LED,以此类推。每次按下按键松开都会打印 Key!!。如图所示。