本节课学习一下STM32的外部中断和中断系统
EXTI简介

中断系统是管理和执行中断的逻辑结构
外部中断是众多能产生中断的外设之一,所以本节课我们就借助外部中断来学习一下中断系统。以后在学其他外设的时候,也是会经常和中断打交道的
中断系统
-
中断 :在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成之后又返回原来被暂停的地方继续运行
-
- 中断 就是在正常主程序 执行的某个时刻 ,发生了中断触发条件 ,比如对外部中断 来说,可以是引脚发生了电平跳变 ;对定时器 来说,可以是定时的时间到了;对于串口通信来说,可以是接收到了数据
-
- 当这些事件发生时,情况会比较紧急。比如外部中断 来了,你如果不来处理,下一个跳变信号 就跟着过来了;比如串口接收中断 来了,你如果不来读取接收到的数据,拿下一个数据再来,就会覆盖掉原来的数据。所以我们希望当中断条件满足时CPU能立即停下当前执行的程序,转而去处理这些中断事件的程序CPU能立即停下当前执行的程序,转而去处理这些中断事件的程序CPU能立即停下当前执行的程序,转而去处理这些中断事件的程序比如外部中断 来了,我想要计次 ,那就变量++;串口中断 来了,我就把接受到的数据转存起来。当这些紧急事件完成后,CPU还能回到原来停下的地方继续运行
-
- 这就是中断的处理流程和用途。使用中断系统,能够极大地提高程序的效率
-
要是没有中断系统 ,为了防止外部中断被忽略 或者串口数据被覆盖 ,那主程序就只能不断地查询是否有这些事件发生,不能再干其他的事情了;要是没有定时器中断 ,那主程序只有靠Delay函数 ,才能实现定时的功能。但有了中断系统之后,主程序就可以放心执行其他的事情,有中断的时候再去处理
-
- 就像早上定了一个闹钟,定好之后就可以放心睡觉了,时间到了闹钟会提醒你,就相当于产生了一个中断信号;如果没有闹钟,就得不断地看时间,生怕错过了起床点,这样没法安心睡觉

- 就像早上定了一个闹钟,定好之后就可以放心睡觉了,时间到了闹钟会提醒你,就相当于产生了一个中断信号;如果没有闹钟,就得不断地看时间,生怕错过了起床点,这样没法安心睡觉
-
中断优先级 :当有多个中断源 同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源
-
- 也就是说,中断优先级 就是中断的紧急程度 ,这个中断优先级 是我们根据程序设计的需求,自己设计的。此外,中断优先级还有多种分类
-
中断嵌套 :当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回。这种把中断程序再次中断的现象,就叫做中断嵌套 。能否进行中断嵌套 ,也是由中断优先级来决定的
中断执行流程
- 左边是一般的含中断的程序,当它执行到某个地方时,外设的中断条件 满足了,无论主程序在做什么事情,比如加减乘除还没算完,OLED显示程序才执行一半,Delay函数还在等待,中断来了,主程序都得立即暂停,程序由硬件电路 自动跳转到中断程序 中。当中断程序执行完之后,程序再返回被暂停的地方继续运行。
- 被暂停的地方,我们称之为 断点断点断点。为了程序能在中断返回后继续原来的工作,在中断执行前,会保护程序的现场 ,中断执行后,会再还原现场 ,这样可以保证主程序即使被中断了,回来之后也能继续运行。当然我们用C语言编程,保护现场 和还原现场 的工作并不需要我们来做,编译器自动帮我们做好了

- 中间这个图,就是中断嵌套的执行流程。
- 假设下图这个被圈起来的中断正在执行时,又有新的优先级更高的中断来。那这里就会再次打断,然后执行新的中断。新的中断结束,在继续原来的中断;原来的中断结束,再继续主程序。这就是中断嵌套的执行流程

- 再看一下右边的C语言程序,带有中断的程序就是这个样子的。上面是主函数,while(1)死循环里就是主程序。正常情况下,程序就是再主程序里不断循环执行,当中断条件满足时,主程序就会暂停。然后自动跳转到中断程序里运行。中断顺序执行完之后,再返回主程序继续执行。
- 一般中断程序都是在一个子函数里的。这个函数不需要我们调用 。当中断来临时,由硬件自动调用这个函数(相当于被动技能)
- 这就是在C语言程序中,中断的执行流程

STM32中断

- 68个可屏蔽中断通道。这个中断通道就是中断源的意思。68个中断源,这个是F1系列最多的中断数量
- STM32的中断包含EXTI外部中断、TIM定时器、ADC模数转换器 、USART串口、SPI通信、RTC实时时钟。我们可以看到,STM32的中断是非常多的,几乎所有模块都能申请中断
- 使用NVIC统一管理中断,每个中断通道(中断源) 都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级 和响应优先级。
- 这个NVIC 就是STM32中用来管理中断、分配优先级 的。NVIC 的中断优先级总共有16个等级,还可以设置抢占优先级 和响应优先级,这个是非常灵活的
STM32里的中断资源分为灰色区域和白色区域

上面这些灰色的,是内核的中断
- 复位中断 。当产生复位事件时,程序就会自动执行复位中断函数 ,也就是我们复位后程序开始执行的位置。
- NMI、不可屏蔽中断、硬件失效、存储管理、总线错误、错误应用等
这些都是内核里面的,一般这些中断都比较高深,了解一下即可
下面这些白色的部分,就是STM32外设的中断了
- 窗口看门狗 。这个是用来监测程序运行状态 的中断。比如你程序卡死了,没有及时喂狗(向输入端发送信号,清零看门狗的计数值),窗口看门狗就会申请中断。让你的程序调到窗口看门狗的中断程序里,那你在中断程序里就可以进行一些错误检查,看看出什么问题了
- PVD电源电压监测 ,如果你供电电压不足 ,PVD电路就会申请中断,你在中断里就知道,现在供电不足,是不是电池没电了,要赶紧保存一下重要数据
接下来这些也都是类似的功能。外设电路 检测到有什么异常 或者事件 ,需要提示一下CPU 的时候,它就可以申请中断,让程序跳到对应的中断函数里运行一次,用来处理这个异常或事件
- EXTI 0~EXTI 4,EXTI 9_5、EXTI 15_10就是我们本节要学的外部中断对应的中断资源
图右边还有个中断的地址。
这个地址是干什么的呢?

这个是因为我们程序中的中断函数 ,它的地址是由编译器 来分配的,是不固定 的。但是我们的中断跳转 ,由于硬件的限制 ,只能跳到固定的地址执行程序。这个地址不存储中断程序,而是告诉你去哪里执行中断程序
所以为了能让硬件跳转到一个不固定的中断函数 里,这里就需要在内存 中定义一个地址的列表 ------用于存放对应中断服务函数 的入口地址 ,STM32去该地址找到对应的中断服务函数 并执行。这个列表地址是固定的,中断发生后,就跳到这个固定位置。
然后在这个固定位置 ,由编译器,再加上一条跳转到中断函数 的代码。这样中断跳转 就可以跳转到任意位置了。
这个中断地址的列表,就叫中断向量表中断向量表中断向量表相当于中断跳转的一个跳板。
不过我们用C语言编程的话,是不需要管这个中断向量表的,因为编译器都帮我们做好了
NVIC基本结构

NVICNVICNVIC(Nested Vectored Interrupt Controller )嵌套向量中断控制器嵌套向量中断控制器嵌套向量中断控制器
- 在STM32中,它是用来统一分配中断优先级 和管理中断的。NVIC是一个内核外设,是CPU的小助手。我们刚才看到,STM32的中断非常多,如果把这些都接到CPU上,那CPU还得引出很多线进行适配,设计上就很麻烦,并且如果很多中断同时申请,或者中断很多产生了拥堵,CPU也会很难处理,毕竟CPU主要是用来运算的。中断分配的任务就放到别的地方吧,所以NVIC就出现了
- NVIC有很多输入口,多少中断线路都可以接过来,比如图中所展示的,就可以接到EXTI、TIM、ADC、USART等等
- 这个线上画了个斜杠,上面写个n,这个意思是,一个外设可能会同时占用多个中断通道,所以这里有n条线。然后NVIC只有一个输出口,NVIC根据每个中断的优先级分配中断的先后顺序,之后,通过右边这一个输出口就告诉CPU该处理哪个中断。对于中断先后顺序分配的任务,CPU不需要知道
- 假设CPU是个医生
- 如果医院只有医生的话,当看病的人很多的时候,医生就得安排一下先看谁,后看谁。
- 如果有紧急的病人,那还得让紧急的病人最先来。这个安排先后次序的任务很繁琐,会影响医生看病的效率。
- 所以医院就安排了一个叫号系统,来病人了同意取号,并且根据病人的等级,分配一个优先级。
- 然后叫号系统看一下现在在排队的病人,优先叫号紧急的病人。
- 最后叫号系统给医生输出的就是一个一个排好队的病人,医生就可以专心看病了
- 这个叫号系统在STM32里就是NVIC
中断的分组
为了处理不同形式的优先级,STM32的NVIC可以对优先级进行分组
- 抢占优先级 和响应优先级
这两种优先级有什么区别呢
我们回到病人叫号的例子。
- 对于紧急的病人,其实有两种形式的优先。
- 一种是,上一个病人在看病,外面排队了很多病人。当上一个病人看完后,紧急的病人即使是后来的,也会最先进去看病,这种相当于插队 的优先级,就叫响应优先级 。响应优先级高 的,可以插队提前看病。
- 如果这个病人更加紧急,并且此时已经有人在看病了,那他还可以不等上一个人看完,直接冲到医生的屋里,让上一个病人先靠边站,先给他看病 。等他结束再让原来的人继续看病。这种形式的优先就是我们之前讲的中断嵌套 ,这种决定是否可以中断嵌套 的优先级,就叫抢占优先级 。抢占优先级高 的,可以进行中断嵌套

为了把优先级再区分为抢占优先级 和响应优先级,就需要对这16个优先级进行分组了。
- NVIC的中断优先级由优先级寄存器的4位(0~15)决定。这里4位二进制可以表示0 ~ 15的数,对应16个优先级。这个优先级的数是值越小,优先级越高,0就是最高优先级
- 这4位可以进行切分,分为高n位 的抢占优先级 和低4 - n位 的响应优先级
- 抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队。结合刚才的例子可以很好理解
- 抢占优先级 和响应优先级 均相同的按中断号排队。这个中断号就是那个表里的数字

- 当抢占优先级和响应优先级均相同时,就按照这里最左边的数字来排队,数值小的优先响应。
- 所以STM32的中断不存在先来后到的排队方式。在任何时候,都是优先级高的先响应。
然后看一下下面这个表

因为优先级总共是4位,所以就有(0,4)、(1,3)、(2,2)、(3,1)、(4,0)这5种分配方式
- 分组0就是0位的抢占等级 ,取值只能为0 | 4位的响应等级,取值可以是0 ~ 15
- 分组1是1位的抢占等级 ,取值是0~1 | 3位的响应等级,取值是 0 ~ 7
- 然后分组2、3、4都是按这个规律来分配的
这个分组方式在程序中是我们自己来选择的。选好分组方式之后,我们在配置优先级的时候,就要注意抢占优先级和响应优先级的取值范围 了,不要超出这个表里规定的取值范围。
了解完NVIC "叫号系统"和叫号的规则之后,我们就来看一下第一个病人------EXTI外部中断
EXTI外部中断

- EXTI (Extern Interrupt)外部中断
- 第二条是EXTI的基本功能,简单来说就是引脚电平变化,申请中断
- 触发方式:EXTI支持引脚电平的变化类型有上升沿/下降沿
-
- 上升沿,就是低电平变到高电平的瞬间触发中断
-
- 下降沿,就是高电平变到低电平的瞬间触发中断
-
- 双边沿,就是上升沿和下降沿都可以触发中断
-
- 软件触发,就是引脚啥事没有,程序里执行一句代码,就能触发中断
再看一下外部中断支持的GPIO口,它支持所有GPIO口,也就是任意的GPIO口都可以当作外部中断的引脚,但相同的Pin不能同时触发中断。
- 这个意思就是,比如PA0 和PB0 不能同时用。或者PA1、PB1、PC1 这样的,端口GPIO_Pin 一样的,只能选一个作为中断引脚
- 所以如果有多个中断引脚,要选择不同Pin的引脚
再看一下外部中断占用的通道
- 其中有16个GPIO_Pin ,这就对应GPIO_Pin_0 到GPIO_Pin_15 ,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒,这些加起来总共有20个中断线路。
- 这里的16个GPIO_Pin 是外部中断的主要功能,后面跟着的这四个东西其实是来"蹭网"的
为啥这些东西要来外部中断蹭网呢
- 因为这个外部中断有个功能,就是从低功耗模式的停止模式下唤醒STM32
- 那对于PVD电源电压监测 ,当电源从电压过低恢复时,就需要PVD 借助一下外部中断 退出停止模式
- 对于RTC闹钟 来说,有时候为了省电,RTC定一个闹钟之后,STM32会进入停止模式 ,等到闹钟响的时候再唤醒,这也需要借助外部中断
- 还有USB唤醒、以太网唤醒,也都是类似的作用
当然我们本节主要学引脚的外部中断,这四个蹭网的知道一下就行。
最后外部中断的触发响应方式 可以是中断响应 和事件响应
- 中断响应 就是申请中断,让CPU执行中断函数
- 事件响应 是额外功能。当外部中断检测到引脚电平变化时,正常的流程是选择触发中断,但在STM32中,也可以选择触发一个事件,如果选择触发事件,那外部中断的信号就不会通向CPU了,而是通向其他外设,用来触发其他外设的操作,比如触发ADC转换 、触发DMA(Direct Memory Access)等
- 总结一下
-
- 中断响应就是外设把 CPU 叫醒,让 CPU 来处理。
-
- 事件响应就是外设之间互相通知,不麻烦 CPU。
接下来我们就来看一下外部中断的基本结构体吧
EXTI基本结构

这个图就是外部中断的整体结构图
- 首先最左边,是GPIO口的外设,比如GPIOA、GPIOB、GPIOC 等等,每个GPIO外设有16个引脚,所以进来16根线。我们刚才说到,EXTI模块只有16个GPIO的通道,但这里每个GPIO外设都有16个引脚,如果每个引脚都占用一个通道,那EXTI的16个通道显然就不够用了
- 所以在这里会有一个AFIO(Asynchronous File I/O)(异步文件输入输出)中断引脚选择 的电路模块,这个AFIO 就是一个数据选择器 ,它可以在这前面3个GPIO外设的16个引脚里选择其中一个 连接到后面EXTI的通道里,所以在这前面说,相同的Pin不能同时触发中断 ,因为对于PA0、PB0、PC0 这些,通过AFIO选择 之后,只有其中一个能接到EXTI的通道0 上,同理PA1、PB1、PC1 这些,也只能有一个,连接到通道1 上,这就是所有GPIO口都能触发中断,但相同的Pin不能同时触发中断的原因
- 然后通过AFIO选择 之后的16个通道,就接到了EXTI边沿测试 及控制电路上,同时,下面这4个蹭网的外设也是并列接进来的。这些加起来,就组成了EXTI的20个输入信号

- 然后经过EXTI电路之后,分为了两种输出
- 其中,上面的这些接到了NVIC,是用来触发中断的。
- 这里注意一下,本来20路输入,应该有20路中断的输出,但是ST公司觉得这20个输出太多了,比较占用NVIC的通道资源,所以就把其中外部中断的9 ~ 5,和15 ~ 10给分到一个通道里。
- 也就是说,外部中断的9~5会触发同一个中断函数,15 ~ 10也会触发同一个中断函数
- 在编程的时候,我们在这两个中断函数里,需要再根据标志位 来区分到底是哪个中断进来的

- 然后下面这里,有20条输出线路到了其他外设,这就是用来触发其他外设操作的,也就是我们刚才说的事件响应

看完这个图,相信你对中断的整体流程就应该熟悉一些了吧
然后我们在具体地看一下这里AFIO和EXTI的内部电路
先看一下AFIO复用IO口
AFIO复用IO口

右边这个图,就是AFIO选择中断引脚的结构图,这个结构看上去就比较简单了,这里就是一系列数据选择器
- 第一个,输入是PA0、PB0、PC0等等,一直到PG0,尾号都是0,然后通过数据选择器,上面写的是配置这个寄存器的这些位,就可以决定选择哪一输入


然后下面的EXTI 1,等等,一直到EXTI 15都是数据选择器
接着我们看一下左边的文字

- AFIO主要用于引脚复用功能的选择和重定义,也就是数据选择器的作用
解释
AFIO (Alternate Function I/O )可以理解为 STM32 的引脚岗位分配中心 ,负责安排"一个引脚到底去干什么工作"。
它主要做两件事:
① 引脚复用功能选择(引脚到底干哪个工作?)
STM32 的每个引脚都很"多才多艺",能干很多活,比如:
- 当普通 GPIO
- 当 USART 的 TX/RX
- 当定时器 PWM
- 当 SPI/I2C 的数据线
- ......
AFIO 的任务之一,就是:
确认这个引脚应该使用哪一个外设功能。
也就是给引脚"定岗位"。
② 引脚重映射(要不要换个岗位/换办公室?)
有些外设的默认引脚你可能不喜欢(被占用了、线路不好布)。
这时候 AFIO 可以让外设的功能搬到另一组引脚。
就像:
"USART1 的 TX 默认在 PA9,要不要改到 PB6?"
这就是 AFIO 的 重映射(Remap)。
也就是给引脚"换个岗位位置"。
把所有句子合成一句最本质的话:
AFIO 就是 STM32 的引脚人事部,负责决定某个引脚用哪个功能(复用功能选择),以及是否把外设的功能换到另一组引脚(引脚重映射)。
接下来来到EXTI 的内部框图
EXTI 框图

- EXTI的右边,就是20根输入线,然后输入线首先进入边沿检测电路
- 在上面的上升沿寄存器 和下降沿寄存器 可以选择是上升沿触发 ,还是下降沿触发,或者两个都触发
- 接着触发信号就进入到这个或门的输入端了
-
- 简单介绍一下,这种弯弯 的符号是或门 ,它可以有多个输入,但只能有一个输出 ,执行的是或的逻辑,在输入端,只要有一个是高电平1,输出就是高电平,只有全部输入低电平0,输出才为0
-
- 然后这种带直边 的符号是与门 ,它同样也可以有多个输入,但只能有一个输出,执行的是与的逻辑,在输入端,只要有一个是低电平0,输出就是0,只有全部输入1,输出才为1
-
- 另外还有一种三角号加个圈 的是非门 ,只有一个输入,一个输出,输入1就输出0,输入0就输出1
-
- 还有一种就是数据选择器 ,它的符号是一个梯形 ,有多个输入,一个输出。在侧面有选择控制器 ,根据控制端的数据,从输入选择一个接到输出




以上就是常见的逻辑符号
我们继续接着前面的讲

在这里,硬件触发 和软件中断寄存器的值接到了这个或门上,也就是任意一个为1,或门就可以输出1
所以我们说,EXTI支持的触发方式是上升沿,下降沿,双边沿和软件触发
回到那个图,触发信号通过这个或门 之后,就兵分两路,上一路是触发中断 的,下一路是触发事件的
- 触发中断首先会置一个挂起寄存器 ,这相当于一个中断标志位 ,我们可以读取这个寄存器判断是哪个通道触发的中断,如果中断挂起寄存器 置1,它就会继续向左走,和中断屏蔽寄存器 共同进入一个与门 ,然后到达NVIC中断控制器 。这里的与门实际上就是开关的作用。因为对于与门来说,1与上任意的数x,等于这个任意的数x;0与上任意的数x,等于这个任意的数x
- 这就相当于,中断屏蔽寄存器给1,那另一个输入就是直接输出,也就是允许中断。中断屏蔽寄存器给0,那另一个输入无论是什么,输出都是0,相当于屏蔽了这个中断
- 下面是具体流程
-
中断发生 -> 挂起寄存器置位
- 当某个中断源(如一个GPIO引脚、一个定时器)满足条件时,硬件会自动将对应的中断挂起寄存器 位置
1。 - 这就像一个信号旗被举了起来,表示"我这里有事件需要处理!"。这个标志位会一直保持,直到被软件清除。
- 当某个中断源(如一个GPIO引脚、一个定时器)满足条件时,硬件会自动将对应的中断挂起寄存器 位置
-
权限检查 -> 与门逻辑
- 这个信号旗(挂起位)和中断屏蔽寄存器(也叫中断使能寄存器)的对应位一起送入一个逻辑"与门"。
- 中断屏蔽寄存器 的作用就是所谓的开关 。
- 屏蔽位 = 1(开启) :
1 & 挂起位 = 挂起位。此时,中断请求被原样输出,得以继续向前传递。相当于开关打开,信号畅通。 - 屏蔽位 = 0(关闭) :
0 & 挂起位 = 0。此时,无论挂起位是什么,输出都是0。中断请求被"屏蔽"或"阻塞",无法传递到下一级。相当于开关关闭,信号被阻断。
- 屏蔽位 = 1(开启) :
-
上报中枢 -> NVIC
- 所有通过了"与门"检查的中断请求,会汇集到NVIC(嵌套向量中断控制器)。
- NVIC 是Cortex-M 内核的中断管理中枢,它负责:
- 优先级仲裁:如果多个中断同时发生,NVIC会根据预设的优先级来决定先处理哪个。
- 中断嵌套:允许高优先级中断打断正在执行的低优先级中断。
- 触发CPU:最终,NVIC会向CPU核心发出中断信号,告诉它:"有一个重要任务需要你马上处理!"
-
CPU响应 -> 执行服务函数
- CPU在满足条件(如没有更高级别的中断正在执行、中断全局使能打开)时,会保存当前现场,然后跳转到对应的中断服务函数 去执行代码。
- 在中断服务函数 中,程序员通常需要手动清除挂起位,以表示"这个中断我已经处理完了"。如果不清除,中断函数一退出,这个"信号旗"还在,NVIC会认为中断再次发生,导致CPU不断地重复进入该中断。
总结与类比
我们可以用一个非常贴切的日常比喻来总结:
- 中断源 : 像是公司里各个部门的门铃按钮。
- 挂起寄存器 : 每个门铃按钮上自带的红色指示灯。按钮被按下,灯就亮,表示有人呼叫。即使手松开了,灯也一直亮,直到有人(软件)来把它按灭。
- 中断屏蔽寄存器: 每个部门经理桌上的一个"免打扰"开关。当经理不想被打断时,就把开关关上。此时,即使门外有人按铃(灯亮了),经理也听不到铃声。
- 与门 : 连接"免打扰开关"和"门铃指示灯"的电路。
- NVIC : 公司的前台总机。它接收所有没有被"免打扰"屏蔽的铃声,并判断哪个部门的呼叫最紧急,然后转接给CEO。
- CPU : CEO。他最终响应总机转接过来的呼叫,去处理具体事务。
- 中断服务函数 : CEO为了处理这个呼叫所需要执行的具体工作流程。工作完成后,他需要去把那个门铃的指示灯按灭(清除挂起位)。

接着看一下下一路事件的输出部分
- 首先也是一个事件屏蔽寄存器 进行开关控制 ,最后通过一个脉冲发生器 ,到其他外设,这个脉冲发射器 就是给一个电平脉冲,用来触发其他外设的动作

然后这个框图剩下的还有
- 这些画一个斜线写着20,表示的就是,这是20根线,代表20个通道
-上面这些就是外设接口 和APB总线 ,我们可以通过总线访问这些寄存器

到这里,有关中断系统 、NVIC中断寄存器 和EXTI外部中断的内容就讲完了
最后看一下本节课配合外部中断,我们所使用的硬件模块
对于外部中断 来说,我们刚学习完它的原理和结构,那到底什么样的设备需要用到外部中断 呢?使用外部中断有什么好处呢?
up主在这里大概总结了使用外部中断模块的特性
- 对于STM32来说,想要获取的信号是外部驱动的很快的突发信号 ,比如旋转编码器的输出信号,我可能很久都不会拧它,这时不需要STM32做任何事;但是我一拧它,就会有很多脉冲波形需要STM32接收。
- 这个信号是突发 的,STM32不知道什么时候会来;同时它是外部驱动 的,STM32只能被动读取 ;最后这个信号非常快 ,STM32稍微晚一点来读取,就会错过 很多波形。所以对于这种情况来说,就可以考虑使用STM32的外部中断 了。有脉冲过来,STM32立即进入中断函数处理;没有脉冲的时候,STM32就专心做其他事情
- 另外还有,比如红外遥控接收头 的输出,接收到遥控数据之后,它会输出一段波形,这个波形转瞬即逝,并且不会等你,所以就需要我们用外部中断来读取
- 虽然还有按键,虽然它的动作也是外部驱动的突发事件 ,但up主说并不推荐 用外部中断来读取按键。因为用外部中断不好处理按键抖动 和松手检测的问题。
- 对于按键来说,它的输出波形也不是转瞬即逝 的。要求不高的话可以在主程序中循环读取 。如果不想用主循环读取的话,可以考虑一下定时器中断读取 的方式,这样既可以做到后台读取按键值、不阻塞主程序 ,也可以很好地处理按键抖动和松手检测的问题
以上是外部中断的应用场景,接下来看一下编码器介绍。
旋转编码器

- 先看一下
第一个图
,它是一种最简单的编码器样式了,这里使用的也是对射式红外传感器 来测速的。为了测速,还需要配合一个这样的光栅编码盘 。当这个编码盘 转动时,红外传感器 的红外光就会出现遮挡、透过、遮挡、透过这样的现象,对应模块输出的电平就是高低电平交替的方波。
- 这个方波的个数表示了转过的角度,方波的频率 表示转速 。那我们就可以用外部中断 来捕获这个方波的边沿 ,以此判断位置和速度 。不过这个模块只有一路输出 ,正转反转输出波形没法区分 ,所以这种测速方法只能测位置和速度 ,不能测量旋转方向
- 那为了进一步测量方向,我们就可以用后面的几种编码器

第二个图片
就是我们套件里的旋转编码器了,左边是它的外观,右边是它的内部拆解结构
- 可以看到内部是用金属触点来进行通断的,所以它是一种机械触点式编码器。这里左右是两部分开关触点

- 其中内侧的这两根细的触点,都是和中间这个引脚连接的,像这样

- 外侧的触点,左边的接在这个引脚上,右边的接在这个引脚。这是这些触点的连接方式
- 中间这个圆的金属片是一个按键,我们这个旋转编码器的轴是可以按下去的

- 这个按键的两根线,就在上面引出来了
- 按键的轴按下,上面两根线短路;松手,上面两根线断开。就是个普通按键

- 再看一下编码盘
- 它也是一系列像光栅一样的东西,只不过这是金属触点,在旋转时,一次接通和断开两边的触点。
- 并且还有个关键的部分是,这个金属盘的位置是经过设计的。它能让两侧触点的通断产生一个90°的相位差(这里的设计指,金属盘上的触点不是轴对称的,旋转的时候就会先后碰到电路板上的左右触电)


- 最终配合一下外部电路,这个编码器的两个输出就会输出这样的波形。当正转时,左边的引脚,就是A相引脚 ,输出一个方波波形 ;同时,右侧的引脚,就是B相引脚 ,输出一个和它**相位相差90°**的波形

- 比如正向旋转时,B相输出是滞后90°的;反转时,B相输出的波形就会提前90°。这样正转和反转就可以区分开了
这种相位相差90°的波形就叫正交波形。
- 带正交波形信号输出的编码器,是可以用来测方向的。这就是单相输出和两相正交输出的区别
- 当然还有的编码器不是输出正交波形。而是一个引脚输出方波信号代表转速,另一个输出高低电平代表旋转方向。
接着看
第三个图

这种是直接附在电机后面的编码器,这种是霍尔传感器形式编码器 ,中间是一个圆形磁铁 ,边上有两个位置错开的霍尔传感器 。当磁铁旋转时,通过霍尔传感器 ,就可以输出正交的方波信号
最后一个

- 这是一个独立的编码器元件了,它的输入轴转动时,输出就会有波形,这个也是可以测速和测方向的,具体用法再看相应的手册
图二的编码器一般是用来调节的,比如音响调节音量 这样的用途。因为它是触点接触的 形式,所以不适合电机这种高速旋转 的地方。另外几种都是非接触 的形式,可以用于电机测速,电机测速在电机驱动的应用中还是非常常见的。
我们本节就用这种旋转编码器模块来学习一下,当然我们本节先学习一下外部中断读取编码器计次数据 的用法。以后我们学了定时器 ,还会再来看一下编码器测速的用途的
旋转编码器的硬件电路
- 这里左边是模块的电路图,这个图里中间这个就是旋转编码器

- 上面按键的两根线,这个模块并没有使用,是悬空的

- 下面的这里就是编码器内部的两个触点,旋转轴旋转时,这两个触点以相位相差90度的方式交替导通。因为这只是个开关信号,所以要配合外围电路才能输出高低电平。

- 看一下左边,这里接了一个10k的上拉电阻,默认没旋转的情况下,这个点被上拉为高电平。
- 当旋转时,内部这里触点导通,那这个点就直接被拉低到GND了,再通过R3口输出,A端口就是低电平了
- 之后这个R3是一个输出限流电阻 ,它是为了防止模块引脚电流过大的。这个C1是输出滤波电容,可以防止一些输出信号抖动

- 右边这一部分电路和左边的也是一模一样的,它的输出接到了B端口上。

- 最后,中间这里可以看到,这个模块的C端口,就直接接到了GND。
那这些就是这个模块的电路图
然后右边我们在使用这个模块的时候,接线就很简单了,上面的VCC、GND 接电源,下面的A相输出 和B相输出接到STM32的两个引脚上,比如PB0和PB1,注意引脚的GPIO_Pin编号不要一样就行了,中间的C引脚,就是GND,我们暂时不用
PPT的内容到此结束
最后大家可以跟着b站up主@江协科技 过一遍手册
下节预告:对射式红外传感器计次&旋转编码器计次