stm32外部中断EXTI

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

二、中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源。

三、中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回。

四、中断处理过程

1、中断请求
在中断请求被响应之前会一直发送中断请求。

2、中断源识别
当系统同时有多个中断源发出的中断请求时,系统往往只能相应并处理一个中断,这就要求CPU对来到的中断请求进行判优,选择出同一时间优先级最高的给予响应和处理。

3、中断响应
中断响应时,CPU要向中断源发出中断响应信号,还要保护现场即将FLAGS压入堆栈,将下一条指令的CS压入堆栈,将下一条指令的IP压入堆栈。还要将终端的入口赋给IP和SP。
4、中断处理
保护软件现场(把中断服务子程序中要用到的寄存器的内容压入堆栈)、开中断(为了可以嵌套)、执行中断处理程序、关中断、恢复现场。
5、中断返回
利用IRET进行中断返回会将堆栈中保存的信息弹出到P和CS和FLAGS中。

五、stm32中断

1、68个可屏蔽中断通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设(中断源)。

2、使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级。

如上图,当有多个中断请求时,NVIC会设置优先级,CPU根据优先级再依次处理中断。

六、EXTI(Extern Interrupt)外部中断

EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序
支持的触发方式:上升沿/下降沿/双边沿/软件触发
支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断
通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒
触发响应方式:中断响应/事件响应

AFIO主要用于引脚复用功能的选择和重定义

在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择。

根据如上结构,EXTI外部中断的步骤应该为:

1.配置RCC,打开需要用到的GPIO外设时钟;

2.配置GPIO,选择端口为输入模式;

3.配置AFIO,选择用到的这一路的GPIO,连接到后面的EXTI;

4.配置EXTI,选择边沿触发方式,上升沿,下降沿或双边沿,选择触发响应方式,可以选择中断响应和事件响应;

5.配置NVIC,给中断选择一个合适的优先级。

完成以上步骤后,中断信号就能通过NVIC进入CPU了,CPU才能收到中断信号,跳转到相应的中断服务函数中去执行。

七、对射式红外传感器计次

接线图

 

EXTI外部中断初始化及中断函数

#include "stm32f10x.h"                  // Device header

uint16_t CountSensor_Count;

void CountSensor_Init(void)
{
    //1.配置RCC
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //GPIOB时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //AFIO时钟使能
	//2.配置GPIO
	GPIO_InitTypeDef GPIO_InitStructure;   //引脚初始化
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//3.配置AFIO
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);  //选择用作EXTI线的GPIO引脚
	4.配置EXTI
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;  //第14线路
	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);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;  //启用14通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //使能通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //设置抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //设置响应优先级
	NVIC_Init(&NVIC_InitStructure);
}

uint16_t CountSensor_Get(void)
{
	return CountSensor_Count;
}

void EXTI15_10_IRQHandler(void)  //中断函数
{
	if (EXTI_GetITStatus(EXTI_Line14) == SET)  //中断标志位判断,确认是EXTI14
	{
		CountSensor_Count ++;
		EXTI_ClearITPendingBit(EXTI_Line14);  //清除中断标志位
	}
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"

int main(void)
{
	OLED_Init();
	CountSensor_Init();
	
	OLED_ShowString(1, 1, "Count:");
	
	while (1)
	{
		OLED_ShowNum(1, 7, CountSensor_Get(), 5);
	}
}

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值