STM32_NVIC_中断控制

文章目录

  • 一、异常类型
    • [   1、中断 (Interrupt)](#   1、中断 (Interrupt))
    • [   2、事件(Event):](#   2、事件(Event):)
    • [   3、总结](#   3、总结)
  • 二、NVIC嵌套向量中断控制器
    • [   NVIC结构体](#   NVIC结构体)
    • [   NVIC中断配置库函数](#   NVIC中断配置库函数)
    • [   1、ISER中断使用寄存器](#   1、ISER中断使用寄存器)
    • [   2、ICER中断清除寄存器](#   2、ICER中断清除寄存器)
    • [   3、ISPR中断使能悬起寄存器](#   3、ISPR中断使能悬起寄存器)
    • [   4、ICPR中断清除悬起寄存器](#   4、ICPR中断清除悬起寄存器)
    • [   5、IABR中断有效位寄存器](#   5、IABR中断有效位寄存器)
    • [   6、IPRx中断优先级寄存器(8Bit wide)](#   6、IPRx中断优先级寄存器(8Bit wide))
    • [   7、STIR软件触发中断寄存器](#   7、STIR软件触发中断寄存器)
    • [   8、中断到中断变量的映射](#   8、中断到中断变量的映射)
  • 三、优先级的定义
    • [   1、优先级寄存器NVIC_IPRx](#   1、优先级寄存器NVIC_IPRx)
    • [   2、优先级分组](#   2、优先级分组)
  • 四、中断编程
    • [   1、编程要点:](#   1、编程要点:)
    • [   2、NVIC初始化结构体](#   2、NVIC初始化结构体)
    • [   3、编写中断服务函数](#   3、编写中断服务函数)

说明:中断即异常,异常即中断。

一、异常类型

1、中断 (Interrupt)

中断是由硬件设备或外部信号引起的,它通常是异步的,意味着它可以在任何时候发生。

中断通常用于处理紧急情况或需要立即响应的事件,例如硬件故障、设备访问错误或外部信号。

中断处理程序通常需要快速执行,以免影响系统性能。

系统异常8个(Reset和Hardfault)是10个。

系统异常清单

2、事件(Event):

事件是由软件或应用程序引发的,它通常是同步的,意味着它在执行特定代码时发生。

事件通常用于处理需要通知或响应的情况,例如用户输入、网络连接状态变化或应用程序生命周期事件。

事件处理程序可以在后台执行,以免阻塞用户界面或影响应用程序性能。

外部中断60个。

外部中断清单

3、总结

中断和事件都是处理系统中异常情况的方法,但它们的触发方式和处理方式不同。

中断通常由硬件设备或外部信号引起,需要快速处理以免影响系统性能。

事件则通常由软件或应用程序引发,可以在后台执行以免阻塞用户界面或影响应用程序性能。

二、NVIC嵌套向量中断控制器

NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。

NVIC结构体

c 复制代码
		typedef struct {
		    __IO uint32_t ISER[8];       // 中断使能寄存器
		    uint32_t RESERVED0[24];
		    __IO uint32_t ICER[8];       // 中断清除寄存器
		    uint32_t RSERVED1[24];
		    __IO uint32_t ISPR[8];       // 中断使能悬起寄存器
		    uint32_t RESERVED2[24];
		    __IO uint32_t ICPR[8];       // 中断清除悬起寄存器
		    uint32_t RESERVED3[24];
		    __IO uint32_t IABR[8];       // 中断有效位寄存器
		    uint32_t RESERVED4[56];
		    __IO uint8_t  IP[240];       // 中断优先级寄存器(8Bit wide)
		    uint32_t RESERVED5[644];
		    __O  uint32_t STIR;          // 软件触发中断寄存器
		}  NVIC_Type;

我们一般使用ISER、ICER和IP三个寄存器,IESR用来使能中断,ICER用来失能中断,IP用来设置中断优先级。

NVIC中断配置库函数

编程的时候很少使用,有更好的方法。

1、ISER中断使用寄存器

偏移: 0x00 - 0x0B

复位值 : 0x0000 0000

Bits 31:0 SETENA[31:0]:中断设置使能位。

0:禁用中断

1:使能中断。

2、ICER中断清除寄存器

偏移: 0x00 - 0x0B

复位值 : 0x0000 0000

Bits 31:0 CLRENA[31:0]:中断清除使能位。

0:禁用中断

1:使能中断。

3、ISPR中断使能悬起寄存器

偏移: 0x00 - 0x0B

复位值 : 0x0000 0000

Bits 31:0 SETPEND[31:0]:中断设置挂起位

写:

0:没有效果

1:将中断状态改为挂起

读:

0:中断未挂起

1:中断正在等待中

可查中断到中断变量的映射,以了解中断到每个寄存器位的对应关系。

将1写入与暂挂中断对应的ISPR位:

-没有效果。

将中断被禁用对应的ISPR位写1;

-设置该中断的状态为挂起。

4、ICPR中断清除悬起寄存器

偏移: 0x00 - 0x0B

复位值 : 0x0000 0000

Bits 31:0 CLRPEND[31:0]:中断清除等待位

写:

0:没有效果

1:移除中断的挂起状态

读:

0:中断未挂起

1:中断正在等待中

将1写入ICPR位不会影响相应中断的活动状态。

5、IABR中断有效位寄存器

偏移: 0x00 - 0x0B

复位值 : 0x0000 0000

Bits 31:0 ACTIVE[31:0]:中断活动标志

0:中断不活动

1:中断活动

如果相应的中断状态是活动的或活动的和挂起的,那么这个位读为1。

6、IPRx中断优先级寄存器(8Bit wide)

偏移: 0x00 - 0x0B

复位值 : 0x0000 0000

IPR0-IPR16寄存器为每个中断提供一个4位优先级字段。

这些寄存器是字节可访问的。

每个寄存器包含四个优先级字段,它们映射到数组中的四个元素,CMSIS中断优先级阵列IP[0]到IP[67],如图所示。

7、STIR软件触发中断寄存器

偏移: 0xE00

复位值 : 0x0000 000

Bits 31:9保留,必须保持干净。

NTID[8:0]软件产生的中断ID

写入STIR以生成软件生成中断(SGI)。要写入的值是所需SGI的中断ID,范围为0-239。例如,0b000000011表示中断IRQ3。

8、中断到中断变量的映射

三、优先级的定义

1、优先级寄存器NVIC_IPRx

用于表达优先级的4bit,又被分组成抢占优先级和子优先级。

如果有多个中断同时响应,抢占优先级高的就会抢占抢占优先级低的优先得到执行,

如果抢占优先级相同,就比较子优先级。

如果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高。

2、优先级分组

设置优先级分组可调用库函数NVIC_PriorityGroupConfig()实现,有关NVIC中断相关的库函数都在库文件misc.c和misc.h中。

中断优先级分组库函数NVIC_PriorityGroupConfig()

c 复制代码
		/**
		* 配置中断优先级分组:抢占优先级和子优先级
		* 形参如下:
		* @arg NVIC_PriorityGroup_0: 0bit for抢占优先级
		*                            4 bits for 子优先级
		* @arg NVIC_PriorityGroup_1: 1 bit for抢占优先级
		*                            3 bits for 子优先级
		* @arg NVIC_PriorityGroup_2: 2 bit for抢占优先级
		*                            2 bits for 子优先级
		* @arg NVIC_PriorityGroup_3: 3 bit for抢占优先级
		*                            1 bits for 子优先级
		* @arg NVIC_PriorityGroup_4: 4 bit for抢占优先级
		*                            0 bits for 子优先级
		* @注意 如果优先级分组为0,则抢占优先级就不存在,优先级就全部由子优先级控制
		*/
		void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
		{
		    // 设置优先级分组
		    SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
		}

四、中断编程

1、编程要点:

1、使能外设某个中断,这个具体由每个外设的相关中断使能位控制。比如串口有发送完成中断,接收完成中断,这两个中断都由串口控制寄存器的相关中断使能位控制。

2、初始化NVIC_InitTypeDef结构体,配置中断优先级分组,设置抢占优先级和子优先级, 使能中断请求。NVIC_InitTypeDef结构体在固件库头文件misc.h中定义。

2、NVIC初始化结构体

NVIC结构体

c 复制代码
		typedef struct {
		    uint8_t NVIC_IRQChannel;                    // 中断源
		    uint8_t NVIC_IRQChannelPreemptionPriority;  // 抢占优先级
		    uint8_t NVIC_IRQChannelSubPriority;         // 子优先级
		    FunctionalState NVIC_IRQChannelCmd;         // 中断使能或者失能
		} NVIC_InitTypeDef;

1、NVIC_IROChannel:

用来设置中断源,不同的中断中断源不一样,且不可写错,即使写错了程序也不会报错,只会导致不响应中断。

可参考stm32f10x.h头文件里面的IRQn_Type结构体定义,这个结构体包含了所有的中断源。

2、NVIC_IRQChannelPreemptionPriority:

抢占优先级,具体的值要根据优先级分组来确定, 具体参考表格 优先级分组真值表 优先级分组真值表。

3、NVIC_IRQChannelSubPriority:

子优先级,具体的值要根据优先级分组来确定, 具体参考表格 优先级分组真值表 优先级分组真值表。

4、NVIC_IRQChannelCmd:

中断使能(ENABLE)或者失能(DISABLE)。 操作的是NVIC_ISER和NVIC_ICER这两个寄存器。

3、编写中断服务函数

在启动文件startup_stm32f10x_hd.s中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。

实际的中断服务函数都需要我们重新编写,为了方便管理我们把中断服务函数统一写在stm32f10x_it.c这个库文件中。

相关推荐
Suifqwu2 小时前
stm32之移植MbedTLS以及算法实现
stm32·嵌入式硬件·算法
forAllforMe2 小时前
用STM32+LAN9252做etherCAT 运动控制从机方案
stm32·单片机·嵌入式硬件
WYH2872 小时前
FreeRTOS工程项目实践
c语言·单片机·嵌入式硬件·学习
阿拉斯攀登5 小时前
第 9 篇 RK 平台安卓驱动实战 2:中断驱动开发,按键中断的完整实现
驱动开发·嵌入式硬件·rk3568·中断·瑞芯微·rk3576·rk安卓驱动
_muffinman5 小时前
LED点阵8*8驱动开发笔记(Ai8051U单片机)
驱动开发·笔记·单片机
LCMICRO-133108477465 小时前
长芯微LDC64115完全P2P替代AD4115,是一款低功耗、低噪声、24位、Σ-Δ(Σ-Δ)模数转换器(ADC)
stm32·单片机·嵌入式硬件·fpga开发·硬件工程·模数转换器
-Springer-5 小时前
STM32 学习 —— 个人学习笔记9-1(USART串口协议 & 串口发送及接收数据)
笔记·stm32·学习
busideyang6 小时前
数据手册和参考手册区别
stm32·单片机·嵌入式硬件·嵌入式
逐步前行6 小时前
STM32_时钟树_寄存器操作
stm32·单片机·嵌入式硬件