当前位置: 首页 > news >正文

Day07_STM32 单片机 - 中断

一、处理器的工作模式

1.1 Cortex-M 核工作模式

1.异常模式
2.线程模式

1.2 Cortex-A 核工作模式

ARM-v7架构:1.非特权模式:User模式2.特权模式:2.1 非异常模式:Sys模式2.2 异常模式:IRQ模式 - 普通中断异常模式FIQ模式 - 快速中断异常模式SVC模式 - 超级管理异常模式ABT模式 - 中止访问异常模式UDF模式 - 未定义异常模式
ARM-v8架构:多两种:MON模式 - 安全监管模式、HYP模式 - 虚拟化技术模式

二、异常处理流程

图 1 异常处理流程图

2.1 异常源

异常源:触发处理器执行异常事件对应的处理逻辑的源头(集合);

异常源支持很多异常事件。

=================================================================

  1. 5 种异常模式对应 7 种异常源;
  2. 每种异常源存在很多异常事件 - 异常源就是异常事件的集合;
  3. SVC 模式下复位异常源优先等级最高处理器优先处理

2.2 自动保护现场 - CPU 自动完成

自动保护现场需要做 4 件事

1.将 CPSR 寄存器中的值保存到 SPSR_<MODE> 寄存器中
2.修改 CPSR 寄存器中的位:
2.1 修改 CPSR 寄存器中的 I / F 位(是否屏蔽 IRQ / FIQ 模式);
2.2 修改 CPSR 寄存器中的 T 位(是否使用 ARM / Thumb 汇编指令集);
2.3 修改 CPSR 寄存器中的 M 位(进入对应的异常模式)。
3.将函数的返回地址保存到 LR 寄存器中;
4.PC 寄存器指向异常向量表。

2.3 手动恢复现场 - 程序员手动完成

  1. 将 SPSR_<MODE> 寄存器中的值恢复到 CPSR 寄存器中;
  2. 将 LR 寄存器中的值赋值给 PC 寄存器。

2.4 异常向量表

地址    异常类型
0x1C    FIQ
0x18    IRQ
0x14    (Reserved)
0x10    Data Abort
0x0C    Prefetch Abort
0x08    Software Interrupt
0x04    Undefined Instruction
0x00    Reset


异常向量表:异常源的集合

        当发生异常事件后,处理器检测当前异常事件所属异常源,就需要给各个异常源分配不同的内存空间地址,处理器去寻址查找。

        异常向量表占内存空间的 32 个字节每个异常源占 4 个字节空间,同时有 4 个字节的空间保留。


图 2 异常处理的流程

为什么引入异常向量表

        在异常出发后,最后是需要执行异常处理的函数

        而在开发板 / 系统上电复位后,函数的地址、参数的地址、变量的地址可能发生改变,对于 CPU 无从知晓变化后的地址,所以可以固定一片内存空间地址,引导 CPU 找到异常处理函数。

        ARM 公司在开发并生产内核时,固定一片 32 个字节的地址空间,存放各个异常源的地址,称为异常向量表

2.5 汇编代码模拟异常处理流程

.text		.global _start		_start:			@ 构建异常向量表b reset_handlerb undefined_handlerb swi_handlerb prefetch_handlerb data_handlerb .	@ 占4个字节空间操作b irq_handlerb fiq_handlerreset_handler:@ 为SVC模式下的SP寄存器给定一个内存空间地址ldr sp, =0x40000820@ 从SVC模式切换到User模式下,执行用户代码msr cpsr, #0xD0@ 用户代码,以下相当于main函数mov r0, #0x1mov r1, #0x2@ 软中断异常事件触发@ swi 2这条汇编指令执行完毕后,需要看到的效果@ 1、CPSR寄存器中的值是否被保存到SPSR寄存器中@ 2、CPSR寄存器中的值是否被改变(IFTM位)@ 3、LR寄存器中是否保存函数的返回地址@ 4、PC是否指向异常向量表中软中断异常源的地址swi 2add r2, r1, r0undefined_handler:swi_handler:@ 压栈保存现场,保存局部变量和函数返回地址stmfd sp!, {r0-r1, lr}@ 软中断异常源下第一个异常事件的处理函数mov r0, #0xffmov r1, #0xeeadd r2, r1, r0@ 出栈恢复现场,恢复局部变量和函数返回地址@ 还需要恢复SPSR寄存器中的值给到CPSR寄存器@ ^的作用:用于将SPSR寄存器中的值赋值给CPSR寄存器ldmfd sp!, {r0-r1, pc}^prefetch_handler:data_handler:irq_handler:fiq_handler:stop:			b stop		
.end		

        当异常发生时,CPU 根据异常的类型,找到异常向量表中对应异常源的固定地址,随后跳转到改地址去执行相应的异常处理函数,这和异常源的名字无关,名字只是帮助开发者理解的符号。


三、分析按键的电路图

KEY1 - PC9
KEY2 - PC8
KEY3 - PC5

图 3 按键抖动示意图

        GPIO 检测按键的抬起和按下高 低电平),中断检测按键抬起 / 按下的时机上升沿 下降沿)。

四、分析芯片手册

图 4 NVIC 和 EXTI

EXTI:外部中断和事件控制器

NVIC:嵌套向量中断控制器

        嵌套中断的嵌套,指的是中断具备优先级等级,高优先级等级的中断信号可以打断低优先级的中断信号。

        向量所有异常中断统一由向量表进行管理。


在使用 Cortex-M 核(MCU),中断处理一般使用 EXTI + NVIC 来实现

在使用 Cortex-A 核(MPU),中断处理一般使用 EXTI + GIC(GICC+CPID) 来实现

4.1 EXTI 介绍

1)介绍

图 5 EXTI 介绍

        外部中断和事件控制器(EXTI)通过可配置的事件输入来管理各个 CPU 和系统唤醒。它向电源控制提供唤醒请求,并向 CPU NVIC 生成中断请求以及向 CPU 事件输入生成事件。对于 CPU,需要额外的事件生成模块(EVG)来生成CPU事件信号。

2)主要特性

图 6 EXTI 主要特性

  • 支持 26 个输入事件编号;
  • 可选择的边沿触发方式 - 上升沿触发、下降沿触发、上升沿下降沿都触发;
  • 中断挂起状态标志位 - 上升沿和下降沿的中断状态在硬件层面被分开记录和处理;
  • 支持中断信号和输入事件的屏蔽功能;
  • 支持多个 GPIO 端口的选择。

4.2 输入事件编号

图 7 输入事件编号列表

         输入事件编号(Event Input Number)是硬件层用于唯一标识外部中断/事件(EXTI)源的数字ID,每个编号对应一条独立的EXTI线(如编号0对应EXTI[0])。其核心作用是通过数字映射将物理引脚的电平变化与系统中断/事件处理逻辑精准关联。

4.3 EXTI 内部框图

图 8 EXTI 内部框图

图 10 EXTI 内部框图描述

  EXTI 外设控制器中有一个寄存器块,这个寄存器块被连接在 AHB3 总线上(EXTI 被连接在 AHB3 总线上)。
输入事件触发块用于提供输入事件边沿触发的逻辑,也就是需要设置输入事件的触发方式为上升沿触发 / 下降沿触发 / 双边沿触发。
输入事件屏蔽块用于提供输入事件的分配(可以分配给 PWR 用于系统唤醒、可以分配给 CPU 下的 NVIC 用于中断控制、也可以分配给 EVG 用于事件输出、还可以把上述操作屏蔽掉)。
IO 端口选择块提供了 GPIO 端口选择的功能(也就是让 EXTI 知道是哪个 GPIO 端口产生了中断信号)。

4.4 寄存器功能分析

图 11 EXTI 功能描述

中断的挂起:中断信号到达,等待被处理,需要执行这个中断信号对应的逻辑代码。也就是执行中断信号对应逻辑代码前,需要判断这个中断信号是否发生,即这个中断是否被挂起。

4.5 GPIO 端口选择

图 12 EXTI 多路选择(GPIO 端口选择)

4.6 寄存器分析

1)EXTI_FTSR1 寄存器

图 13 EXTI_FTSR1

下降沿触发选择寄存器

        写入 0:PC9 引脚下降沿触发不使能
        写入 1:PC9 引脚下降沿触发使能

2)EXTI_FPR1 寄存器

图 14 EXTI_FPR1

图 15 

下降沿触发挂起寄存器

rc_w1权限:
r    c_w1
写入0:
没有影响
写入1:人为清除对应的值

-----------------------------------------------------
读 0:没有下降沿触发请求存在
也就是下降沿没有触发,中断没有挂起
读 1:下降沿触发请求存在
也就是下降沿触发,中断被挂起


        当我们检测按键是否按下时,也就是检测中断是否被挂起,也就是读取这个寄存器对应位是否为 1:

        读取到 1:就代表中断被挂起,可以执行处理逻辑

        读到到 0:就代表中断没有被挂起,不需要执行处理逻辑

        当我们读取到中断被挂起后,为了让中断不一直处于被挂起状态,需要人为手动解除中断的挂起。

3)EXTI_EXTICRm 寄存器

图 16 EXTI_EXTICRm

图 17 GPIO 端口的选择

http://www.dtcms.com/a/390149.html

相关文章:

  • 花瓶测试用例10条(基于质量模型)
  • C++ 之 【智能指针的简介】
  • Vue3 + xgplayer 实现多功能视频播放器:支持播放列表、自动连播与弹幕
  • 牛客算法基础noob46 约瑟夫环
  • TCP协议的详解
  • 【LeetCode】大厂面试算法真题回忆(136)——环中最长子串
  • Hystrix:熔断器
  • SQLark 实战 | 数据筛选与排序
  • 达梦Qt接口源码Qt6编译错误处理记录
  • 知识付费创作者:如何避免陷入跟风做内容的陷阱?
  • @once_differentiable 自定义算子的用处
  • 分子动力学--蛋白配体模拟
  • python第二节 基础语法及使用规范详解
  • 运维安全07 - JumpServer(堡垒机)介绍以及使用
  • 同一个电脑内两个进程间如何通信的几种方式
  • 《FastAPI零基础入门与进阶实战》第20篇:消息管理-封装
  • Pyside6 + QML - 信号与槽04 - Python 主动发射信号驱动 QML UI
  • 【系列文章】Linux系统中断的应用06-中断线程化
  • ruoyi-vue(十五)——布局设置,导航栏,侧边栏,顶部栏
  • 第13章 线程池配置
  • 任天堂获得新专利:和《宝可梦传说:阿尔宙斯》相关
  • Redis MONITOR 命令详解
  • 七、Java-多线程、网络编程
  • 三轴云台之动态补偿机制篇
  • MySQL备份与恢复实战指南:从原理到落地,守护数据安全
  • 手机上记录todolist待办清单的工具选择用哪一个?
  • 仓颉编程语言青少年基础教程:Interface(接口)
  • 用 go-commons 打造一个轻量级内置监控系统,让服务开箱即用
  • PyQt6之QSpinBox计数器应用
  • 大模型应用开发4-MCP实战