STM32中断(EXTI外部中断)

中断适合突发的,剧烈的事件。

中断概念:主程序运行过程中出现了特定的中断触发条件,cpu暂停当前程序去处理中断事件,处理完毕后再返回暂停前的位置继续执行。

中断有优先级,高优先级中断可以中断低优先级中断。

外部事件中断所涉及到的外设:

GPIO、AFIO、EXIT、NVIC

发生中断时:EXTI检测指定GPIO的电平信号,当其指定的GPIO口产生指定的电平变化时,EXTI立刻向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序。

GPIO允许中断的发生与检测,中断由GPIO获取信号作为起始

AFIO为数据选择器,由于只有16个中断源,而引脚有16×7个引脚,所以规定每个引脚只能拥有一个中断,也就是说如果GPIOA1作为中断源,则GPIOB1、C1就无法作为中断源。AFIO用来选择哪一个端口的哪一个引脚连接中断源。

EXIT是外部中断外设,可以检测指定GPIO的电平信号(由AFIO选择),检测到指定的电平信号(上升沿/下降沿/双边沿)后向NVIC发出中断申请。

NVIC是嵌套中断向量控制器,用来对众多外设的中断进行优先级排序,为cpu处理中断提供方便。

NVIC中规定了中断的优先级分为抢占优先级和响应优先级,抢占优先级决定了此中断是否能够中断别的中断,响应优先级决定了某个正在运行的中断结束后,此中断是否是第一个被执行的中断。抢占优先级和响应优先级共用一个四位寄存器,具体分配的多少由优先级分组决定。

优先级分组设置好后,所有的众多外设全按照此分组分配优先级。(数字越小优先级越高)

外部事件中断流程:

以下是具体的代码:

//实现指南者按键1的中断配置
void EXTI_Key1_Init(void)
{
	//-------------------------------------配置GPIO-----------------------------------------
	
	//开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//定义结构体
	GPIO_InitTypeDef GPIO_InitStruct;
	//设置结构体成员
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;//按键默认接低电平,按下开关变成高电平,所以输入模式为下拉电阻,默认低电平
	//应用结构体函数
	GPIO_Init(GPIOA,&GPIO_InitStruct);

	//-------------------------------------配置AFIO-----------------------------------------
	
	//开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	//选择引脚连接中断通道
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

	//-------------------------------------配置EXTI-----------------------------------------
	
	//定义结构体
	EXTI_InitTypeDef EXTI_InitStruct;
	//配置结构体变量
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStruct.EXTI_Line = EXTI_Line0;
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	
	EXTI_Init(&EXTI_InitStruct);

	//-------------------------------------配置NVIC-----------------------------------------
	
	//分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置成2,2的分布,2bit抢占优先级,2bit响应优先级。
	
	//定义结构体
	NVIC_InitTypeDef NVIC_InitStruct;
	
	//配置结构体成员
	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
	
	//应用结构体
	NVIC_Init(&NVIC_InitStruct);
	
	//-------------------------------------编写中断函数-----------------------------------------
	//中断函数编写在了stm32f10x_it.c中,使用中断函数须在main.c中引用其头文件
	
}
//中断函数
void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0) == SET)//发现中断标志位为1,说明按下了按键(其实此处不检测也可以?)
	{
		count++;
		OLED_ShowNum(1,2,count,2);//如果执行则将数字从0变成1
		
		
		
		EXTI_ClearITPendingBit(EXTI_Line0);//清除标志位,防止一直进入中断函数。
	}
	
}

编写代码过程中的一些细节:

1.NVIC的中断源和中断函数名不同,NVIC中断源是“EXTI0_IRQn”,中断函数名是“EXTI0_IRQHandler”,中断源在stm32f10x.h文件中,中断函数名字在启动文件 startup_stm32f10x_hd.s中

2.NVIC的固件库函数在misc.h和misc.c中

3.关于多文件编程中的跨文件变量,跨文件变量只能是某个文件的全局变量,假如int变量count在a.c中定义,想要在b.c中使用,则只需要在b.h中写:extern int count;。不需要在a.h中声明,如若声明,则会报错。

4.中断函数可以编写在自己写的文件中(应该是可以在任何文件中),只需要引用此文件即可,但是stm32标准库中建议中断函数都写在stm32f10x_it.c中,使用时引用stm32f10x_it.h即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shimmer8875

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值