![](https://img-blog.csdnimg.cn/direct/0099a460b1834e27a3a3d0d75c34452d.png)
#include "key.h"
extern void printf(const char* fmt, ...);
void delay_ms(int ms) {
for (int i = 0; i < ms; i++)
for (int j = 0; j < 1000; j++);
}
int main() {
printf("EXTI test\r\n");
HAL_KEY1_RCC_GPIO_init();
HAL_KEY1_EXTI_init();
HAL_KEY1_GIC_init();
while (1);
return 0;
}
#include "key.h"
/**
* @brief RCC/GPIO章节初始化
*
*/
void HAL_KEY1_RCC_GPIO_init() {
// 1. 使能GPIOF组控制器
RCC->MP_AHB4ENSETR |= 0x1 << 5;
// 2. 设置PF7、PF8、PF9引脚为输入模式
GPIOF->MODER &= ~(0x3F << 14);
}
/**
* @brief EXTI章节初始化
*
*/
void HAL_KEY1_EXTI_init() {
// 1. 将EXTI9与PF9进行连接,PF8、PF7同理
EXTI->EXTICR3 &= ~(0xFF << 8);
EXTI->EXTICR3 |= 0x05 << 8;
EXTI->EXTICR2 &= ~(0xFF << 24);
EXTI->EXTICR2 |= 0x05 << 24;
EXTI->EXTICR3 &= ~(0xFF);
EXTI->EXTICR3 |= 0x05;
// 2. 设置为下降沿触发
EXTI->FTSR1 |= 0x7 << 7;
// 3. 设置不屏蔽PF9的EXTI中断
EXTI->C1IMR1 |= 0x7 << 7;
// // 4. 清除中断挂起标志位
// EXTI->FPR1 |= 0x7 << 7;
}
/**
* @brief GIC章节初始化
*
*/
void HAL_KEY1_GIC_init() {
/************** GICD初始化 **************/
// 1. 使GICD层组0使能
GICD->CTRL |= 0x1;
// 2. 使GICD层中断号使能
GICD->ISENABLER[3] |= 0x7 << 1;
// 3. 设置GICD层中断优先级,99(7级)、98(6级)、97(5级)
GICD->IPRIORITYR[24] |= 0x1 << 27;
GICD->IPRIORITYR[24] |= 0x1 << 19;
GICD->IPRIORITYR[24] |= 0x1 << 11;
// 4. 设置GICD层中断分配给CPU0
GICD->ITARGETSR[24] &= ~(0x3 << 24);
GICD->ITARGETSR[24] &= ~(0x3 << 16);
GICD->ITARGETSR[24] &= ~(0x3 << 8);
GICD->ITARGETSR[24] |= 0x1 << 24;
GICD->ITARGETSR[24] |= 0x1 << 16;
GICD->ITARGETSR[24] |= 0x1 << 8;
// // 5. 清除GICD层中断挂起标志位
// GICD->ICPENDR[3] |= 0x7 << 1;
/************** GICC初始化 **************/
// 1. 使GICC层组0使能
GICC->CTRL |= 0x1;
// 2. 设置GICC层中断优先级屏蔽(31级)
//(数值:GICC > GICD,表示GICD优先级高于屏蔽阈值)
GICC->PMR |= 0x1F << 3;
// // 3. 清除GICC层的获取的中断号
// GICC->EOIR |= (对应的中断号);
}
#include "key.h"
extern void printf(const char* fmt, ...);
extern void delay_ms(int ms);
unsigned int i = 0;
// 中断处理函数
void do_irq(void) {
// 消抖
delay_ms(50);
int interrupt_id = GICC->IAR & 0x3FF;
switch (interrupt_id) {
case 99:
printf("KEY1 down! ID = %d\r\n", interrupt_id);
break;
case 98:
printf("KEY3 down! ID = %d\r\n", interrupt_id);
break;
case 97:
printf("KEY2 down! ID = %d\r\n", interrupt_id);
break;
}
// 清除中断标志位和中断号
// 下面这行保证不会连续打印
EXTI->FPR1 |= 0x7 << 7;
// 下面这个可以不写
// GICD->ICPENDR[3] |= 0x7 << 1;
// 下面这行保证能多次触发中断
GICC->EOIR = interrupt_id;
}
![](https://i-blog.csdnimg.cn/direct/63e1a396f6954b139ebaaaab412ece89.png)