参考视频:正点原子
以下相关介绍以实际应用为主!!!!!
1.外部中断的个人理解
STM32F4每个IO口都可以作为外部中断输入。但是只有16个中断线EXTI0~15【但是不代表可以用16个中断】
只能用7个中断服务函数:
对于什么IO口用什么外部中断线如下:
2.外部中断的配置流程
第一步:开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
第二步:IO口初始化【调用你的IO口初始化函数就行】
KEY_Init();
第三步:设置IO与中断线的映射,将PC13连接到EXIT13上【标红的根据IO口的不同自行更改】
记得把这个.c文件放进去
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);
第四步:配置EXTI结构体
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line13; //中断线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能
EXTI_Init(&EXTI_InitStructure);
第五步:NVIC的配置【中断通道在stm32f4xx.h文件里面找】
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
第六步:中断服务函数的编写【中断服务函数名字在startup_stm32f401xx.s文件里面找】
中断服务函数名
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler //中断线5-9共用
EXTI15_10_IRQHandler //中断线10-15共用
终端里面常用的库函数
EXTI_GetITStatus(uint32_t EXTI_Line); // 判断某个中断是否发生
EXTI_ClearITPendingBit(uint32_t EXTI_Line); // 清除中断标志位
中断服务函数框架
void EXTIX_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_LineX))
{
中断逻辑
//清除事件标志,表示本次中断已被处理
EXTI_ClearITPendingBit (EXTI_LineX);
}
}
3.代码
初始化代码
/*******************************************************************
* Function : 按键13的外部中断的配置
* Parameter : void
* Return : void
* Comment :
KEY1 -- PA0 (按下高电平,松开低电平)---门铃
KEY2 -- PC13(按下低电平,松开高电平)
********************************************************************/
void EXIT13_Init(void)
{
/*第一步:使能外部中断的时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_EXTIT, ENABLE);
/*第二步:GPIO初始化*/
KEY_Init();
/*第三步:设置IO与中断线的映射,将PC13连接到EXIT13上*/
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line13;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/*第四步:NVIC的配置*/
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
}
中断服务函数代码
/*******************************************************************
* Function : 按键2的外部中断函数
* Parameter : void
* Return : void
* Comment :
KEY1 -- PA0 (按下高电平,松开低电平)---门铃
KEY2 -- PC13(按下低电平,松开高电平)
作用:按键2按下,进入外部中断,松开按键2,LED3翻转---》模拟开关灯
********************************************************************/
void EXTI15_10_IRQHandler(void)
{
//判断是因为EXTI13触发进入中断
if(EXTI_GetITStatus(EXTI_Line13))
{
//中断处理
SysTick_Ms(50); //消抖
if(KEY2_Press)
{
while(KEY2_Press); //等待按键2松开
LED3_FZ;
}
//清除事件标志,表示本次中断已被处理
EXTI_ClearITPendingBit (EXTI_Line13);
}
}