Skip to main content

中断与事件 原理

中断是什么,它有什么作用呢?

up的视频讲解:

1 中断与事件 原理

1.1 什么是中断?

举个例子: 你正在写作业, 但是你妈妈突然叫你去吃饭, 吃完饭后你再接着把作业写完.

  • 写作业 -> 吃饭 -> 接着写作业

这个过程就叫中断, 那么对芯片而言呢?

1.2 中断四大阶段

  1. 中断请求
  • 外设(按键、定时器、串口、ADC 等)满足触发条件后,向 CPU 发送中断请求信号
  1. 中断响应
  • CPU 检测到中断请求,且该中断未被屏蔽、优先级允许时

  • 暂停当前正在执行的主程序

  • 把当前寄存器、程序地址等现场数据压入栈保存

  • 按照NVIC向量表地址, 跳转到对应中断的入口地址

  1. 中断处理
  • CPU 执行专门用来处理该事件的代码,这段代码叫做中断服务函数
  1. 中断返回
  • 中断任务执行完毕后

  • 从栈中恢复之前保存的寄存器、断点地址

  • CPU 回到被打断的主程序位置,继续往下执行

中断与事件的区别
  • 中断(Interrupt):

    • 中断是CPU打断断开正在执行的程序, 去执行中断程序

    • 进入NVIC,有相应的中断服务函数,需要CPU处理

  • 事件(Event)

    • 事件不强制打断CPU的运行, 只发出通知信号

    • 不进入NVIC,仅用内部硬件自动控制,TIM,DMA,ADC等

1.3 中断优先级

STM32中断优先级基本概念:

  • 抢占优先级(Preemption)

    高抢占优先级(数值小)可以打断正在执行的低抢占优先级中断,实现中断嵌套。

  • 响应优先级(Subpriority)

    抢占优先级相同时,响应优先级高(数值小)的先执行;不能互相打断

  • 自然优先级

    由芯片硬件固定,对应中断向量表中的中断号(IRQn),编号越小优先级越高,软件不可改。

优先级规则
  • 优先级数值规则 无论抢占还是响应,数值越小,优先级越高(0 最高)

  • 同级仲裁规则 抢占优先级、响应优先级都相同时,自然优先级越高,先执行

2 NVIC

2.1 NVIC 中断控制器

NVIC(Nested Vectored Interrupt Controller): 嵌套向量中断控制器, 它在内核里面

  • NVIC属于是内核的器件(由ARM公司设计),M3 内核都是支持 256 个中断,其中包含了 16 个系统中断和 240 个外部中断,并且具有 256 级的可编程中断设置

  • 但是对于ST公司来说,用不了M3内核中的所有中断以及中断优先级,进而对其进行了一定的裁剪。STM32中共有10个内核中断,60个外部中断,16个中断优先级;

  • 我们可以从ST官方的(datasheet)数据手册中看到它

NVIC 中断控制器

  • 也可以在ARM官方Cortex-M3(Technical Reference)技术手册中看到它

Cortex-M3

2.2 NVIC 中断向量表

中断向量表定义在启动文件中,发生中断时,CPU会自动按照这张表的地址, 跳转到对应的中断服务函数

  • 比如说这里的定时器向量, DMA中断向量, Uart串口中断等, 当然还有很多这里只是一部分

中断向量表

2.3 NVIC 寄存器

NVIC属于内核设备, 所以它的寄存器需要在Cortex-M3内核技术手册中找到, 这里写代码很少用到, 了解就行

NVIC寄存器

  • ISER 开启中断
  • ICER 关闭中断
  • ISPR 软件触发中断
  • ICPR 取消中断请求
  • IABR 看哪个中断在跑
  • IPR 设置中断优先级

2.4 NVIC 工作原理

  • 内核中断由SHPR寄存器控制,SHPR与IPR寄存器属于同一级别

    • SHPR System Handler Priority Registers SCB(系统控制块)设置内核异常

    • AIRCR Application Interrupt and Reset Control Register SCB(系统控制块)配置中断优先级分组、系统复位

  • 外部中断,首先进入ICER、ISER寄存器,用于控制是否开对应的中断,

    • 打开的中断进入IPR寄存器,进行中断优先级的判断
    • IPR寄存器受AIRCR寄存器控制,最后按照中断优先级依次进入CPU被执行

NVIC工作原理

:::

3 EXTI

3.1 EXTI 外部中断/事件

EXTI(External Interrupt/Event Controller): 外部中断/事件控制器

  • 外部中断/事件, 来自芯片的外部, 通过引脚输入

  • 内部中断/事件, 来自芯片内部, 通常由各外设发出如:

    • 定时器中断:定时时间到了 → 中断

    • 串口(UART)中断:收到数据 / 发完数据 → 中断

    • ADC 中断:模数转换完成 → 中断

    • DMA 中断:数据搬运完 → 中断

    • 看门狗中断:超时报警 → 中断

3.2 EXTI 框架结构

EXTI

Input Line: 多个 GPIO 引脚通过 AFIO 模块的多路选择器(MUX), 由AFIO_EXTICR寄存器控制, 分时复用到同一条 EXTI 中断线上, 然后进入外部中断/事件控制器

1 或门(OR): 一个输入有效时, 或门就会输出高电平请求信号

2 与门(AND): 两个输入都有效, 或门才会输出高电平请求信号

3.3 EXTI 寄存器

EXTI 寄存器

应当分为这3部分:

  • 1 中断/事件 产生源 :

FTSR Falling trigger selection register(下降沿选择寄存器): 检测下降沿后, 产生一个脉冲信号(脉冲宽度为 1 个 PCLK2 周期)

RTSR Rising trigger selection register(上升沿选择寄存器)`: 检测到上升沿后, 产生一个脉冲信号

SWIER Software interrupt event register(软件中断事件寄存器): CPU 写该寄存器的对应位为 1, 即可强制产生一个中断 / 事件请求

  • 2 生成 中断

PR Pending register(挂起请求寄存器): 该寄存器对应位置1, 表示中断请求已被挂起, 等待处理. 为 0时, 清除挂起状态

IMR Interrupt mask register(中断屏蔽寄存器): 若对应位为 0, 该中断请求会被屏蔽, 为 1 则允许

  • 3 生成 事件 (不进入 NVIC)

EMR Event mask register(事件屏蔽寄存器): 同上

Pulse generator(脉冲发生器): 将电平信号转换为一个单周期的脉冲信号, 输出到片内外设(如定时器、ADC、DMA)

  • 最顶上的APBbus, CPU就是通过该总线来访问这些寄存器的

3.4 EXTI 中断线

每个寄存器使用20位, 每一位对应一根外部中断线, 一共20根

  • 0-15:对应GPIO_PIN 0-15中断

  • 16:PVD输出

  • 17:RTC闹钟事件

  • 18:USB唤醒事件

  • 19:连接到以太网唤醒事件

EXTI 中断线

EXTI 线 0~15:对应外部 IO 口使用的中断线只有 16 个,但是 STM32F1 的 IO 口 却远远不止 16 个

  • 所以 STM32 把 GPIO 管脚 GPIOx.0到GPIOx.15(x=A,B,C,D,E,F,G)通过AFIO寄存器映射到中断线 0~15

  • 以中断线线 EXTI0 为例:它对应了GPIOA.0、GPIOB.0、 GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0 和 GPIOG.0

  • 而中断线每次只能连接到 1 个 IO 口上, 这样就需要通过配置决定对应的中断线配置到哪个 GPIO 上了

EXTI 复用

4 中断的使用

4.1 中断的使用步骤

EXIT的配置步骤

  1. 设置GPIO的模式

  2. 设置GPIO与EXIT映射关系

  3. 设置EXIT触发方式

  4. 设置NVIC中断优先级

  5. 设置中断服务函数

中断的使用步骤

4.2 中断服务函数

HAL 库为了用户使用方便,提供了一个中断通用入口函数 HAL_GPIO_EXTI_IRQHandler

  • 在该函数内部直接调用中断回调函数 HAL_GPIO_EXTI_Callback()

  • 用户只要在中断回调函数中写程序即可

4 温度警报-GPIO中断 实验

5 光照警报-GPIO中断 实验