第5课【中断与NVIC】中断 NVIC 优先级 中断编程

目录

  • 基本知识框架
  • 课堂笔记
    • 中断
      • 什么是中断
      • 中断的基本工作机制
      • 功能框图
      • 中断的优点
    • 中断类型和中断优先级
      • 中断类型
        • 系统中断
        • 外部中断
      • 中断优先级
    • NVIC嵌套向量控制器
      • NVIC寄存器结构体
      • NVIC寄存器相关库函数
      • 中断优先级寄存器和中断优先级设置库函数
    • 中断编程
  • 基本知识框架Xmind文件下载

基本知识框架

第5课【中断与NVIC】中断 NVIC 优先级 中断编程_第1张图片

课堂笔记

中断

什么是中断

中断是一种计算机处理突发情况的工作机制

中断的基本工作机制

中断工作机制并不是凭空出现的,而是借鉴了生活中的经验。例如,你今天想完成两件事情:看电视和收快递,你会这样去完成,躺在沙发上专心看电视,并等待快递员通知你去收取快递,如果快递员不通知,那你就会专心的看你的电视;这和中断的使用场景非常相似,计算机在处理主任务的同时,还会面对一些突发情况(内存溢出,硬件宕机,定时器溢出。。。),通过中断这种硬件层面的功能,当异常情况发生时,中断控制器主动通知CPU保存主任务进度,优先执行突发情况处理的程序,执行完后再恢复主任务现场,并继续先前的工作

功能框图

第5课【中断与NVIC】中断 NVIC 优先级 中断编程_第2张图片

中断的优点

相比轮询,中断机制有以下优点

  • 提高了计算机的工作效率:中断不像轮询一样,需要CPU时时刻刻去监测突发情况是否发生,而是主动去通知CPU来处理突发情况,当不发生突发情况时,CPU可以专心的完成主任务
  • 满足实时性的需求:当有实时性要求很高的任务时,通过配置中断,可以使此任务得到优先处理,
  • 提供了故障处理的手段当发生故障,尤其是硬件故障时,通过中断,可以实现故障处理,设备复位等操作

中断类型和中断优先级

中断类型

STM32中,根据发起中断请求的外设在内核中还是内核以外,可以分为系统中断和外部中断

系统中断

系统中断是由内核中的外设发出的中断请求,由嵌套向量控制器NVIC直接响应

外部中断

外部中断是由内核外的外设,即APB总线上的外设发出的中断请求,由外部中断/事件控制器相应,如果发出的是中断信号,最终还会传到NVIC嵌套向量控制器

中断优先级

如果STM32同一时间收到多个中断信号,那么信号之间就有可能出现冲突。所以NVIC中还定义了中断的优先级,优先级高的中断,会被优先处理
优先级分为主优先级子优先级,主优先级中断信号高于子优先级中断信号,会被优先响应,同级中断信号,根据优先级编号判断,编号越小,优先级越高,如果主优先级和子优先级都相同,则比较它们的硬件编号,硬件编号越小的,优先级越高

STM32中中断信号的优先级不是完全固定的,有部分中断信号的优先级是可以编程的,由开发者去设定中断信号的优先级

STM32中有8个系统中断(算上Reset和HardFault的话,有10个),60个外部中断,其中大部分优先级是可编程的,少部分中断信号优先级是固定的
第5课【中断与NVIC】中断 NVIC 优先级 中断编程_第3张图片
第5课【中断与NVIC】中断 NVIC 优先级 中断编程_第4张图片

NVIC嵌套向量控制器

NVIC嵌套向量控制器 ,这个控制器控制着整个芯片中断相关的功能,是内核中的一个外设,和内核紧密耦合。但由于STM32需要的中断功能没有那么高,所以实际上STM32中的NVIC是经过裁剪的,是属于CorteX NVIC的一个子集

为什么NVIC叫嵌套向量控制器
个人理解
嵌套:中断是可以嵌套的,这就意味着在执行优先级较低的中断服务时,是会被优先级较高的中断服务打断,等待高优先级的中断服务完成后,再恢复低优先级中断服务的现场,继续执行低优先级的中断服务
向量:向量指的是有方向有数值的量,在这里的向量指的是中断向量表,中断向量表之前已经讨论过,向量表中存储的是中断服务函数的地址,当有中断信号产生时,会从中断向量表中找到相应的中断函数的地址,然后跳转到该函数执行,流程如下图
第5课【中断与NVIC】中断 NVIC 优先级 中断编程_第5张图片

NVIC寄存器结构体

NVIC寄存器结构体定义在固件库core_m3.h中,内容如下

typedef struct
{
	__IO uint32_t ISER[8];		// 中断使能寄存器
	uint32_t RESERVED0[24];
	__IO uint32_t ICER[8];		// 中断清除寄存器
	uint32_t RESERVED1[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 uint32_t IP[240];		// 中断优先级寄存器(8bit)
	uint32_t RESERVED5[644];	
	__IO uint32_t STIR;			// 软件触发中断寄存器
}NVIC_Type;

实际中断的配置流程中,一般只用到ISER、ICER和IP三个寄存器,ISER寄存器用来使能中断,ICER寄存器用来失能中断,IP用来设置中断的优先级

NVIC寄存器相关库函数

在库函数头文件core_m3.h中除了提供NVIC寄存器结构体的定义,还提供了用来操作寄存器的库函数,这些函数遵循CMSIS的规则,这意味着只要是Cortex-M3处理器,这些函数都可用
第5课【中断与NVIC】中断 NVIC 优先级 中断编程_第6张图片
但这些库函数一般都很少用到,因为还有更简洁的方法去配置寄存器

中断优先级寄存器和中断优先级设置库函数

NVIC有一个专门用于配置中断优先级的寄存器NVIC_IPRx,IPR寄存器的位数为8位,理论上可配置的中断优先级可以是0~255,但大多数的单片机系统,都会将中断优先级简化,STM32 F103中只是用到了IPR的高4位在这里插入图片描述
通过内核外设SCB程序中断及复位控制寄存器AIRCR,其中的PRIGROUP[10:8]设置位,可以将中断根据优先级进行分组,虽然IPR寄存器仅有4位,但通过与PRIGROUP的前3位配合,可以将这4位分别设置成主优先级和子优先级 ,共5组,详细可见下表
第5课【中断与NVIC】中断 NVIC 优先级 中断编程_第7张图片
和中断相关的库函数全部都在misc.c和misc.h里面,以下是优先级分组的解析和设置优先级库函数NVIC_PriorityGroupConfig()详细内容
第5课【中断与NVIC】中断 NVIC 优先级 中断编程_第8张图片

// 设置中断优先级
// NVIC_PriorityGroup_0: 0bit for Main Interupt
// 						 4bit for Sub  Interupt
// NVIC_PriorityGroup_1: 1bit for Main Interupt
// 						 3bit for Sub  Interupt
// NVIC_PriorityGroup_2: 2bit for Main Interupt
// 						 2bit for Sub  Interupt
// NVIC_PriorityGroup_3: 3bit for Main Interupt
// 						 1bit for Sub  Interupt
// NVIC_PriorityGroup_4: 4bit for Main Interupt
// 						 0bit for Sub  Interupt
//
// If Enabled NVIC_PriorityGroup_0,All bit will Work As Sub Interupt
void PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
	SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup
}

中断编程

将中断的思想通过库函数体现到函数中,一般要经过一下的过程:

  1. 想使能某个中断,首先要明确其寄存器的使能中断位。再需要根据需求是开启外设的中断
  2. 初始化NVIC_InitType结构体,设定中断源,设定中断优先级(包括主优先级和子优先级),最后使能中断
    以下是NVIC_InitType结构体的详细内容
typedef struct
{
	uint8_t NVIC_IRQChannel;					// 中断源
	uint8_t NVIC_IRQChannelPreemptionPriorty;	// 中断主优先级
	uint8_t NVIC_IRQChannelSubPriorty;			// 中断子优先级
	FunctionableState NVIC_IRQChannelCmd		// 中断使能/失能
;}

NVIC_InitType结构体中有4个成员,它们分别代表了:

  • NVIC_IRQChannel:用来设置中断源。中断源如果写错,并不会报错,而是会导致原本要相应的中断不工作,而其他意料之外的中断会工作的后果。NVIC_IRQChannel可设置的内容可以在头文件stm3210x.h定义的中断源结构体IRQn_Type中查询到
  • uint8_t NVIC_IRQChannelPreemptionPriorty:用来设置中断主优先级,具体可以查看上表
  • uint8_t NVIC_IRQChannelSubPriorty:用来设置中断子优先级,具体可以查看上表
  • FunctionableState NVIC_IRQChannelCmd:用来设置中断使能/失能,主要是通过设置NVIC_ISER和NVIC_ICER寄存器来实现
  1. 最后编写中断服务函数,当系统响应中断时,会通过中断向量表找到并执行这个函数。原先在启动文件startup_stm3210x_hd.s中设置的空函数,为的是去初始化中断向量表,如果中断向量表中的函数指向错误,那么很可能会使系统陷入死循环

基本知识框架Xmind文件下载

链接:资源下载

你可能感兴趣的:(STM32,c语言)