中断流程:
- 按键初始化
- 打开SYSCFG的时钟
- 配置中断线
- 中断屏蔽器打开
- 上升沿/下降沿二选一
- 配置优先级
- 中断服务函数
Key_Config();
RCC->AHB2ENR|=(1<<14);//SYSCFG时钟
按键初始化
打开SYSCFG的时钟
//配置中断线
SYSCFG->EXTICR[0]&=~(0xf<<0);//EXTI0
SYSCFG->EXTICR[0]|=(4<<8);//EXTI2
SYSCFG->EXTICR[0]|=(4<<12);//EXTI3
SYSCFG->EXTICR[1]|=(4<<0);//EXTI4
配置中断线:这几个中断线对应按键的PA0,PE2/3/4
//中断屏蔽器
EXTI->IMR|=(1<<0);
EXTI->IMR|=(1<<2);
EXTI->IMR|=(1<<3);
EXTI->IMR|=(1<<4);
中断屏蔽器打开
//边沿检测器 按键松手
EXTI->FTSR|=(1<<0);//下降沿
EXTI->RTSR|=(1<<2);//上升沿
EXTI->RTSR|=(1<<3);//上升沿
EXTI->RTSR|=(1<<4);//上升沿
上升沿/下降沿二选一
统一按键松手触发
PA0按键按下时电平由低变高,松手时由高变低;PE2/3/4按键按下时电平由低变高,松手时由高变低,所以PA0用下降沿,PE2/3/4用上升沿
NVIC_SetPriorityGrouping (7-5);//中断分组 第五组(使用频率较多)
//配置优先级
NVIC_SetPriority(EXTI0_IRQn,5);//优先级 占先=1 次级=1
NVIC_EnableIRQ(EXTI0_IRQn);//使能
NVIC_SetPriority(EXTI2_IRQn,6);//优先级 占先=1 次级=2
NVIC_EnableIRQ(EXTI2_IRQn);//使能
NVIC_SetPriority(EXTI3_IRQn,7);//优先级 占先=1 次级=3
NVIC_EnableIRQ(EXTI3_IRQn);//使能
NVIC_SetPriority(EXTI4_IRQn,8);//优先级 占先=2 次级=0
NVIC_EnableIRQ(EXTI4_IRQn);//使能
配置优先级
NVIC_SetPriorityGrouping (7-5);这句是放在主函数
第五组的 占先有4个 次组级4个
NVIC_SetPriority(EXTI0_IRQn,5);//优先级 占先=1 次级=1 5->01 01
NVIC_SetPriority(EXTI2_IRQn,6);//优先级 占先=1 次级=2 6->01 10
//中断服务函数(不用声明)
void EXTI0_IRQHandler (void)
{
if(EXTI->PR&(1<<0))//判断是否触发中断请求(标志位)
{
EXTI->PR|=(1<<0);//清楚标志位
LED1_TUN;
}
}
中断服务函数
完整代码
/*
Function name:Key_Exti_Config
Description:按键中断初始化
param:None
retval:None
Remarks:
PA0 PE2/3/4
*/
void Key_Exti_Config(void)
{
Key_Config();
RCC->AHB2ENR|=(1<<14);//SYSCFG时钟
//配置中断线
SYSCFG->EXTICR[0]&=~(0xf<<0);//EXTI0
SYSCFG->EXTICR[0]|=(4<<8);//EXTI2
SYSCFG->EXTICR[0]|=(4<<12);//EXTI3
SYSCFG->EXTICR[1]|=(4<<0);//EXTI4
//中断屏蔽器
EXTI->IMR|=(1<<0);
EXTI->IMR|=(1<<2);
EXTI->IMR|=(1<<3);
EXTI->IMR|=(1<<4);
//边沿检测器 按键松手
EXTI->FTSR|=(1<<0);//下降沿
EXTI->RTSR|=(1<<2);//上升沿
EXTI->RTSR|=(1<<3);//上升沿
EXTI->RTSR|=(1<<4);//上升沿
//配置优先级
NVIC_SetPriority(EXTI0_IRQn,5);//优先级 占先=1 次级=1
NVIC_EnableIRQ(EXTI0_IRQn);//使能
NVIC_SetPriority(EXTI2_IRQn,6);//优先级 占先=1 次级=2
NVIC_EnableIRQ(EXTI2_IRQn);//使能
NVIC_SetPriority(EXTI3_IRQn,7);//优先级 占先=1 次级=3
NVIC_EnableIRQ(EXTI3_IRQn);//使能
NVIC_SetPriority(EXTI4_IRQn,8);//优先级 占先=2 次级=0
NVIC_EnableIRQ(EXTI4_IRQn);//使能
}
//中断服务函数(不用声明)
void EXTI0_IRQHandler (void)
{
if(EXTI->PR&(1<<0))//判断是否触发中断请求(标志位)
{
EXTI->PR|=(1<<0);//清楚标志位
LED1_TUN;
}
}