赞
踩
还不知道外部中断是什么的同学可以看看以下资料
STM32 外部中断详解(原理+配置代码)
深入讲解STM32中断
1.在HARDWARE创建EXTI的头文件和源文件,用来写我们的中断配置程序
包含常用的头文件
2.创建EXTI的初始化函数,在函数中定义NVIC 和 EXTI 结构体
3.按键对应的IO口初始化
使能SYSCFG时钟,使用APB2总线复用功能
4.中断线以及中断初始化初始化配置
这段代码是用于配置外部中断线(EXTI)的。库函数SYSCFG_EXTILineConfig
来配置外部中断线。
EXTI_PortSourceGPIOC表示将外部中断线连接到GPIOC端口,
EXTI_PinSource13表示将外部中断线连接到GPIOC的第13引脚(PA13)
具体来说,这段代码将以下引脚连接到外部中断线:
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上的中断标志位。这样可以避免重复触发中断
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。