EXTI外部中断

devtools/2024/10/10 11:26:24/

目录

一.前言

二. 红外对射式传感器

三.旋转编码器


一.前言

        什么是中断?中断就是在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。为什么能够在原来位置继续运行的原因就在于我们的单片机具有还原现场的能力。值得注意的是:最好不要在主程序和中断程序里,进行可能产生冲突的硬件配置。例如主程序中正在使用OLED,突然收到中断,从而转到中断函数中,而这个时候中断函数再进行OLED相关的操作,那么在执行完中断程序后,继续执行主程序就会出错。

        在知道了什么是中断之后,大家应该就不难理解EXTI中断了。EXTI中断,可以检测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序。

看到这里,想必大家还是有点问题的,NVIC又是什么呢?它的名字叫做嵌套中断向量控制器,在内核中帮助CPU处理中断选择,这样CPU就只需要执行中断,而不再需要自己进行筛选了。如下所示:

 讲到这里,肯定有不少小伙伴对这个NVIC是怎么筛选中断的过程感兴趣吧。这里我们讲下NVIC的中断优先级。它是由优先寄存器的4位决定的,这4位又可以进行切分,分为高n位的抢占优先级和4-n位的响应优先级。其中,抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,如果这两个都相同,那么就得按照中断号进行排队。这个中断号就在我们的引脚定义图当中。

其实,NVIC能够完成它的工作还得多亏了前面的两个“大功臣”----AFIO和EXTI边沿检测及控制。

二. 红外对射式传感器

        在了解了上述知识后,我们就可以开始进行实际中断操作了。首先就是我们的红外对射式传感器。将它连在任意的GPIO口上,这里我选择GPIOB口的14号。

首先肯定开启外设的时钟,不然是没法进行工作的。这里需要打开GPIOB和AFIO的时钟,NVIC和EXTI无需打开。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

 接着就是对GPIO,AFIO和EXTI进行初始化了,如下所示:

    //GPIO初始化GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU ;GPIO_InitStruct.GPIO_Pin= GPIO_Pin_14;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStruct);//AFIO选择中断引脚GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//EXTI初始化EXTI_InitTypeDef EXTI_InitStruct;EXTI_InitStruct.EXTI_Line=EXTI_Line14;EXTI_InitStruct.EXTI_LineCmd=ENABLE;EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;EXTI_Init(&EXTI_InitStruct);

这些东西的配置我们是都可以在对应的库函数中查找到的,我们一定要学会查看手册及使用库函数。对GPIO初始化的库函数就在gpio.h当中。AFIO相关的库函数也包括在了gpio.h当中。

对EXTI初始化的库函数包含在了exti.h当中。

下面我们进行最后一步的配置----NVIC的配置,如下所示:

	//NVIC中断分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC配置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);

由于NVIC属于内核当中,所以和它有关的库函数就放在了杂项当中,也就是misc.h。

这里我们设好NVIC的中断分组为2,因为这个小项目不会产生过多的中断冲突,我们就可以随意点,如果后面在做项目的时候,就需要严谨一点了。中断分组的原理如下:

所以这里我们选择了中断分组为2之后,我们的抢占优先级和响应优先级的取值范围就都为0~3了。PreemptionPriority为抢占优先级,subpriority为响应优先级。 所以我们这里都设置为1。

并且由于我们这里选择的是GPIOB的14号引脚中断,而10号到15号是合并在一起的,所以也就是EXTI15_10_IRQN。

在初始化完成之后,我们就可以编写中断函数了,这个中断函数是自动执行的,因此我们不要在头文件当中再进行声明了。关于中断函数的名称,我们可以从启动文件中进行复制。

如下所示:

void EXTI15_10_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line14)==SET)	//判断是否是外部中断14号线触发的中断{//如果出现数据乱跳的情况,可再次判断引脚电平,以避免抖动if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0){CountSensor_Count++;}//清除外部中断14号线的中断标志位EXTI_ClearITPendingBit(EXTI_Line14);}
}

值得注意的是:这里的中断标志位必须清除,否则就会导致中断连续不断地触发,从而导致主程序卡死。 

 到这里,整个配置就已经完成了,如果我们想要检测红外对射式传感器的效果,就可以将其中CountSensor_Count结果显示在OLED上面。这个比较简单,我这里就不再介绍了。如果有任何疑问,欢迎到评论区留言讨论。

三.旋转编码器

        旋转编码器就是用来测量位置,速度或者旋转方向的装置,当其旋转轴旋转时,其输出端可以输出与速度和方向对应的方波信号,读取方波信号的频率和相位信息即可得知旋转轴的速度和方向。

主要类型有:机械触电式/霍尔传感器式/光栅式

相关中断函数配置如下所示,这里它的一些初始化代码和上面的相差不大,只需更换GPIO相关引脚配置即可。

void EXTI0_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line0) == SET)		//判断是否是外部中断0号线触发的中断{/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0){if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)		//PB0的下降沿触发中断,此时检测另一相PB1的电平,目的是判断旋转方向{Encoder_Count --;					//此方向定义为反转,计数变量自减}}EXTI_ClearITPendingBit(EXTI_Line0);			//清除外部中断0号线的中断标志位//中断标志位必须清除//否则中断将连续不断地触发,导致主程序卡死}
}


http://www.ppmy.cn/devtools/123673.html

相关文章

【Android 源码分析】Activity生命周期之onStop-2

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

STM32单片机(F03C8T6)-点灯(寄存器点灯和库函数点灯)

作者:Whappy 时间:2024.10.9 日志:本实验是我第一个32位单片机实验程序,如有不足请指点! #include "stm32f10x.h" // Device headerint main(void) {//寄存器点灯RCC->APB2ENR 0x000…

团标大数据(2024年09月)

一、总体数据 截至2024年09月30日,共有8240家社会团体在全国团体标准信息平台注册,其中民政部登记注册的有973家,地方民政部门登记注册的有7267家。社会团体在平台共计公布89857项团体标准,其中民政部登记注册的社会团体公布3603…

使用C语言获取iostat中的await值的方法和方案

使用C语言获取iostat中的await值的方法和方案 1. 准备工作2. 调用iostat命令并获取输出3. 解析iostat输出4. 完整实现和错误处理5. 注意事项在Linux系统中,iostat命令是sysstat软件包的一部分,用于监控系统的CPU、网卡、tty设备、磁盘、CD-ROM等设备的活动情况和负载信息。其…

Word 首行缩进 2 字符怎么设置?具体步骤演示

在日常的文档编辑和排版中,首行缩进是一个非常常见且重要的排版需求。尤其是在中文文档中,首行缩进能够提高文章的美观度和可读性,使文章结构更加清晰。那 Word 首行缩进 2 字符怎么设置呢?下面就给大家展示具体的操作步骤。 设置…

深入理解C#中的TimeSpan结构体:创建、访问、计算与格式化

TimeSpan 结构体在 C# 中用于表示两个时间点之间的时间间隔。它可以表示天、小时、分钟、秒以及毫秒的时间长度。TimeSpan 结构体非常适合于处理时间差,比如计算两个 DateTime 对象之间的差异,或者在需要表示一段时间长度时使用。 以下是一些使用 TimeS…

Git---Git打标签

打标签 像其他版本控制系统(VCS)一样,Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0 、 v2.0 等等)。 在本节中,你将会学习如…

PHP基本语法总结

目录 输出语句 注释 数据类型(变量) 局部和全局作用域 类型比较(松散比较与严格比较) 常量 运算符 并置运算符 不等于 逻辑运算符 条件语句 数组 关联数组 数组排序 一般数组 关联数组 循环 函数 变量函数 魔…