配置EXIT外部中断其实就是把GPIO刀NVIC的各个外设配置好
第一步:配置RCC,把我们涉及到的外设的时钟都打开
(此处EXTI是默认打开的,而NVIC是内核外设无需配置)
第二步:配置GPIO,选择端口为输入模式
第三步:配置AFIO,一共有16个引脚可以选择,每个引脚只能配一个GPIO端口
第四步:配置EXTI,选择边沿触发方式,比如上升沿,下降沿,双边沿,
选择触发响应方式(中断响应,事件响应)
中断响应:CPU处理
事件响应:对应某个外设处理,CPU正常工作
第五步:配置NVIC,给中断设置响应优先级和抢占优先级
响应优先级:当中断队列中有多个请求时,响应优先级高的(数字越小越高)将会优先执行
抢占优先级:当已有中断在运行时,此时再来一中断请求若其抢占优先级比正在运行的中断事件的抢占优先级高的话会在原中断事件上再嵌套一个中断事件
原理图:
模板代码:
uint16_t Key_Count = 0;//中断计数位
void KeyIt_Init(void)//按键中断初始化函数
{
GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO初始化传参结构体
EXTI_InitTypeDef EXTI_InitStructure;//定义EXTI初始化传参结构体
NVIC_InitTypeDef NVIC_InitStructure;//定义NVIC初始化传参结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//打开AFIO时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//设置为上拉输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//选择1号引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置IO口速度为50MHz
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIO,传入结构体参数
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
//在AFIO里将1号引脚的中断线路分配给GPIOA端口
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
//选择外部中断线路为1号线路(1号引脚对应的线路)
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能对应外部中断线路
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//设置为中断模式(有中断模式和事件模式)
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//设置为低电平触发中断
EXTI_Init(&EXTI_InitStructure);//初始化EXTI,传入结构体参数
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//将优先级设置为分组2的配置,即抢占优先级为2位(0~3),响应优先级为2位(0~3),数字越小优
先级越高
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;//选择为EXTI1通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能对应通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//设置抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//设置响应优先级为1
NVIC_Init(&NVIC_InitStructure);//初始化NVIC,传入结构体参数
}
uint16_t Key_Count_Get(void)//返回中断计数位函数
{
return Key_Count;//返回中断计数位
}
void EXTI1_IRQHandler(void)//每个中断的中断处理函数都是固定的,在启动文件里找
{
if (EXTI_GetITStatus(EXTI_Line1) == SET//如果该中断线路状态寄存器值为SET)
{
Key_Count++;//中断计数位自增
EXTI_ClearITPendingBit(EXTI_Line1);//清除中断标志位
}
}