0502STM32EXTI中断项目&代码实现

对射式红外传感器&旋转编码器计次

一般一个模块要写的第一个就是初始化函数,把模块要用的资源配置好

配置外部中断的步骤:

1.配置RCC,把我们涉及到的外设的时钟都打开
2.配置GPIO,选择端口为输入模式
3.配置AFIO,选择我们用的这一路GPIO,连接到后面的EXTI
4.配置EXTI,选择中断或事件响应
5.配置NVIC,给中断选择一个合适的优先级
最后,通过NVIC,外部中断信号就能进入CPU了
CPU收到中断信号,跳转到中断函数里执行中断函数

EXTI是一个独立外设,按理需要开启时钟,但是寄存器里面却没有EXTI时钟的控制位,(论推测可能是和EXTI唤醒有关,或者其他的一些电路设计上的考虑)
另外NVIC也不需要开启时钟,因为NVIC是内核的外设,内核外设都不需要开启时钟,和CPU一起的,在内核。

而RCC管的都是内核外的外设,

AFIO相关函数&GPIO的一个函数

AFIO没有专门分配库函数文件,是和GPIO在一个文件里面

在这里插入图片描述

GPIO_ADIODeInit()复位AFIO外设,调用此函数,AFIO外设的配置就会全部清除
GPIO_PinLockConfig 锁定GPIO配置,调用此函数,参数指定某个引脚,引脚配置就锁定,防止意外更改

GPIO_EventOutputConfig、GPIO_EventOutputCmd是用来配置AFIO的事件输出功能的,用的不多

GPIO_PinRemapConfig 可以用来进行引脚重映射,第一个参数可以选择要重映射的方式,第二个参数是新的状态
GPIO_EXTILineConfig 本节需要用到的,可以配置AFIO的数据选择器,来选择我们想要的中断引脚
GPIO_ETH_MediaInterfaceConfig 和以太网相关,这个芯片没有以太网外设,用不到

EXTI相关函数

在这里插入图片描述
EXTI_DeInit 可以把EXTI的配置都清除,恢复成上电默认的状态
EXTI_Init 可以根据结构体里的参数配置EXTI外设,初始化主要用的这个函数,使用方法和GPIO_Init是一样的,
EXTI_StructInit 可以把参数传递的结构体变量赋一个默认值
这三个函数,基本所有的外设都有,就像是库函数的模板函数一样,基本每个外设都需要这些类型的函数,会用一个之后,再见到这种函数,就很容易上手。为什么要用结构体来初始化模块,还得定义结构体,结构体赋值,然后再传递结构体的地址,是因为其他外设也都一样,一个套路,而且结构体可以看到参数的名字,参数也都可以复制粘贴,根本不用查看寄存器,随便选参数就配置好了。

EXTI_GenerateSWInterrupt 用来软件触发外部中断,调用这个函数,参数给一个指定的中断线,就能软件触发一次外部中断,如果程序中需要用到这个功能,可以使用这个函数,如果程序中只需要外部引脚触发中断,那就不需要用这个函数了。

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
void EXTI_ClearFlag(uint32_t EXTI_Line);
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
这四个函数也是库函数的模板函数,很多模块都有着四个函数,因为外设运行过程中,会产生一些状态标志位,比如外部中断来了,会有一个挂起寄存器置了一个标志位,对于串口收到数据,会置标志位,定时器时间到,也会置标志位。这些标志位都是放在状态寄存器,当程序想要看这些标志位时,可以用到这4个函数

GetFlagStatus可以获取指定的标志位是否被置1了
ClearFlag可以对置1的标志位进行清除

对于标志位,有的比较紧急,在置标志位后会触发中断,在中断函数里,如果想查看标志位和清除标志位,那用下面两个函数,
GetITStatus 获取中断标志位是否被置1了、
ClearITPendingBit 清除中断挂起中断位

总结:如果想再主程序里面查看和清除标志位,就用上面两个函数
如果想在中断函数里查看和清除标志位,就用下面两个函数。
本质上,四个函数都是对状态寄存器的读写,只不过下面的两个函数只能读写与中断有关的标志位,并且对中断是否允许做出了判断,而上面的连个函数只是一般的读写标志位,没有额外的处理,能不能触发中断的标志位都能读取。
库函数对这两种场景,区分了两类读写函数,实在随便用也问题不大。

代码

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
此处注释写错了,所以才有有很多的版本来修订

NVIC中断函数

在这里插入图片描述

1.用来中断分组的,参数是中断分组的方式
2.根据结构体里指定的参数初始化NVIC

3.设置中断向量表
4.系统低功耗配置
3.4函数用的不多,可以先不看

在这里插入图片描述
For the complete STM32 Devices IRQ Channels list, please refer to stm32f10x.h file
对于完成的STM32中断通道列表,请参考stm32f10x.h文件,这个意思是IRQn_Type的定义不在这个文件,要到stm32f10x.h里去找。

在这里插入图片描述
可以看到这里有很多的中断通道,因为这个库函数可以兼容所有的F1系列芯片,但是不同的芯片中断列表是不一样的,所以有很多条件编译,用来选择所使用芯片的中断通道列表。

启动文件里的中断函数名字

在STM32中,中断函数的名字都是固定的,每个中断通道都对应一个中断函数,中断函数的名字可以参考启动文件。

在这里插入图片描述
可以看到定义了中断向量表,这里面以IRQ结尾的字符串就是中断函数的名字,EXTI15_10_IRQHandler就是EXTI15_10的中断函数
在这里插入图片描述

中断函数都无参无返回值。在中断函数里,一般都是先进行一个中断标志位的判断,确保使我们想要的中断源触发的这个函数,因为这个函数EXTI10-15都能进来,所以要先判断是不是想要的EXTI14进来了

中断编程的建议:

1.在中断函数里,最好不要执行耗时过长的代码,中断函数要简短快速,别刚进中断就执行一个Delay多少毫秒这样的代码,因为中断是处理一个突发的事情,如果为了一个突发的事情待在中断里出不来了,那主程序就会收到严重的阻塞
2.不要在中断函数和主函数调用相同的函数或者操作同一硬件,尤其是硬件相关函数,比如OLED显示函数,如果既在主函数里调用LED,又在中断调用OLED,OLED就会显示错误。因为可能在主程序中,OLED刚显示一半,进入中断后,还是OLED显示函数,那OLED就可能挪到其他地方显示了,当中断结束之后,需要继续原来的显示就出问题了。因为硬件的显示位置被挪到其他地方了,所以再回来时,继续显示的内容就会跟着跑到其他地方去。
虽然在中断进入和退出时,会有保护现场和恢复现场,但这只能保证CPU程序能正常返回不出问题,对于外部硬件的话,并没有在进入中断时进行现场保护。为了避免这样可能存在的问题,就最好不要在主程序和中断程序里,操作可能产生冲突的硬件。

可以在中断里操作变量或者标志位,当中断返回时,再对这个变量进行显示和操作,这样既能保证中断函数的简短快捷,又能保证不产生冲突的硬件操作。这就是中断程序设计的注意事项。

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

  • 30
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值