五、EXTI外部中断

一、外部中断原理

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就会显示错误。

在实现功能的时候,可以像我这样,在中断里操作变量或者标志位,当中断返回时,我再对这个变量进行显示和操作。这样既能保证中断函数的简短快速,又能保证不产生冲突的硬件操作。

在其它地方,大家也都可以多用用变量或者标志位,来减少代码之间的耦合性,让各部分代码相互独立,仅使用变量、标志位或者函数作为接口,这样能让程序更加清晰,代码更加强健。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值