十四、外部中断按键点灯
1. 配置流程
一般使用GPIO的外部中断功能,都需要有以下几个步骤。
- 开启时钟
- 配置GPIO的模式
- 使能NVIC中断并配置优先级
- 配置GPIO中断
- 使能中断和清除中断标志位
- 编写中断服务函数
CW32单片机的任意引脚都可以配置为外部中断触发,我们开发板只有一个按键它是复位按键我们不能使用,所以我们直接外接一个按键,接到了单片机的PA0引脚上,因此我们可以使能PA0的外部中断功能。
1.1 开启时钟
开启GPIO时钟
C
__RCC_GPIOA_CLK_ENABLE(); // 使能GPIO时钟
1
1.2 配置GPIO模式
C
GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体
GPIO_InitStruct.Pins = GPIO_PIN_0; // GPIO引脚
GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLDOWN; // 下拉输入
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 速度高
GPIO_InitStruct.IT = GPIO_IT_RISING; // 上升沿触发中断
GPIO_Init(CW_GPIOA, &GPIO_InitStruct); // 初始化
1
2
3
4
5
6
7
2
3
4
5
6
7
1.3 配置GPIO中断
C
// 清除PA0中断标志
GPIOA_INTFLAG_CLR(bv0);
// 使能NVIC
NVIC_EnableIRQ(GPIOA_IRQn);
1
2
3
4
2
3
4
1.4 编写中断服务函数
使能中断之后,如果有中断触发,就会跳转到中断处理函数里面执行。需要编写中断处理函数。首先是中断函数名, 这个是固定的,在startup_cw32f030.s启动文件中有定义,如图所示。(部分截取)
由于整个中断服务函数会响应所有GPIOA的中断请求,我们需要判断本次触发的中断是否由PA0触发,根据手册描述,ISR寄存器指示了IO的中断请求状态,这里用按位与操作实现判断。在完成对中断请求的响应之后,需要手动清除中断标志位,根据手册描述,将ICR寄存器对应的位清零就可以清除中断标志(如果不清除中断标志,单片机会在此次中断执行完之后立刻再次进入中断)。
关于ISR和ICR寄存器的描述如图所示。
中断服务函数编写代码如下:C
void GPIOA_IRQHandler(void)
{
if(CW_GPIOA->ISR_f.PIN0) // 判断是否是PA0中断
{
GPIOA_INTFLAG_CLR(bv0); // 清除标志位
LED_FLAG = 1; // 标志位置1
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
GPIOA_INTFLAG_CLR() 是原厂封好的一个宏,原型是:
而这个bv0是原厂给的位运算宏,我们就不需要再使用 GPIOA_INTFLAG_CLR((((uint32_t)1u) << 0));这样的形式去操作了,直接使用bv0就好了。2. 实验现象
关于这一章节的代码,在立创·地文星CW32F030C8T6开发板资料/第03章软件资料/代码例程/006外部中断按键中断。
烧写我们的代码之后,按下一次按键会打印KEY_IRQHandler。如图所示。