打印
[其他ST产品]

【明解STM32】中断系统理论基础知识篇之中断寄存器功能原理

[复制链接]
2081|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
前言
        在之前的STM32的中断系统理论基础知识之基本原理及NVIC中,分别中断的基本原理,中断的管理机制和中断的处理流程进行了较为详细的论述,读者通过全篇的阅读了解可以整体上对以围绕NVIC为管理核心的STM32的中断系统有一个初步的了解,明白中断的一些基本概念以及STM32中断系统的一个大致的工作流程。

        这一篇主要对中断系统相关的寄存器进行相应的分析介绍,适当了解中断系统寄存器的相关介绍,有助于加深对STM32内核的中断及异常的认识,明白中断时的功能都是由哪些寄存器负责完成实现的,同时对后续介绍到的中断相关配置及API函数的使用有很好的帮助。



使用特权

评论回复
评论
过期的塔头 2023-9-30 10:43 回复TA
———————————————— 版权声明:本文为CSDN博主「Sharemaker」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/helloqusheng/article/details/130937520 
沙发
过期的塔头|  楼主 | 2023-9-30 10:43 | 只看该作者
寄存器概述
        图1为STM32中断系统寄存器的概述,总共可以分为3组不同的寄存器组。各个寄存器组下分别又有不同用于中断控制的寄存器。它们都属于STM32内核上的寄存器。

        (1)、NVIC作为内嵌向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对 Cortex-M3 内核里面的 NVIC 进行裁剪,把不需要的部分去掉,所以说 STM32的 NVIC 是Cortex-M3的 NVIC 的一个子集。它用于总体管理异常和中断,因此提供了和中断系统紧密相关的控制和状态寄存器;

        (2)、SCB为系统控制块,SCB中包含了一些内核系统控制相关的寄存器,同时也包含了关于中断相关的,由于本篇主要介绍中断系统,因此这里就只针对SCB中关于中断控制的寄存器功能进行分析介绍;

        (3)、而为了满足一些代码段不允许被中断打断,那么这段代码就必须用关中断的方式给保护起来的场合,STM32提供了中断屏蔽寄存器,我们可以一次性把一堆必须要屏蔽的中断进行屏蔽。


图1 中断系统寄存器概述

使用特权

评论回复
板凳
过期的塔头|  楼主 | 2023-9-30 10:44 | 只看该作者
NVIC寄存器组
        NVIC控制器包含一系列寄存器组,STM32为其定义了如下的结构体:

typedef struct
{
  __IO uint32_t ISER[8];  /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
  uint32_t RESERVED0[24];
  __IO uint32_t ICER[8];  /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
  uint32_t RSERVED1[24];
  __IO uint32_t ISPR[8];  /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register*/
  uint32_t RESERVED2[24];
  __IO uint32_t ICPR[8];  /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register*/
  uint32_t RESERVED3[24];
  __IO uint32_t IABR[8];  /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register*/
  uint32_t RESERVED4[56];
  __IO uint8_t  IP[240];  /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
  uint32_t RESERVED5[644];
  __IO  uint32_t STIR;  /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register*/
}  NVIC_Type;

使用特权

评论回复
地板
过期的塔头|  楼主 | 2023-9-30 10:44 | 只看该作者
中断使能寄存器ISER

        Interrupt Set-Enable Registers,这是一个中断使能寄存器组。总共有8个uint32类型的寄存器,即ISER[8],上面说了 CM3 内核支持 256 个中断,这里用 8 个32位寄存器来控制,每个位控制一个中断。但是例如STM32F103 的可屏蔽中断只有 60 个,所以对我们来说,有用的就是两个(ISER[0]和 ISER[1]),总共可以表示 64 个中断。而 STM32F103 只用了其中的前 60 位。ISER[0]的 bit0 ~ bit31 分别对应中断 0 ~ 31。ISER[1]的 bit0 ~ 27 对应中断 32~59;这样总共 60 个中断就分别对应上了。你要使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO 口映射等设置才算是一个完整的中断设置)。

使用特权

评论回复
5
过期的塔头|  楼主 | 2023-9-30 10:45 | 只看该作者


图2 中断使能和中断除能寄存器组

使用特权

评论回复
6
过期的塔头|  楼主 | 2023-9-30 10:45 | 只看该作者
(2)、中断除能寄存器ICER

        Interrupt Clear-Enable Registers,是一个中断除能寄存器组。总共有8个uint32类型的寄存器,即ICER[8],该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和 ICER 一样。这里要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为NVIC 的这些寄存器都是写 1 有效的,写 0 是无效的。

使用特权

评论回复
7
过期的塔头|  楼主 | 2023-9-30 10:45 | 只看该作者
(3)、中断挂起控制寄存器ISPR

        Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。总共有8个uint32类型的寄存器,即ISPR[8],每个位对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,暂时停止执行该中断,而执行同级或更高级别的中断。写 0 是无效的。

使用特权

评论回复
8
过期的塔头|  楼主 | 2023-9-30 10:45 | 只看该作者

使用特权

评论回复
9
过期的塔头|  楼主 | 2023-9-30 10:46 | 只看该作者
(4)、中断解挂控制寄存器ICPR

        Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。总共有8个uint32类型的寄存器,即ICPR[8],其作用与 ISPR 相反,将之前暂时停止执行的中断解挂,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断解挂。写 0 无效。

使用特权

评论回复
10
过期的塔头|  楼主 | 2023-9-30 10:46 | 只看该作者
(5)、中断激活标志位寄存器IABR

        Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。总共有8个uint32类型的寄存器,即IABR[8],对应位所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。如果在中断执行过程中,发生了更高优先级的中断抢占,那么之前被抢占的中断该标志位依然是1。

使用特权

评论回复
11
过期的塔头|  楼主 | 2023-9-30 10:46 | 只看该作者

图4 中断激活标志位寄存器组

使用特权

评论回复
12
过期的塔头|  楼主 | 2023-9-30 10:46 | 只看该作者
(6)、中断优先级控制寄存器IP

        Interrupt Priority Registers,是一个中断优先级控制的寄存器组。总共有240个uint8类型的寄存器,即IP[240],这个寄存器组相当重要!STM32 的中断分组与这个寄存器组密切相关。IP 寄存器组由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。而 STM32 只用到了其中的前 60 个。IP[59] ~ IP[0]分别对应中断 59 ~ 0。而每个可屏蔽中断占用的 8bit 并没有全部使用,而是只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。



图5 中断优先级控制寄存器组

使用特权

评论回复
13
过期的塔头|  楼主 | 2023-9-30 10:47 | 只看该作者
(7)、软件触发中断寄存器STIR

        这个寄存器是利用软件设置中断编号的方式来触发中断发生,是一个uint32类型的寄存器,有效位为0~8。比如设置NVIC->STIR=3,则会触发中断3,需要注意的是,该寄存器无法触发系统异常如NMI或Systick的。

图6 软件触发中断寄存器

使用特权

评论回复
14
过期的塔头|  楼主 | 2023-9-30 10:47 | 只看该作者
SCB寄存器组
        系统控制块(SCB)是内核外设的主要模块之一,提供系统控制以及系统执行信息,包括配置,控制,报告系统异常等。而SCB数据结构中也包含了一些常用于中断控制的寄存器。

使用特权

评论回复
15
过期的塔头|  楼主 | 2023-9-30 10:47 | 只看该作者
(1)、中断控制和状态寄存器ICSR

        该寄存器的主要作用为:

        a. 设置和清除系统异常的挂起状态,异常包括Systick、PendSV、NMI。这个功能和NVIC的中断挂起控制寄存器ISPR和中断解挂控制寄存器ICPR差不多;

        b.通过读取VECTACTIVE=>Vector Active域,可以确定当前执行的异常/中断编号,VECTACTIVE域和中断程序状态寄存器(IPSR)功能比较类似,IPSR包含了当前正在执行的中断服务程序(ISR)编号,只不过VECTACTIVE是用来读Systick、PendSV、NMI这些异常状态的。

使用特权

评论回复
16
过期的塔头|  楼主 | 2023-9-30 10:47 | 只看该作者
图7 中断控制和状态寄存器

        注意:当写ICSR时,如果:写1到PENDSVSET位和写1到PENDSVCLR位;写1到PENDSTSET位和写1到PENDSTCLR位;程序执行的效果是不可预测的。该寄存器各个位域可以通过调试器读取状态,但多数情况下只有挂起位用于应用开发。

使用特权

评论回复
17
过期的塔头|  楼主 | 2023-9-30 10:48 | 只看该作者
(2)、向量偏移寄存器VTOR

        由于CPU随时都可能检测到中断信息,也就是说,CPU 随时都可能执行中断处理程序,所以中断处理程序必须一直存储在内存某段空间之中。中断处理程序在内存中的入口地址称为中断向量;而要确定中断处理程序的入口地址,处理器利用了一种向量表机制:即中断向量,必须存储在对应的中断向量表表项中。采用向量表处理中断,处理器会从存储器的向量表中,自动定位中断的程序入口。

使用特权

评论回复
18
过期的塔头|  楼主 | 2023-9-30 10:48 | 只看该作者
     一般来说,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动。而这张“中断向量表”的起始地址是0x8000004,当中断来临,STM32的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。不过有些应用可能需要在运行时修改或定义向量表地址。为了进行这种处理,M3/M4处理器实现了一种名为向量表重定位的特性。向量表重定位特性提供了一个名为向量表偏移寄存器(VTOR)的可编程寄存器。该寄存器将正在使用的存储器的起始地址定义为向量表。

使用特权

评论回复
19
过期的塔头|  楼主 | 2023-9-30 10:48 | 只看该作者

图8 向量偏移寄存器

使用特权

评论回复
20
过期的塔头|  楼主 | 2023-9-30 10:48 | 只看该作者
中断向量表里的中断跳转地址在编译后就定下来了,SCB->VTOR向量可动态调整就是让我们的程序运行后还能改变向量的跳转地址。方法就是:在RAM重建一个中断向量表,在想改变的位置重新赋值新的跳转地址。通过赋值向量表偏移数值SCB->VTOR = (uint32_t)__VECTOR_RAM,这样下次异常发生时,就直接跳到重新指定的RAM中断向量表的首地址处,再匹配对应的中断向量。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

923

帖子

0

粉丝