2.外部中断EXTI和外部中断按键控制led灯

2.1认识外部中断

概念:在主程序运行过程中,出现了特定的中断触发条件,使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完后又返回原来被暂停的位置继续运行

对于互联型产品,外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,对于其它

产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲

或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏

蔽。挂起寄存器保持着状态线的中断请求。

主要特性:

            每个中断/事件都有独立的触发和屏蔽

            每个中断线都有专用的状态位

            支持多达20个软件的中断/事件请求

            检测脉冲宽度低于APB2时钟宽度的外部信号。参见数据手册中电气特性部分的相关参数。

STM32外部中断架构

·有20条外部中断线
·有16条是GPIO的中断线(0-15),同一个引脚号对应同一个line
·第十九条line只在有ETH互联设备上才存在
·GPIO的中断线要启用必须先配置AFIO的寄存器EXTICRx

2.STM32外部中断机制框架

1.边沿检测:上升沿、下降沿或双边沿

2.软件配置中断或事件寄存器

3.屏蔽中断寄存器或事件寄存器

4.请求挂起寄存器

5.中断发送给NVIC中断控制器

6.事件则产生一个脉冲响应

2.2复用功能

概念:处理器的引脚本身默认就是一个普通的GPIO,但是他可以被复用成其他功能,称之为一个引脚的复用功能(比如上面的STM32外部中断架构)

2.3重映射

概念:重映射属于复用功能的另外一个功能,可以把具有特殊功能的引脚,分配到其他引脚上去,如果某个功能被重映射了,那么这个功能将不再遵循其默认的分配

2.4中断嵌套控制器NVIC

Cortex-M3内核支持256个中断,其中包含了16个内核中断(异常)和240个外部中断,并且具有256级的可编程中断设置。但是,STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有84个中断,包括16个内核中断(异常)和68个可屏蔽中断,具有16级可编程的中断优先级。而STM32F103系列上面,16个内核中断(异常)不变,而可屏蔽中断只有60个(在107系列才有68个)  优先级号越小,优先级越高

2.中断优先级分组

这60个中断,怎么管理呢?这就涉及到STM32的中断分组。STM32可以将中断分成5个组,分别为组0-4;同时,对每个中断设置一个抢占优先级和响应优先级。分组配置是由SCB->AIRCR寄存器的bit10-8来定义的。SCB->AIRCR是在哪里的呢?由于这是CM3内核定义的,具体的分配关系如下所示:

CM3中定义了8个Bit用于设置中断源的优先级,而STM32只选用其中的4个Bit抢占优先级的级别高于响应优先级,而数值越小所代表的的优先级越高,介绍一下抢占优先级、响应优先级的区别:


·高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的;

·抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断;

·抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行;
·如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;

除此之外有两点需要注意:

·打断的情况只会与抢占优先级有关,和响应优先级无关

·一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果

3.中断优先级控制函数结构体


·中断优先级控制函数 
 NVIC_SetPriorityGrouping()

·中断优先级控制结构体参数
 NVIC_IRQChannel:定义初始化的是哪一个中断

NVIC_IRQChannelPreemptionPriority:  定义此中断的抢占优先级别

NVIC_IRQChannelSubPriority:  定义此中断的响应优先级别

NVIC_IRQChannelCmd:该中断是否使能

NVIC_Init() :函数初始化NVIC寄存器


4.中断优先级设置步骤


1、系统运行后先设置中断优先级分组。调用函数。


2、针对每个中断,设置对应的抢占优先级和响应优先级。


3、如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

小项目:外部中断按键控制LED灯

软件流程设计
1.初始化系统

初始化GPIO、EXTI外设时钟

初始化按键和LED引脚(按键引脚为PA0,LED引脚为PA1)

初始化EXTI外部中断条件

初始化NVIC嵌套中断控制器

void Shake_Init(void)
{

	GPIO_InitTypeDef GPIOEXTI;       //GPIO结构体
	EXTI_InitTypeDef Exti_Initstruct;//中断结构体
	NVIC_InitTypeDef NVIC_Initstruct;//NVIC结构体
	
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//初始化GPIOA和引脚复用时钟
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置NVIC优先级分组
	
	
	
	GPIOEXTI.GPIO_Mode = GPIO_Mode_IPU;//模式为上拉输入
	GPIOEXTI.GPIO_Pin = GPIO_Pin_0;    //引脚为PA0
	GPIO_Init(GPIOA, &GPIOEXTI);       //初始化GPIO结构体
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//配置外部中断线GPIO
	
	Exti_Initstruct.EXTI_Line = EXTI_Line0;                    //配置外部中断线
	Exti_Initstruct.EXTI_LineCmd = ENABLE;                     //外部中断线使能
	Exti_Initstruct.EXTI_Mode = EXTI_Mode_Interrupt;           //配置外部中断模式
	Exti_Initstruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//边沿检测
    EXTI_Init(&Exti_Initstruct);                               //初始化中断结构体
	
	NVIC_Initstruct.NVIC_IRQChannel = EXTI0_IRQn;              //配置中断通道
	NVIC_Initstruct.NVIC_IRQChannelCmd = ENABLE;               //该中断是否使能
	NVIC_Initstruct.NVIC_IRQChannelPreemptionPriority = 0;     //定义抢占优先级
	NVIC_Initstruct.NVIC_IRQChannelSubPriority = 0;            //定义响应优先级
	NVIC_Init(&NVIC_Initstruct);                               //初始化NVIC结构体

}
2.编写外部中断函数

判断中断发生控制LED灯

//编写外部中断函数
void EXTI0_IRQHandler()
{
    if ( EXTI_GetITStatus(EXTI_Line0) != RESET)    //检测中断
		{
		     GPIO_ResetBits(GPIOA, GPIO_Pin_1);
			 delay(1000);
             GPIO_SetBits( GPIOA, GPIO_Pin_1); 
			 delay(1000);                          //中断发生则LED亮1s灭1s
		     EXTI_ClearITPendingBit(EXTI_Line0);   //清除中断
		
		}			
 
}
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值