带你了解STM32:EXTI外部中断
目录
1.中断系统
2.中断执行流程
3.STM32中断
4.NVIC(嵌套中断向量控制器)基本结构
5.NVIC优先级分组
6.EXTI简介
6.1 EXTI基本结构
6.2 AFIO复用IO口(数据选择器)
6.3 EXTI框图
7.什么样的设备需要用到外部中断,使用外部中断有什么好处
8.旋转编码器简介
8.1 硬件电路
8.2 参考资料
9.对射式红外传感器计次代码
第一步:按图接线到面包板
第二步:复制OLED显示屏代码
第三步:新建文件,将传感器文件封装在一个工程里CountSensor
第四步:初始化
第五步:完善对射式红外传感器计次模块,.c文件写中断函数,头文件中断函数不用声明,因为中断函数不需要调用,自动执行
第五步:主函数调用
10.旋转编码器计次代码
第一步:按图接线到面包板上
第二步:复制OLED工程
第三步:模块化旋转编码器,新建文件,命名为Encoder
第四步:主函数调用
11.EXTI外部中断库函数
AFIO相关函数
EXTI库函数
NVIC的四个库函数
1.中断系统
中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行
中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源
中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回
2.中断执行流程
中断程序的执行流程。主程序在执行到某处时,外设的中断条件满足时,主程序就会立即暂停,程序由硬件电路自动跳转到中断程序中,中断执行完后,程序才会返回到被暂停的地方继续执行,被暂停的地方称之为“断点”,为了程序能在中断返回后继续原来的工作,在中断执行前,会对程序的当前状态进行保护,中断执行完后,会还原未完成的程序状态(编译器自行完成)。比如:主函数中的Delay函数正在推迟,外设的中断程序执行了,Delay马上停止并保护Delay的当前状态,等待中断程序执行完后,还原Delay的状态,之后Delay继续执行
中断嵌套的执行流程。主程序正常执行,外设的中断程序条件满足,程序跳转到中断程序执行,当又有优先级更高的中断程序执行时,当前的中断程序会停止,进行优先级更高的中断程序,优先级更高的中断程序执行完后,执行原来的中断程序,原来的中断程序执行完后,执行主程序
中断程序代码。一般中断函数都是在一个子函数里面的,这个函数不需要人为调用,当中断来临时,由硬件自动调用
3.STM32中断
68个(不一定有这么多,具体的看手册)可屏蔽中断通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设
使用NVIC(STM32中管理中断分配优先级)统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级
STM32中断向量表。灰色的是内核的中断(一般用不到),白色的是STM32外设的中断。中断地址用处:因为程序中的中断函数的地址是由编译器分配的不固定,但是中断跳转,由于硬件的限制,只能跳到固定的地址执行程序,所以为了能让硬件跳转到一个不固定的中断函数里面,就需要在内存中定义一个地址的列表,这个是列表固定的,这个就是中断向量表(程序跳转的一个跳板),中断发生,就跳到这个固定的地址,然后在这个固定位置,由编译器,再加上一条跳转到中断函数的代码,这样中断跳转就能跳到任意地址了,C语言编程是不需要管这个表的,编译器会自动实现
4.NVIC(嵌套中断向量控制器)基本结构
NVIC是一个内核外设,CPU的小助手
5.NVIC优先级分组
NVIC的中断优先级由优先级寄存器的4位(0~15)(值越小,优先级越高,0就是最高优先级)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级
抢占优先级高的可以中断嵌套(在原来的中断程序还没结束时,抢占优先级高的可直接进行程序运行),响应优先级高的可以优先排队(在原来的中断程序结束后,响应优先级高的可直接进行程序运行),抢占优先级和响应优先级均相同的按中断号(STM32中断向量表中)排队,所以STM32不存在先来后到的排队方式,在任何时候优先级高的先响应
6.EXTI简介
EXTI(Extern Interrupt)外部中断
EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序(引脚电平变化,申请中断)
支持的触发方式:上升沿(低电平变成高电平)/下降沿(高电平变成低电平)/双边沿/软件触发
支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断
通道数:16个GPIO_Pin(外部中断的主要功能),外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒(这四个是“蹭网”的,,因为外部中断有个功能,就是从低功耗模式的停止模式下唤醒STM32,那对于PVD电源电压监测,当电源从电压过低恢复时,就需要PVD借助一下外部中断退出停止模式,比如:RTC闹钟,有时候为了省电,RTC定一个闹钟之后,STM32会进入停止模式,等到闹钟响的时候再唤醒,这也需要借助外部中断)
触发响应方式:中断响应/事件响应(触发事件外部中断的信号就不会通向CPU,而是通向其他的外设,用来触发其他外设的操作)
总结一下,中断响应是正常的流程,引脚电平变化触发中断,事件响应不会触发中断,而是触发别的外设操作,属于外设之间的联合工作
6.1 EXTI基本结构
6.2 AFIO复用IO口(数据选择器)
AFIO主要用于引脚复用功能的选择和重定义(数据选择器的作用)
在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择
AFIO选择引脚的结构图
6.3 EXTI框图
或门:多个输入一个输出。执行或的逻辑,在输入端只要有一个是高电平1,输出就是高电平1,只有全部输入低电平0,输出才为0
与门:多个输入一个输出。执行与的逻辑,在输入端只要有一个输入低电平0,输出就是0,只有全部输入高电平1,输出才为1
非门:一个输入一个输出。执行非的逻辑,输入1输出0,输入0输出1
数据选择器:多个输入一个输出。侧面有选择控制端,根据控制端的数据,从输入选择一个输出
中断屏蔽寄存器:通过与门,输入1,那么请求挂起寄存器就可以直接输出,允许中断,输入0,那么就不允许中断
事件屏蔽寄存器:通过与门,输入1,允许事件发生,输入0,那么就不允许事件发生
7.什么样的设备需要用到外部中断,使用外部中断有什么好处
使用外部中断模块的特性:对于STM32,想要获取的信号是外部驱动的很快的突发信号,比如:旋转编码器,如果很久不拧,这时STM32不需要做很多事,但是一拧,就会有很多的脉冲波形需要STM32接收,这个信号是突发的,这时就要考虑STM32的外部中断。按键不推荐使用外部中断,外部中断对于按键抖动的处理不好,建议使用定时器
好处:STM32主程序的执行不会太过于复杂
8.旋转编码器简介
旋转编码器:用来测量位置、速度或旋转方向的装置,当其旋转轴旋转时,其输出端可以输出与旋转速度和方向对应的方波信号,读取方波信号的频率和相位信息即可得知旋转轴的速度和方向
类型:机械触点式/霍尔传感器式/光栅式
实物图
8.1 硬件电路
8.2 参考资料
9.对射式红外传感器计次代码
第一步:按图接线到面包板
第二步:复制OLED显示屏代码
第三步:新建文件,将传感器文件封装在一个工程里CountSensor
第四步:初始化
外部中断配置思路:1.配置RCC,将图中涉及的外设时钟打开;2.配置GPIO,选择端口的输入模式(看手册配置模式);3.配置AFIO,选择用的这一路的GPIO,连接到后面的EXTI;4.配置EXTI,选择边沿触发方式(上升沿、下降沿、双边沿)和触发响应方式(中断响应、事件响应);5.配置NVIC,给中断选择一个合适的优先级,最后通过NVIC,外部中断信号就能进入CPU了,这样CPU才能到收到中断信号,才能跳转到中断函数里执行中断程序
第五步:完善对射式红外传感器计次模块,.c文件写中断函数,头文件中断函数不用声明,因为中断函数不需要调用,自动执行
第五步:主函数调用
最终代码
10.旋转编码器计次代码
第一步:按图接线到面包板上
第二步:复制OLED工程
第三步:模块化旋转编码器,新建文件,命名为Encoder
第四步:主函数调用
最终代码
11.EXTI外部中断库函数
AFIO相关函数
GPIO_AFIODelnit,这个函数是用来复位AFIO外设的,调用这个函数,AFIO外设的配置就会全部清除
GPIO_PinLockConfig,这个函数是用来锁定GPIO配置的,调用这个函数,参数指定某个引脚,那这个引脚的配置就会被锁定,防止意外更改
GPIO_EventOutputConfig、GPIO_EventOutputCmd,这两个函数是用来配置AFIO的事件输出功能的
GPIO_PinRemapConfig,这个函数可以用来进行引脚重映射,第一个参数选择要重映射的方式,第二个参数是新的状态
GPIO_EXTILineConfig,这个函数可以配置AFIO的数据选择器,来选择想要的中断引脚
GPIO_ETH_MediaInterfaceConfig,这个函数和以太网有关
EXTI库函数
EXTI_Delnit,这个函数可以把EXTI的配置都清除,恢复成上电默认的状态
EXTI_Init,这个函数可以根据结构体里的参数配置EXTI外设,初始化EXTI的函数
EXTI_StructInit,这个函数可以把参数传递的结构体变量赋一个默认值
EXTI_GenerateSWInterrupt,这个函数是用来软件外部中断函数的,参数给一个指定的中断线,调用一次就能软件中断一次
剩下的库函数都是外设标志位函数(基本所以的外设都有这种函数),读写状态寄存器
前两个函数,在主程序查看和清除标志位,第一个可以获取指定的标志位是否被置为1,第二个可以对置1的标志位进行清除
后两个函数,在中断函数里查看和清除标志位,第一个获取中断标志位是否被置1,第二个清除中断挂起标志位
NVIC的四个库函数
NVIC_PriorityGroupConfig,这个函数是用来中断分组,参数是中断分组的方式
NVIC_Init,这个函数根据结构体里面指定的参数初始化NVIC
NVIC_SetVectorTable,设置中断向量表
NVIC_SystemLPConfig,系统低功耗配置