STM32单片机入门学习笔记——中断系统、外部中断

笔记整理自B站UP主江科大自化协教程《STM32入门教程-2023持续更新中》,所用单片机也为教程推荐单片机。

中断的定义

STM32单片机入门学习笔记——中断系统、外部中断_第1张图片

中断就是在正常主程序执行的某个时刻,发生了中断触发条件,比如对于外部中断来说,可以是引脚发生了跳变;对于定时器来说,可以是定时的时间到了;对于串口通信来说,可以是接收到了数据。

STM中断

68个可屏蔽中断通道(中断源),F1系列最多的中断数量,包含EXTI(外部中断)、TIM(定时器)、ADC(模数转换器)、USART(串口)、SPI通信、I2C通信、RTC实时时钟等多个外设

使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级。

STM32单片机入门学习笔记——中断系统、外部中断_第2张图片

内核的中断

Reset:复位中断,当产生复位事件时,程序就会自动执行复位中断函数

这些内核中断我们一般用不到

STM32单片机入门学习笔记——中断系统、外部中断_第3张图片

WWDG:Window Watchdog,窗口看门狗,用来监测程序运行状态的的中断,比如程序卡死了没有及时喂狗,窗口看门狗就会申请中断,让你的程序跳到窗口看门狗的中断程序里,在中断程序里就可以进行一些错误检查

PVD:电源电压监测,如果供电电压不足,PVD电路就会申请中断

STM32单片机入门学习笔记——中断系统、外部中断_第4张图片
STM32单片机入门学习笔记——中断系统、外部中断_第5张图片
STM32单片机入门学习笔记——中断系统、外部中断_第6张图片

EXTI0~EXTI4、EXTI9_5、EXTI15_10:外部中断对应的中断资源

程序中的中断函数地址是由编译器来分配的,是不固定的,中断跳转只能跳到固定的地址执行程序,所以为了能让硬件跳转到一个不固定的函数里,需要在内存中定义一个地址的列表,这个列表地址是固定的,中断发生后,就跳到这个固定位置,然后在这个固定位置由编译器再加上一条跳转到中断函数的代码,这样中断跳转就可以跳转到任意位置了。

中断地址的列表也叫中断向量表,相当于中断跳转的一个跳板

NVIC的基本结构

STM32单片机入门学习笔记——中断系统、外部中断_第7张图片

NVIC:Nested Vectored Interrupt Controller嵌套中断向量控制器,内核外设要在Cortex-M3编程手册找

它的作用前面提到过:统一分配中断优先级和管理中断

NVIC是内核外设,是CPU的“小助手”,NVIC可以看做是“医院的叫号系统”,CPU可以看做是“医生”,

NVIC优先级分组

抢占优先级和响应优先级的区别

还是病人叫号的这个例子,对于紧急的病人有两种形式的优先:一种是上一个病人在看病,外面排了很多病人,当上一个病人看完后,紧急的病人即使是后来的,也会最先进去看病,这种相当于插队的优先级就叫响应优先级;另一种,如果外面的病人更加紧急,并且此时有人在看病,那它可以不等上一个看完,直接进去让医生看,等它看完后,之前看病的人再继续,这种形式的优先就是中断嵌套,这种决定是不是可以中断嵌套的优先级就是抢占优先级

  • NVIC的中断优先级由优先级寄存器的4位(0~15对应16个优先级)决定,这个优先级的数值越小,优先级越高,0就是最高优先级。这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级

  • 抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号(前面表格里的序号,数值小的优先响应)排队

STM32单片机入门学习笔记——中断系统、外部中断_第8张图片

这个分组方式在程序中是我们自己来选择,选好分组后,在配置优先级的时候要注意抢占优先级和响应优先级的取值范围。

EXTI外部中断

  • Extern Interrupt

  • EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序(简单来说:引脚电平变化申请中断)

  • 支持的触发方式:上升沿/下降沿/双边沿/软件触发

  • 支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断(PA0和PB0不能同时用,端口GPIO_Pin一样的只能选一个作为中断引脚)

  • 通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒(20个中断线路)

外部中断有个功能就是从低功耗模式的停止模式下唤醒STM32,对于PVD电源电压监测,当电源从电压过低恢复时,就需要PVD借助一下外部中断退出停止模式;对于RTC闹钟,RTC定了一个闹钟之后,STM32会进入停止模式,等到闹钟响的时候再唤醒,这也需要借助外部中断。

  • 触发响应方式:中断响应/事件响应(中断响应:申请中断让CPU执行中断函数;事件响应:当外部中断检测到引脚电平变化时,不会触发中断,而是触发别的外设操作,比如触发ADC转换、触发DMA等,属于外设之间的联合工作)

EXTI基本结构

STM32单片机入门学习笔记——中断系统、外部中断_第9张图片

这张图也解释了前面提到的:所有GPIO口,但相同的Pin不能同时触发中断(会经过AFIO选择)

外部中断的9~5会触发同一个中断函数,15~10也会触发同一个中断函数,那我们可以根据标志位来区分到底是哪个中断进来了。

AFIO复用IO口

STM32单片机入门学习笔记——中断系统、外部中断_第10张图片
  • AFIO主要用于引脚复用功能的选择重定义

  • 在STM32中,AFIO主要完成两个任务:复用功能引脚重映射中断引脚选择

STM32单片机入门学习笔记——中断系统、外部中断_第11张图片

复用功能引脚重映射

EXTI框图

STM32单片机入门学习笔记——中断系统、外部中断_第12张图片

经过或门后兵分两路,一路触发中断,另一路触发事件

请求挂起寄存器:相当于中断的标志位,可以读取这个寄存器判断是哪个通道触发的中断

脉冲发生器:给一个电平脉冲,用来触发其他外设的动作

使用外部中断模块的特性

对于STM32来说,想要获取的信号是外部驱动的很快的突发信号(旋转编码器、红外接收头等等)

STM32单片机入门学习笔记——中断系统、外部中断_第13张图片

相位相差90度的波形,就是正交波形,带正交波形信号输出的编码器是可以用来测方向的

外部中断配置代码部分(以对射式红外传感器计次为例中断IO口为PB14)

第一步:配置RCC,把这里设计的外设时钟都打开

第二步:配置GPIO,选择端口为输入模式

第三步:配置AFIO,选择我们这一路用的GPIO

第四步:配置EXTI,选择边沿触发方式,比如上升沿、下降沿、双边沿,选择触发响应方式,比如中断响应、事件响应

第五步:配置NVIC,给中断选择一个合适的优先级

可以参考EXTI基本结构的图:

STM32单片机入门学习笔记——中断系统、外部中断_第14张图片

第一步——开启时钟

主体代码

EXTI和NVIC两个外设的时钟是一直都打开的,寄存器中没有EXTI时钟的控制位,RCC管的都是内核外的外设,RCC管不着NVIC

第二步——配置GPIO

模式选择

可以看STM32F10xxx参考手册(中文),8.1.11外设的GPIO配置

STM32单片机入门学习笔记——中断系统、外部中断_第15张图片

这里选择上拉输入,默认为高电平的输入方式

STM32单片机入门学习笔记——中断系统、外部中断_第16张图片

主体代码

第三步——配置AFIO

它的库函数和GPIO在一个文件里,stm32f10x_gpio.h

STM32单片机入门学习笔记——中断系统、外部中断_第17张图片

GPIO_AFIODeInit——用来复位AFIO外设,调用这个函数AFIO外设的配置就会全部清除

GPIO_PinLockConfig——用来锁定GPIO配置,调用这个函数参数指定某个引脚,那这个引脚的配置就会被锁定,防止意外更改

GPIO_EventOutputConfig、GPIO_EventOutputCmd——配置AFIO事件输出功能

GPIO_PinRemapConfig——可以用来进行引脚的重映射

GPIO_EXTILineConfig——调用这个函数,就可以配置AFIO的数据选择器,来选择我们想要的中断引脚

GPIO_ETH_MediaInterfaceConfig——和以外网有关

主体代码

代表连接PB14号口——第14个中断线路

第四步——配置EXTI

stm32f10x_exti.h

EXTI_DeInit——调用它可以把EXTI的配置都清除,恢复成上电默认的状态

EXTI_Init——配置EXTI外设,和GPIO配置类似

EXTI_StructInit——类似GPIO_Init

以上这三个函数基本所有的外设都有

EXTI_GenerateSWInterrupt——软件触发外部中断,调用这个函数参数给一个指定的中断线,就能软件触发一次这个外部中断

EXTI_GetFlagStatus——可以获取指定的标志位是否被置1

EXTI_ClearFlag——可以对置1的标志位进行清除

EXTI_GetITStatus、EXTI_ClearITPendingBit——在中断函数中查看和清除标志位

如果你想在主程序中查看和清除标志位,就用EXTI_GetFlagStatus、EXTI_ClearFlag;如果想在中断函数里查看和清除标志位,就用EXTI_GetITStatus、EXTI_ClearITPendingBit

STM32单片机入门学习笔记——中断系统、外部中断_第18张图片

主体代码

第五步——配置NVIC

misc.h文件

NVIC_PriorityGroupConfig——中断分组

NVIC_Init——初始化NVIC

NVIC_SetVectorTable——设置中断向量表

NVIC_SystemLPConfig——系统低功耗配置

pre-emption priority——先占优先级(抢占优先级)

subpriority——从占优先级(响应优先级)

中断分组

分组方式整个芯片只能用一种,这个分组的代码整个工程只需要执行一次就可以了

通道选择(stm32f10x.h)

STM32单片机入门学习笔记——中断系统、外部中断_第19张图片
STM32单片机入门学习笔记——中断系统、外部中断_第20张图片

主体代码

中断函数代码部分

中断函数的名字都是固定的,可以参考启动文件,startup_stm32f10x_md.s

STM32单片机入门学习笔记——中断系统、外部中断_第21张图片

在中断函数中,一般都是先进行中断标志位的判断,因为这个函数EXTI15~EXTI10都能进来,所以要判断一下是不是我们想要的EXTI14进来,判断完之后要注意清除中断标志位

STM32单片机入门学习笔记——中断系统、外部中断_第22张图片

主体代码

外部中断配置代码部分(以旋转编码器计次为例中断IO口为PB0和PB1)

如何判断正反转呢?

AB相都触发中断,B相下降沿和A相低电平时才判断为正转;A相下降沿和B相低电平时才判断为反转

第一步——开启时钟

同上不变

主体代码

第二步——配置GPIO

STM32单片机入门学习笔记——中断系统、外部中断_第23张图片

主体代码

学习一下红框的这种写法,两个中断IO口

第三步——配置AFIO

主体代码

第四步——配置EXTI

STM32单片机入门学习笔记——中断系统、外部中断_第24张图片

主体代码

同样学习一下红框的这种写法,两个中断IO口

第五步——配置NVIC

STM32单片机入门学习笔记——中断系统、外部中断_第25张图片

主体代码

中断函数代码部分

STM32单片机入门学习笔记——中断系统、外部中断_第26张图片

主体代码

中断编程的建议

  1. 在中断函数中最好不要执行耗时过长的代码,中断函数要简短快速

  1. 最好不要在中断函数和主函数调用相同的函数或者操作同一个硬件,比如OLED显示函数,对于外部硬件并没有在进入中断时进行现场保护,CPU程序是正常工作的(有保护现场会恢复现场),这就强调变量、标志位、函数作为接口的使用,能让程序更加清晰,代码更加强健。

感谢抽出宝贵时间阅读的各位小读者们,创作不易,如果感觉有帮助的话,帮忙点个赞再走吧!你们的支持是我创作的动力,希望能带给大家更多优质的文章。

你可能感兴趣的:(单片机入门学习笔记,单片机,stm32,嵌入式硬件,c语言,arm开发)