嵌入式STM32—第四天中断实现控制led灯解析优先级

本文详细介绍了如何在STM32中配置中断优先级,包括抢占优先级、响应优先级和自然优先级,并通过具体代码展示了NVIC控制器的使用,以及EXTI中断的初始化设置。通过设置不同中断源的优先级,实现了对LED灯控制的中断响应策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.软件及工程环境搭建

  • 就不介绍了,可以直接用现成的
    链接:https://pan.baidu.com/s/1GaSYpNm6yh-lZZmqRdXxvQ
    提取码:dy63
  • 相关资料文件
    链接:https://pan.baidu.com/s/1X4eUtVAlA7r2eRojVgQJ9Q
    提取码:9sgn

中断实现控制led灯解析优先级

- M4中断优先级(分三种):
抢占优先级:含义是不同等级间的中断可以嵌套,高优先级可以中断低优先级,数字小的优先级高。

响应优先级:含义是不同响应优先级的中断不能嵌套,但是当抢占优先级相同,响应优先级不同,多个中断源同时发生中断时候,响应优先级高的中断事件会优先响应,数字小的优先级高。

自然优先级:就是NVIC控制器的中断源编号,数字小的,优先级高。作用:当抢占优先级和响应优先级都相同的中断源同时发生中断时候,自动优先级高的优先响应。不存在嵌套行行。
优先级等级小结:抢占优先级>响应优先级>自然优先级占优先级决定是否可以嵌套,响应优先级和自然优先级决定同时发生时,先响应谁(如果抢占相同,才依据响应,如果抢占和响应都相同,自然优先级才会起作用)
在这里插入图片描述

- NVIC控制器一般步骤:

  • 设置分组方式
  • 确定中断源的抢占优先级和响应优先级,使用NVIC_EncodePriority函数进行编码
  • 把上下编码得到优先级值写入优先级配置寄存器,使用NVIC_SetPriority函数。
  • 使能对应中断源,使用NVIC_EnableIRQ函数。
    不太了解的话可以看一下资料NVIC.ppt里面有挺详细的
  • 配置整个应用程序的中断分组方式,STM32F4只有0~4组

先LED初始化,就不写了,第一天的有,中断配置不太了解的,可以去看看第三天的,那就开始了哦,Exit_Init初始化

/*******************************************************
*函数名:Exit_Init
*功  能: NVIC中断初始化
*参  数:无
*返  回:无
*备  注:注意开启PA0,PD2的PC12的映射SYSCFG时钟 ,使能外部中断
********************************************************/
void Exit_Init(void)
{		
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);//开启SYSCFG时钟,简称重映射 
		EXTI_InitTypeDef  Exit_Key1,Exit_Key2,Exit_Key3;//定义外部中断结构体变量	
		//key1
		SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0); //映射到PA0引脚到EXTI
		Exit_Key1.EXTI_Line = EXTI_Line0; //选择EXTI0
		Exit_Key1.EXTI_Mode = EXTI_Mode_Interrupt; // 选择模式(中断)
		Exit_Key1.EXTI_Trigger = EXTI_Trigger_Rising;//选择上升沿触
		Exit_Key1.EXTI_LineCmd = ENABLE;//启用EXTI0
		EXTI_Init(&Exit_Key1);//写入EXTI初始化
		NVIC_SetPriority(EXTI0_IRQn,NVIC_EncodePriority(0x05,1,1));//NVIC,响应分组二,抢占优先级一,响应优先级一
	    NVIC_EnableIRQ(EXTI0_IRQn);//使能外部中断0线进行工作
	
		//key2
		SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD,EXTI_PinSource2); //映射到PD2引脚到EXTI2	
		Exit_Key2.EXTI_Line = EXTI_Line2; //选择EXTI2
		Exit_Key2.EXTI_Mode = EXTI_Mode_Interrupt; // 选择模式(中断)
		Exit_Key2.EXTI_Trigger = EXTI_Trigger_Falling;//选择下升沿触
		Exit_Key2.EXTI_LineCmd = ENABLE;启用EXTI2
		EXTI_Init(&Exit_Key2);//写入EXTI初始化
		NVIC_SetPriority(EXTI2_IRQn,NVIC_EncodePriority(5,2,2));//NVIC,响应分组二,抢占优先级二,响应优先级二
	    NVIC_EnableIRQ(EXTI2_IRQn);//使能外部中断2线进行工作
		
		//key3
		SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,EXTI_PinSource12); //映射到PC12引脚到EXTI3	
		Exit_Key3.EXTI_Line = EXTI_Line12; //选择EXTI12
		Exit_Key3.EXTI_Mode = EXTI_Mode_Interrupt; // 选择模式(中断)
		Exit_Key3.EXTI_Trigger = EXTI_Trigger_Falling;//选择下升沿触
		Exit_Key3.EXTI_LineCmd = ENABLE;//启用EXTI3
		EXTI_Init(&Exit_Key3);//写入EXTI初始化
		NVIC_SetPriority(EXTI15_10_IRQn,NVIC_EncodePriority(5,1,1));//NVIC,响应分组二,抢占优先级一,响应优先级一		
	    NVIC_EnableIRQ(EXTI15_10_IRQn);//由于没有EXTI12,所以使能外部中断15_10线进行工作	
		
}
  • 总结一下:响应分组要一致看自己需要配置,抢占优先级越低抢的厉害,假如抢占优先级相同,响应优先级越低,没用抢不了。响应优先级只是比同时谁先用而已。追加:如果对应的不设置NVIC;那他默认是抢占优先级零,响应优先级零。
  • 功能:
/*******************************************************
*函数名:EXTI0_IRQHandler
*功  能:按键一中断
*参  数:无
*返  回:无
*备  注:注意挂起寄存器(清0)
********************************************************/
int EXTI1_flag;

void EXTI0_IRQHandler(void)//由中断自动触发
{
		 
		EXTI_ClearFlag(EXTI_Line0); //挂起寄存器PA0
		EXTI1_flag++;
		if(EXTI1_flag%2)
		GPIO_ResetBits(GPIOC,GPIO_Pin_13);
		else 
		GPIO_SetBits(GPIOC,GPIO_Pin_13);
}
/*******************************************************
*函数名:EXTI0_IRQHandler
*功  能:按键二中断
*参  数:无
*返  回:无
*备  注:注意挂起寄存器(清0)
********************************************************/
int EXTI2_flag;
void EXTI2_IRQHandler(void)//由中断自动触发
{
		EXTI_ClearFlag(EXTI_Line2); //挂起寄存器PD2
		EXTI2_flag++;
		if(EXTI2_flag%2)
		GPIO_ResetBits(GPIOC,GPIO_Pin_10);
		else 
		GPIO_SetBits(GPIOC,GPIO_Pin_10);
		while(1)
		{
				
		};
}

/*******************************************************
*函数名:EXTI0_IRQHandler
*功  能:按键三中断
*参  数:无
*返  回:无
*备  注:注意挂起寄存器(清0)
********************************************************/
int EXTI3_flag;
void EXTI15_10_IRQHandler(void)
{
			EXTI3_flag++;
			if(EXTI3_flag%2)
			GPIO_ResetBits(GPIOC,GPIO_Pin_11);
			else 
			GPIO_SetBits(GPIOC,GPIO_Pin_11);
			EXTI_ClearFlag(EXTI_Line12);  //挂起寄存器PC2
}
  • 总结一下:点击按键二是死循环,通过优先级控制按键一和按键三打断。

- 主函数main调用相关的函数

//SCB->AIRCR =0X05FA<<16 |5<<8; //纯寄存器设置写入秘钥,设置分组为2
	NVIC_SetPriorityGrouping(5);  //NVIV函数设置分组2,4个位,高2位作为抢占,低2位作为响应
	LEDInit();//LED初始化
	Exit_Init();//按键NVIC中断初始化
	while(1)
	{
		//嵌入式少不了while(1),要程序一直执行的
	}

到此完美实现中断实现控制led灯解析优先级,最后感谢大家阅读,如果需要其他相关资料请联系我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值