一、外部中断原理
5-1
中断系统是管理和执行中断的逻辑结构,外部中断是众多能产生中断的外设之一。
使用中断系统,能够极大地提高程序的效率。有了中断系统之后,主程序就可以放心执行其它事情,有中断的时候再去处理。

一般中断程序都是在一个子函数里的,这个函数不需要我们调用,当中断来临时,由硬件自动调用这个函数。

中断通道就是中断源的意思。
NVIC就是STM32中用来管理中断、分配优先级的。
09:24各中断讲解

NVIC:嵌套中断向量控制器,在STM32中,它是用来统一分配中断优先级和管理中断的。NVIC是一个内核外设,是CPU的小助手。
图中/n表示:一个外设可能会同时占用多个中断通道,所以这里有n条线。
NVIC只有一个输出口,NVIC根据每个中断的优先级分配中断的先后顺序。
CPU是医生,各个中断是病人,NVIC是叫号系统。

响应优先级:看病时可以插队到最前面提前看病
抢占优先级:不等上一个人看病结束,直接冲进屋,打断上一个人看病,让医生先给自己看,即中断嵌套。

1.端口GPIO_pin一样的,如PA1、PB1、PC1,只能选一个作为中断引脚。所以你如果有多个中断引脚,要选择不同Pin的引脚,比如PA9和PB15。
3.中断响应是正常的流程,引脚电平变化触发中断。
事件响应不会触发中断,而是触发别的外设操作,属于外设之间的联合工作。

这个AFIO就是一个数据选择器,它可以在这前面3个GPIO外设的16个引脚里选择其中一个连接到后面EXTI的通道里。所以这前面说,相同的Pin不能同时触发中断,因为对于PA0、PB0、PC0来说,通过AFIO选择之后,只有一个能接到EXTI的通道0上。
然后通过AFIO选择之后的16个通道,就接到了EXTl边沿检测及控制电路上,同时,下面这4个蹭网的外设也是并列接进来的,这些加起来,就组成了EXTl的20个输入信号。
然后经过EXTI电路之后,分为了两种输出:其中,上面的这些,接到了NVIC,是用来触发中断的(本来是20个通道,但是外部中断的9~5,和15~10,给分到一个通道里了,也就是说,外部中断的9~5会触发同一个中断函数,15~10也会触发同一个中断函数,在编程的时候,我们在这两个中断函数里,需要再根据标志位来区分到底是哪个中断进来的)。
然后,下面这里,有20条输出线路到了其它外设,这就是用来触发其它外设操作的,也就是我们刚才说的事件响应。




二、外部中断程序
5-2


外部中断配置流程:
概述:
1.配置RCC,把我们这里涉及的外设的时钟都打开,不打开时钟,外设是没法工作的。
2.配置GPIO,选择端口为输入模式。
3.配置AFIO,选择我们用的这一路GPIO,连接到后面的EXTI。
4.配置EXTI,选择边沿触发方式,比如上升沿、下降沿或者双边沿,还有选择触发响应方式,可以选择中断响应和事件响应,一般都是中断响应。
5.配置NVIC,给我们这个中断选择一个合适的优先级。
最后,通过NVIC,外部中断信号就能进入CPU了。这样CPU才能收到中断信号,才能跳转到中断函数里执行中断程序。
配置代码:
1.配置RCC

EXTI和NVIC这两个外设的时钟是一直都打开着的,不需要我们再开启时钟了。
NVIC不需要开启时钟,是因为NVIC是内核的外设,内核的外设都是不需要开启时钟的。EXTI原因不明。
2.配置GPIO

3.配置AFIO




AFIO的库函数是和GPIO在一个文件里的。
GPIO_EXTILineConfig:调用这个函数就可以配置AFIO的数据选择器,来选择我们想要的中断引脚。这个函数虽然是GPIO开头,但实际上里面是操作的AFIO的寄存器,所以这个函数实际上是AFIO的函数。
4.配置EXTI

调用这个函数,可以把参数传递的结构体变量赋一个默认值

5.配置NVIC


分组方式整个模块只能用一种。

在STM32中,中断函数的名字都是固定的,每个中断通道都对应一个中断函数,中断函数的名字我们可以参考一下启动文件里定义的中断向量表,这里面以IRQHandler结尾的字符串就是中断函数的名字。


这就是中断函数的格式,中断函数都是无参无返回值的。中断函数的名字不要写错了,写错了就进不了中断了,最好是直接从启动文件复制过来,这样就不会有问题了。
中断程序结束后,一定要再调用一下清除中断标志位的函数。因为只要中断标志位置1了,程序就会跳转到中断函数,如果你不清除中断标志位,那它就会一直申请中断,这样程序就会不断响应中断,执行中断函数,那程序就卡死在中断函数里了,所以我们每次中断程序结束后,都应该清除一下中断标志位。

初始化函数放在头文件里声明一下,但这个中断函数就不用声明了,因为中断函数不需要调用,它是自动执行的。
旋转编码器:


num记录的之前的累计值,函数返回的是每次产生的变化值,所以num就会从0开始输出当前的位置。所以count每次变化前必须要清零,之前的变化已经给到num啦
不直接返回count主要是代码可移植性和封装的考虑 另外最好不要在主函数和中断函数里面操作同一个变量 有可能会出现未知bug(摘自评论,不完全正确)
一些中断编程的建议:
1.在中断函数里,最好不要执行耗时过长的代码。中断函数要简短快速,别刚进中断就执行一个Delay多少毫秒这样的代码。因为中断是处理突发的事情,如果你为了一个突发的事情待着中断里不出来了,那主程序就会受到严重的阻塞。
2.最好不要在中断函数和主函数调用相同的函数或者操作同一个硬件。尤其是硬件相关的函数,比如OLED显示函数。如果你既在主程序里调用OLED,又在中断里调用OLED,OLED就会显示错误。
在实现功能的时候,可以像我这样,在中断里操作变量或者标志位,当中断返回时,我再对这个变量进行显示和操作。这样既能保证中断函数的简短快速,又能保证不产生冲突的硬件操作。
在其它地方,大家也都可以多用用变量或者标志位,来减少代码之间的耦合性,让各部分代码相互独立,仅使用变量、标志位或者函数作为接口,这样能让程序更加清晰,代码更加强健。

1576

被折叠的 条评论
为什么被折叠?



