STM32教程:外部中断(EXTI)的初始化详解
文章目录
1、中断
1.2 中断系统
1.3 中断执行流程
在主程序中,当他执行到某个地方时,这时无论主程序在干什么事情,只要满足了外设的中断条件,主程序都立即暂停,程序由硬件电路自动跳转到中断程序中。当中断程序执行完后,程序在返回被暂停的地方继续运行。
右边就是中断嵌套的执行流程,当其中一个中断正在执行时,又有新的优先级更高的中断来,那么就会再次打断中断,然后执行新的中断;新的中断结束,再继续原来的中断,原来的中断结束,再继续主程序,这就是中断嵌套。
带有中断的C语言程序如下:
2、STM32中断
2.2EXTI(外部中断)
EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序。
2.3 EXTI 的基本结构
外部中断的整体结构图如下所示:
最左边是GPIO口的外设,比如GPIOA、GPIOB、GPIOC等等,每个GPIO外设有16个引脚,所以进来16根线。
EXTI模块只有16个GPIO的通道,但每个GPIO外设都有16个引脚,如果每个引脚都占用一个通道,那么EXTI的通道就不够用了,因此在这里就会有一个AFIO中断引脚选择的电路模块。
这个AFIO就是一个数据选择器,他可以在前面的3个GPIO外设的16个引脚中选择其中一个连接到后面EXTI的通道里,所以印证了前面我们所说的相同的Pin不能同时出发中断。
然后通过AFIO选择之后的16个通道,就接到了EXTI边沿检测及控制电路上,同时下面还接入了4个外设;这些加起来就组成了EXTI的20个输入信号。
然后经过EXTI电路之后,分为了两种输出。上面部分接NVIC,用来触发中断;下面部分有20条输出线路接到了其他外设,用来触发其他外设中断,也就是事件响应。
2.4 AFIO复用IO口
3、NVIC基本结构
在STM32系统中,NVIC是用来统一分配中断优先级和管理中断的。NVIC是一个内核外设,是CPU的助手;他有很多输入口,中断线路都可以接过去;线上画了斜杠,上面写了n,意思是一个外设可能同时占用多个通道,因此这里有n条线。
NVIC只有一个出口,NVIC根据每个中断的优先级分配中断的先后顺序,之后通过右边的输出口告诉CPU应该处理哪个中断。
3.2 NVIC优先级分组
为了处理不同形式的优先级,STM32的NVIC可以对优先级进行分组,分为抢占优先级和响应优先级。
4、配置EXTI
4.2 AFIO 库函数
对于AFIO,ST公司并没有给他分配专门的库函数文件,他的库函数与GPIO在一个文件内。其中红色部分就是与AFIO有关的库函数。
1.GPIO_AFIODeInit,这个函数是用来复位AFIO外设的,调用一下这个函数,AFIO的配置就会全部清零。
2.GPIO_PinLockConfig,用来锁定GPIO配置,调用这个函数,参数指定某个引脚,那这个引脚就会被锁定,防止意外更改。
3.GPIO_EventOutputConfig,这个函数用来配置AFIO的事件输出功能的。
4.GPIO_EventOutputCmd,也是用来配置AFIO的事件输出功能。
5.GPIO_PinRemapConfig,用来进行引脚重映射,第一个参数选择要重映射的方式,第二个参数是新的状态。
6.GPIO_EXTILineConfig,调用这个函数,就可以配置AFIO的数据选择器,来选择想要的中断引脚。
7.GPIO_ETH_MediaInterfaceConfig,和以太网有关的函数。
4.3 EXTI 库函数
1.EXTI_DeInit,调用他,可以把EXTI的配置都清除,恢复成上电默认状态。
2.EXTI_Init,根据结构体里面的参数配置EXTI外设,初始化EXTI。
3.EXTI_StructInit,可以把参数的结构体变量赋一个默认值。
4.EXTI_GenerateSWInterrupt,软件出发外部中断,调用这个函数,参数给一个指定的中断线,就能软件出发一次外部中断。
5.FlagStatus EXTI_GetFlagStatus,可以获取指定的标志位是否被置1。
6.EXTI_ClearFlag,可以对置1的标志位进行清除。
7.ITStatus EXTI_GetITStatus,获取中断标志位是否被置1。
8.EXTI_ClearITPendingBit,清除中断挂起标志位。
其中第5、6个函数和第7、8个函数的区别是:第5、6个函数是用在主程序中查看和清除标志位的;而第7、8个函数是在中断函数里查看和清除标志位的。
4.4 NVIC 库函数
1.NVIC_PriorityGroupConfig,用来中断分组,参数是中断分组的方式。
2.NVIC_Init,根据结构体里面指定的参数初始化NVIC。
3.NVIC_SetVectorTable,设置中断向量表。
4.NVIC_SystemLPConfig,系统低功耗配置。
4.5 配置EXTI的步骤
上面是外部中断的整体结构图,我们把图中的每个模块都打通,就能实现中断了,分为如下5个步骤:
1、配置RCC,把要涉及的外设的时钟都打开(不打开时钟,外设是无法工作的);
2、配置GPIO,选择我们的端口为输入模式;
3、配置AFIO,选择我们的这一路GPIO,连接到后面的EXIT;
4、配置EXIT,选择边沿触发方式,比如上升沿,下降沿或者双边沿,以及选择触发响应方式,可以选择中断响应和事件响应(一般是中断响应);
5、配置NVIC,给我们这个中断选择一个合适的优先级。
6、通过NVIC,外部中断信号就能进入CPU了,这样CPU才能收到中断信号,才能跳转到中断函数里执行中断程序。
需要注意的是:注意,NVIC不需要手动开启时钟,因为NVIC属于内核中的外设,内核中的外设是不需要手动开启时钟的。
4.6 初始化EXTI
例如我们需要对一个对射式红外传感器进行计次,先将传感器的功能封装在一个模块里,对这个传感器的初始化配置如下:
#include "stm32f10x.h" // Device header
void CountSensor_Init(void)
{
//1.配置RCC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO的时钟
//RCC管的是内核外的外设
//AFIO也是APB2外设总线上的
//EXTI和NVIC两个外设时钟是一直都打开的,不需要我们再开启时钟
//NVIC是内核的外设,内核的外设不需要开启时钟
//2.配置GPIO
GPIO_InitTypeDef GPIO_Initstructure;
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_IPD;//选择模式
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_14;//选择引脚
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_Initstructure);//调用函数,初始化GPIOB外设
//3.配置AFIO
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14); //配置AFIO外部中断引脚
//当执行完这个函数后,AFIO的第14个引脚数据选择器就拨好了
//输入端被拨到了GPIO外设上,对应的就是PB14号引脚;输出端固定连接的是EXTI的第14个中断线路。
//这样PB14号引脚的电平信号就可以顺利通过AFIO,进入后面的EXTI电路了
//4.配置EXTI
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line14;//指定要配置的中断线
EXTI_InitStructure.EXTI_LineCmd=ENABLE;//指定选择的中断线的新状态
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//指定外部中断线模式
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//指定触发信号的有效边沿方式
EXTI_Init(&EXTI_InitStructure);
//5.配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置优先级分组:先占优先级和从占优先级
//6.调用NVIC_Init函数
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;//指定中断通道来开启或关闭
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//指定抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//指定响应优先级
NVIC_Init(&NVIC_InitStructure);
}
外部中断的信号从GPIO到AFIO,再到EXTI,再到NVIC,最终通向CPU,这样才能让CPU由主程序跳转到中断程序执行。
作者:木木bit~