外部中断EXTI和NVIC
2026/6/24 5:25:46 网站建设 项目流程

一、外部中断/事件控制器框图输入线是EXTI即外部中断源,外部中断源有20个中断(事件线) 即输入线上有20个事件线

0-15是GPIO的,16-19是一些特殊的外部中断

外部中断通用I/O映像

1.输入线(20条事件线选一条)

2.边沿检测电路(此时连接着上升沿触发选择寄存器和下降沿触发选择寄存器,选一个外部中断用于IO口高低电平变化,)(0和1分别表示低电平和高电平,而信号在低电平一段时间然后在一个时刻从0低电平突然到1高电平然后一段时间的高电平后在一时刻从高电平突然变到低电平,上升沿是低电平变成高电平的过程即上升沿就是信号从低电平(0)跳变到高电平(1)的那一瞬间,下降沿是高电平到低电平的的过程)

3.NVIC中断控制器(内核外设)

二、配置中断步骤

1.初始化用来中断的GPIO口

2.初始化EXTI(外部中断源)

3.配置NVIC(中断优先级)

4.编写中断服务函数

1.配置GPIO的结构体

2.初始化EXTI(外部中断源)

在exti.h文件里找到结构体EXTI_InitTypeDef;

结构体成员详解
1. EXTI_Line
EXTI中断/事件线选择,可选EXTI0 ~ EXTI19,定义在 stm32f10x_exti.h
2. EXTI_Mode
EXTI模式选择,二选一:产生中断模式 / 产生事件模式(一般选择中断)
3. EXTI_Trigger
边沿触发配置,可选:上升沿触发、下降沿触发、双边沿(上升+下降)触发


4. EXTI_LineCmd
EXTI线路开关控制:使能EXTI线 / 禁用EXTI线

3.在misc.c文件里misc.h找到NVIC中断优先级的结构体


结构体成员详解
1. NVIC_IRQChannel
指定要配置的中断通道,相关定义在 misc.h ,例如EXTI0、USART1、TIM2等各类外设中断。

不同的组别优先级不一样
2. NVIC_IRQChannelPreemptionPriority
抢占优先级:高抢占优先级中断可以打断当前正在执行的低抢占优先级中断,实现中断嵌套。数字越小的地位越高

3. NVIC_IRQChannelSubPriority
子优先级(响应优先级):抢占优先级相同时,子优先级数值越小,中断优先响应;无法实现中断嵌套。
4. NVIC_IRQChannelCmd
中断通道开关:取值 ENABLE 使能

4.编写中断服务函数

写好的中断服务函数

三、代码编写

基于之前的项目,首先创建exti文件夹,创建exti.c和exti.h文件,然后在c文件包含的头文件和固件库,然后函数定义(中断服务函数);在.h文件里面包含固件库和函数声明;在main.c文件里包含exti.h文件,在USER文件夹里面,exti.h在exti文件夹,没有和main.c文件所在的文件夹在一起,需要添加路径(魔术棒include paths找到exti.h所在文件夹即可)

void exti_init(void) { 1.初始化用来中断的GPIO口(用到的是震动传感器PA1,选择之前项目的shake_inie()函数体配置GPIO) GPIO_InitTypeDef shake_init;//初始化结构体 EXTI_InitTypeDef exti_init;//初始化结构体 NVIC_InitTypeDef nvic_init;//初始化结构体 //打开GPIOA时钟(DO选择链接到A1引脚) RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIO的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断的时钟 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSouurcel);//设置GPIOA1口设置成GPIO的外部中断源(外部中断线的配置) NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//把4个优先级bit切成两半——2bit给抢占优先级(0, 1, 2, 3),2 bit 给子优先级。 //配置结构体 shake_init.GPIO_Mode=GPIO_Mode_IPD; shake_init.GPIO_Pin=GPIO_Mode_Pin_1; shake_init.GPIO_Speed=GPIO_Speed_10MHz; //初始化函数 GPIO_Init(GPIOA, &shake_init); 2.初始化EXTI(外部中断源) exti_init.EXTI_Line=EXTI_Line1;//用到的是GPIOA1,所以选Line1 exti_init.EXTI_Mode=EXTI_Mode_Interrupt;//选择中断模式 exti_init.EXTI_Trigger=EXTI_Trigger_Falling;//震动传感器正常处于高电平,发生震动变成低电平,选择下降沿 exti_init.EXTI_LineCmd=ENABLE; EXTI_Init(&exti_init); 3.配置NVIC(中断优先级) //初始化函数 NVIC_Init(&nvic_init); nvic_init.NVIC_IRQChannel= EXTI1_IRQn ; //GPIOA1 → Pin_1 →EXTI_Line1→IRQ通道:EXTI1_IRQn→函数:EXTI1_IRQHandler引脚编号 = EXTI 线编号,一一对应。 nvic_init.NVIC_IRQChannelPreemptionPriority=1;对应图表示在0~3 里随便选 nvic_init.NVIC_IRQChannelSubPriority=1;//0~3 里随便选 nvic_init.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&nvic_init); 4.编写中断服务函数 }
在main.c添加中断函数 void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line1)!=RESET)//发生中断(RESET = 0)震动传感器产生高电平 { GPIO_ResetBits(GPIOA,GPIO_Pin_3);打开继电器开灯 delay(1000); GPIO_SetBits(GPIOA,GPIO_Pin_3);关闭继电器关灯 } EXTI_ClearFla(EXTI_Line1);// 发生中断后会有中断标志,中断服务函数最后一定要清标志,不然一退出又重新进中断,死循环 }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询