stm32 外部中断程序(标准库)
还不知道外部中断是什么的同学可以看看以下资料
STM32 外部中断详解(原理+配置代码)
深入讲解STM32中断
EXTI的初始化方法
1.在HARDWARE创建EXTI的头文件和源文件,用来写我们的中断配置程序
包含常用的头文件
2.创建EXTI的初始化函数,在函数中定义NVIC 和 EXTI 结构体
3.按键对应的IO口初始化
使能SYSCFG时钟,使用APB2总线复用功能
4.中断线以及中断初始化初始化配置
这段代码是用于配置外部中断线(EXTI)的。库函数SYSCFG_EXTILineConfig
来配置外部中断线。
EXTI_PortSourceGPIOC表示将外部中断线连接到GPIOC端口,
EXTI_PinSource13表示将外部中断线连接到GPIOC的第13引脚(PA13)
具体来说,这段代码将以下引脚连接到外部中断线:
- GPIOC的第11引脚(PA11)连接到中断线11。
- GPIOC的第12引脚(PA12)连接到中断线12。
- GPIOC的第13引脚(PA13)连接到中断线13。
- GPIOA的第0引脚(PA0)连接到中断线0。
这些引脚被配置为外部中断源,当对应的引脚上的电平发生变化时,会触发相应的中断事件
5.配置EXTI_Line0的结构体
这段代码是用于配置STM32的外部中断(EXTI)的初始化结构体。
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
:将外部中断线设置为LINE0。EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
:设置外部中断模式为中断事件模式。EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
:设置触发方式为上升沿触发。EXTI_InitStructure.EXTI_LineCmd = ENABLE;
:使能外部中断线。EXTI_Init(&EXTI_InitStructure);
:使用初始化结构体进行外部中断的配置。
这段代码的作用是配置STM32的外部中断,当GPIOC的第13引脚上的电平从低变高时,会触发一个中断事件。
同理继续配置EXTI_Line2,3,4
6.定义NVIC的结构体
这段代码是用于配置两个外部中断的初始化结构体(注意:只有EXTI0~4有独立的中断向量,5 ~ 9和 10 ~ 15共享中断向量EXTI9_5_IRQn和EXTI15_10_IRQn,),并使能这两个中断通道。具体解释如下:
-
第一个外部中断(EXTI0)的配置:
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
:设置中断通道为EXTI0。NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
:设置抢占优先级为0。NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
:设置响应优先级为3。NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
:使能外部中断通道。NVIC_Init(&NVIC_InitStructure);
:调用NVIC_Init函数进行配置。
-
第二个外部中断(EXTI15_10)的配置:
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
:设置中断通道为EXTI15_10。NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
:设置抢占优先级为0。NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
:设置响应优先级为2。NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
:使能外部中断通道。NVIC_Init(&NVIC_InitStructure);
:调用NVIC_Init函数进行配置。
EXTI初始化的完整代码
void EXTIX_Init(void)
{
//定义NVIC 和 EXTI 结构体
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
KEY_Init(); //按键对应的IO口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource11);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource12);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 连接到中断线0
/* 配置EXTI_Line0 */
EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0
EXTI_Init(&EXTI_InitStructure);//配置
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line11 | EXTI_Line12 | 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_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中断0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;//响应优先级为3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//外部中断2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置
}
编写中断服务函数
void EXTI0_IRQHandler(void) //中断服务程序
{
delay_ms(20); //消抖
if(KEY_UP==1)
{
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位
}
void EXTI0_IRQHandler(void): 这是中断服务程序的函数原型,表示该函数是用于处理外部中断0的中断事件,在函数中写上我们需要执行的程序即可。
EXTI_ClearITPendingBit(EXTI_Line0);: 这行代码调用了EXTI_ClearITPendingBit函数,用于清除外部中断0上的中断标志位。这样可以避免重复触发中断
在main的编写
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168);
LED_Init();
EXTIX_Init();
while(1);
}
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)用于设置系统中断优先级分组为2,两位抢占优先级,两位响应优先级
之后在调用我们项目相关功能的初始化函数即可,可见在使用外部中断时我们在主函数编写的代码是非常少的,相关功能实现的代码基本放在中断服务函数中
还有就是如果我们需要快速屏蔽一个中断源可以这么写
EXTI->IMR |= EXTI_Line14; //使能外部中断14
EXTI->IMR &= ~(EXTI_Line14); //屏蔽外部中断14
中断屏蔽寄存器EXTI->IMR