STM32-EXIT外部中断(七)

EXIT外部中断

中断系统是管理和执行中断的逻辑结构啊。外部中断是众多能产生中断的外设之一,所以本节我们就借助外部中断来学习一下中断系统,在以后学其他外设的时候,也是会经常和中断打交道的啊。那我们先来了解一下中断的概念啊。

中断响应和事件响应。中断响应好理解啊,就是申请中断,让 CPU 执行中断函数。那事件响应是什么意思呢?这个其实是 STM32 对外部中断增加的一种额外的功能啊。当外部中断检测到引脚电平变化时,正常的流程是选择触发中断,但在 STM32 中也可以选择触发一个事件。如果选择触发事件,那外部中断的信号就不会通向 CPU 了,而是通向其他外设,用来触发其他外设的操作,比如触发 ADC 转换啊,触发 DMA 等。所以总结一下就是,中断响应是正常的流程,引脚电平触发中断。事件响应不会触发中断,而是触发别的外设操作,属于外设之间的联合工作。

接着右边这个图就是 STM32 里的中断资源,这里看一下啊。上面这些灰色的是内核的中断,比如第一个复位中断,当产生复位事件时,程序就会自动执行复位中断函数,也就是我们复位后程序开始执行的位置。然后 NMI 不可屏蔽中断,硬件失效、存储管理、总线错误、错误应用等等,这些都是内核里面的啊。一般这些中断都比较高层,我们看上去也挺难理解的,但是这些中断我们一般用不到,所以了解一下即可。

然后下面这些不是灰色的部分,就是 STM32 外设的中断了。比如第一个窗口看门狗,这个是用来监测程序运行状态的中断。那比如你程序卡死了,没有及时喂狗,窗口看门狗就会申请中断,让你的程序跳到窗口看门狗的中断程序里。那你在中断程序里就可以进行一些错误检查,看看出现什么问题了。

然后 PVD 电源电压监测,如果你供电电压不足, PVD 电路就会申请中断,你在中断里就知道现在供电不足,是不是电池没电了,赶紧保存一下重要数据啊。

接着下面这些也都是类似的功能啊,外设电路检测到有什么异常或者事件,需要提示一下 CPU 的时候,它就可以申请中断,让程序跳到对应的中断函数里运行一次,用来处理这个异常或事件。

那下面这个 EXTI0 到 EXTI4 然后下面的 EXTI 9~5 和这右边的 EXTI 15~10 就是我们本节要学的外部中断对应的中断资源了。

然后这个表右边这里还有个中断的地址,这个地址是干什么的呢?这个是因为我们程序中的中断函数啊,它的地址是由编译器来分配的,是不固定的 啊。但是我们的中断跳转由于硬件的限制,只能跳到固定的地址执行程序 。所以为了能让硬件跳转到一个不固定的中断函数里,这里就需要在内存中定义一个地址的列表啊,这个列表第中断发生后就跳到这个固定位置,然后在这个固定位置由编译器再加上一条跳转到中断函数的代码,这样中断跳转就可以跳到任意位置了

这个中断地址的列表就叫中断向量表,相当于中断跳转的一个跳板啊。不过我们用 C 语言编程的话是不需要管这个中断向量表的,因为编译器都帮我们做好了,所以我们还是很省心的。

然后接下来我们来看一下 NVIC 的基本结构。

看一下 NVIC 的基本结构。这个 NVIC 的名字叫做嵌套中断向量控制器。在 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 个优先级

为了把这个优先级再区分为抢占优先级和响应优先级,就需要对这 16 个优先级进行分组了。我们看一下 PPT 的第一句, NVIC 的中断优先级由优先级寄存器的 4 位决定,这里 4 位二进制可以表示 0~15 的数,对应 16 个优先级啊,这个优先级的数是值越小优先级越高。0 就是最高优先级。

然后呢这 4 位可以进行切分为高 N 位的抢占优先级和低 4 减 N 位的响应优先级。然后下面这一句,抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队。这个通过刚才的例子应该就好理解了吧。

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

然后看一下下面的这个表,因为优先级总共是四位,所以就有 04 13 22 31 40 这五种分组方式。分组 0 就是 0 位的抢占等级,取值只能为 0 啊。4 位的响应等级,取值可以是 0~15。分组一是一位的抢占等级取值是 0~1,3 位的响应等级取值是 0~7 啊。然后分组 1234 都是按照这个规矩来分配的,大家自己看一下啊。这个分组方式在程序中是我们自己来选择的哈。选好分组方式之后,我们在配置优先级的时候,就要注意抢占优先级和响应优先级的取值范围了,不要超出这个表里规定的取值范围。

{

}

那接下来我们就来看一下外部中断的基本结构吧。这个图就是外部中断的整体结构图。首先最左边是 GPIO 口的外设,比如 GPIOA,GPIOB,GPIOC 等。每个 GPIO 外设有 16 个引脚,所以进来 16 根线。那我们刚才这里说了, EXTI 模块只有 16 个 GPIO 的通道,但这里每个 GPIO 外设都有 16 个引脚。如果每个引脚占用一个通道,那 EXTI 的 16 个通道显然就不够用了。所以在这里会有一个AFIO 中断引脚选择的电路模块 。这个 AFIO 就是一个数据选择器啊,它可以在在这前面三个 GPIO 外设的 16 个引脚里选择其中一个连接到后面的 EXTI 的通道里。所以这前面说相同的 pin 不能同时触发中断。因为对于 PA0 PB0 PC0 这些通过 AFLIO选择之后只有其中一个能接到 EXTI 的通道 0 上。同理 PA1 PB1 PC1 这些也只能有一个接到通道 1 上。这就是所有 GPI O 口都能触发中断,但相同的 pin 不能同时触发中断的原因。

然后通过 AFIO 选择之后的 16 个通道,就接到了 EXTI 边缘检测及控制电路上。同时下面这 4 个蹭网的外设也是并列进来的啊,这些加起来就组成了 EXTI 的 20 个输入信号,然后经过 EXTI 电路之后分为了两种输出,其中上面的这些接到了 NVIC,就是用来触发中断的。

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

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

然后我们再具体的看一下这里 AFO 和 EXTI 的内部电路。那先看一下 AFIO 复用 IO 口。

对外部中断来说,我们刚学习完它的原理和结构。那到底什么样的设备需要用到外部中断呢?使用外部中断有什么好处呢?

在这里大概总结了使用外部中断模块的特性,就是对于 STM32 来说,想要获取的信号是外部驱动的,很快的突发信号。比如旋转编码器的输出信号啊,我可能很久都不会拧它,这时不需要 STM32 做任何事,但是我一拧它,就会有很多脉冲波形需要 STM32 接收,这个信号是突发的哈, STM32 不知道什么时候会来,同时它是外外部驱动的, STM32 只能被动读取。最后这个信号非常快, STM32 稍微晚来一点读取,就会错过很多波形。所以对于这种情况来说,就可以考虑使用 STM32 的外部中断了。有脉冲过来, STM32 立即进入中断函数处理,没有脉冲的时候, STM32 就专心做其他事情。

另外还有啊,比如红外遥控接收头的输出,接收到遥控数据之后,它会输出一段波形哈。这个波形转瞬即逝,并且不会等你,所以就需要我们用外部中断来读取。

最后还有按键啊,虽然它的动作也是外部驱动的突发事件,但我并不推荐使用外部中断来读取按键,因为外部中断不好处理按键抖动和松手检测的问题啊。对于按键来说,它的输出波形也不是转瞬即逝的哈,所以要求不高的话,可以在主程序中循环读取。如果不想用主循环读取的话,可以考虑一下定时器中断读取的方式。这样既可以做到后台读取按键值,不阻塞主程序,也可以很好的处理按键抖动和松手检测的问题,这感兴趣的话可以了解一下。

来看一下这个编码器介绍啊。本节程序还用到了对射式红外传感器,这个模块我们之前就讲过,用法也是比较简单的啊,这里就不再讲了

我们直接看一下旋转编码器。首先旋转编码器

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

那为了进一步测量方向,我们就可以用后面的几种编码器。第二个图片就是我们套件里的旋转编码器了,左边是它的外观,右边是它的内部拆解图。结构。可以看到啊,它内部是用金属触点来进行通断的,所以它是一种机械触点式编码器。这里左右是两部分开关触点,其中内侧的这两根细的触点啊都是和中间的这个引脚连接的。外侧的触点左边的接在这个引脚。右边的接在这个引脚,这就是这些触点的连接方式啊。然后中间这个圆的金属片是一个按键,我们这个旋转编码器的轴是可以按下去的,这个按键的两根线就在上面引出来了。按键的轴按下,上面两根线短路,松手上面两根线断开,就是个普通按键啊。然后再看一下编码盘,它也是一系列像光栅一样的东西啊,只不过这是金属触点,在旋转时依次接通和断开两边的触点

并且还有个关键的部分是,这个金属盘的位置是经过设计的啊。它能让你两侧触点的通断产生一个 90 度的相位差。最终配合下外部电路,这个编码器的两个输出就会输出这样的波形啊。当正转时,左边的引脚就是 A 相引脚,输出一个方波信号。同时右侧的引脚就是 B 相引脚,输出一个和它相位相差 90 度的波形。那比如正向旋转时, B 相输出是滞后 90 度的,就是这样的。

反向旋转时, A 相还是方波信号啊。那 B 相就会提前 90 度,就这样的。这样正转和反转就可以区分开了。这种相位相差 90 度的波形就叫正交波形。带正交波形信号输出的编码器是可以用来测方向的啊。这就是单向输出和两向正交输出的区别。当然还有的编码器不是输出正交波形啊,而是一个引脚输出方波信号代表转速,另一个输出高低电平代表旋转方向。这种不是正交输出的编码器,但也是可以测量方向的,这个了解一下。

然后接着看一下第三个图,这种是直接附在电机后面的编码器啊,这种是霍尔传感器形式的编码器。器,中间是一个圆形磁铁,边上有两个位置错开的霍尔传感器。当磁铁旋转时,通过霍尔传感器就可以输出正交的方波信号。那最后一个就是独立的编码器元件,它的输入轴转动时,输出就会有波形,这个也是可以测速和测方向的啊,具体用法再看相应的手册。

当然第二个图里的这个编码器一般是用来进行调节的啊,比如音响调节音量这样的用途。因为它是触点接触的形式,所以不适合电机这种高速旋转的地方。

另外几种都是非接触的形式啊,可以用于电机测速电机测速在电机驱动的应用中还是非常常见的啊。我们本节就用这种旋转编码器模块来学习一下。当然我们本节先学习一下外部中断读取编码器计次数据的用法。以后我们学了定时器,还会再来看一下编码器测速的用途的啊。

这个旋转编码器的硬件电路啊,这里左边这个是模块的电路图,这个图里中间这个就是旋转编码器,上面按键的两根线这个模块并没有使用啊,是悬空的。

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

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

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

最后中间这里可以看到这个模块的 C 端口就直接接到了 GND。 那这些就是这个模块的电路图啊。

然后右边我们在使用这个模块的时候,接线就很简单了啊。上面的 VCC 接地接电源,下面的 A 相输出和 B 相输出接到 STM32 的两个引脚上,比如 PB0 和 PB1。注意引脚的 GPIO 编号不一样就行了。然后中间的 C 引脚就是 GND, 我们暂时不用。

相关推荐
2301_780943842 小时前
第一阶段:基础知识准备
单片机
Deitymoon2 小时前
STM32——蜂鸣器
stm32·单片机·嵌入式硬件
BT-BOX2 小时前
STM32物联网云监控智能报警器(MQ-2烟雾/火焰/DHT11温湿度/红外)
stm32·嵌入式硬件·物联网
光子物联单片机2 小时前
STM32传感器模块编程实践(二十)ESP8266实现MQTT连接OneNET上传温湿度数据
c语言·stm32·单片机·嵌入式硬件·mqtt
三品吉他手会点灯2 小时前
STM32F103 学习笔记-21-串口通信(第4节)—串口发送和接收代码讲解(下)
笔记·stm32·单片机·嵌入式硬件·学习
时空自由民.2 小时前
嵌入式-CI(Continuous Integration)介绍
linux·单片机·ci/cd
LingLong_roar12 小时前
STM32 启动流程
stm32·单片机·嵌入式硬件
weixin_5206498712 小时前
短距离硬件通信
单片机·嵌入式硬件
振南的单片机世界15 小时前
HAL慢、ODR中、BSRR快:GPIO翻转速度的三重境界
单片机·嵌入式硬件