STM32自学笔记(二)中断

一个完整的中断设置包括:使能,中断分组,屏蔽,IO口映射

NVIC中断优先级管理(这段具体写代码时不太会涉及,可跳过)

结构体NVIC_Type中有如下寄存器

  1. ISER[8]:中断使能寄存器组,为8个32位寄存器,控制CM3内核的256个中断

    由于STM32F103的可屏蔽中断只有60个,故我们只会用到 ISER[0]ISER[1] .

    ISER[0] 的bit0~bit31分别对应中断0~31,ISER[1] 的bit0~bit27分别对应中断32~59

    要使能某个中断,必须设置相应的ISER位为1。

  2. ICER[8]:中断除能寄存器组。每个位对应的中断与 ISER[8]相同,但作用相反,其用来清除某个中断的使能。之所以不直接向ISER写0来清除使能,是因为NVIC的寄存器都是写1有效,写0无效的。

  3. ISPR[8]:中断挂起控制寄存器组。每个位对应的中断与ISER[8]相同。通过置1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。

  4. ICPR[9]:中断解挂控制寄存器组。每个位对应的中断与ISER[8]相同,作用与ISPR相反,通过置1将挂起的中断解挂。

  5. IABR[8]:中断激活标志位寄存器组。每个位对应的中断与ISER[8]相同。这是一个只读寄存器,若某位值为1,表示该位所对应的中断正在被执行。通过IABR可以知道当前执行的中断是哪一个。在中断执行完毕后由硬件自动清零。

  6. IP[240]:中断优先级控制寄存器组。IP寄存器组由240个8bit的寄存器组成。每个可屏蔽中断占用8bit,这样总共可以表示240个可屏蔽中断。而STM32只用到其中的前60个。

    IP[59]~IP[0]分别对应中断59~0.

    同时每个可屏蔽中断占用的8bit实际上只用了高4位,这4位又分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。这两个优先级各占几个位要根据SCB->AIRCR中的中断分组设置来决定

STM32的中断分组:STM32将中断分为5个组,0~4.该分组的设置是由AIRCR寄存器的bit10~8来定义的。

具体的分配关系见下表

AIRCR[10:8] bit[7:4]分配情况 分配结果
0 111 0 : 4 0位抢占优先级,4位响应优先级
1 110 1 : 3 1位抢占优先级,3位响应优先级
2 101 2 : 2 2位抢占优先级,2位响应优先级
3 100 3 : 1 3位抢占优先级,1位响应优先级
4 011 4 : 0 4位抢占优先级,0位响应优先级

通过这个表,我们就可以清楚的看到组 0~4 对应的配置关系,例如组设置为 3,那么此时所有的 60 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是响应优先级。每个中断,你可以设置抢占优先级为 0~7,响应优先级为 1 或 0。

抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。

这里需要注意两点:第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级 中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。

设置中断优先级分组

调用格式如下

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_x); 

此函数的作用是对中断的优先级进行分组,在系统中只调用一次,确定后最好不要更改。

NVIC_PriorityGroup_x中的x代表组别,正如上面的表所表现的,分组范围为0~4,第几组x就是几。现在设置中断优先级分组为2,那么方法是

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

这样就确定了一共为2位抢占优先级,2位响应优先级

配置中断

首先讲解结构体NVIC_InitTypeDef,其拥有三个成员变量与一个使能

  1. NVIC_IRQChannel:定义初始化的是哪个中断。中断的名字在stm32f10x.h中找,

    常用的有USART1_IRQn(串口1)

  2. NVIC_IRQChannelPreemptionPriority: 定义这个中断的抢占优先级别

  3. NVIC_IRQChannelSubPriority: 定义这个中断的响应优先级别

  4. NVIC_IRQChannelCmd: 该中断是否使能

和配置GPIO的过程类似,进行NVIC的配置

NVIC_InitTypeDef   NVIC_InitStructure;		//首先实例化对象
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;		//串口 1 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为 1 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		// 子优先级位 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   		//IRQ 通道使能

配置完成后,对NVIC寄存器进行初始化

NVIC_Init(&NVIC_InitStructure); 	//根据上面指定的参数初始化 NVIC 寄存器 

总结

总结一下,中断设置有如下步骤

  1. 调用函数 NVIC_PriorityGroupConfig()进行中断分组,也就是确定抢占优先级和响应优先级分配的位数

  2. 实例化NVIC_InitTypeDef对象并进行参数设置,配置所用到中断的优先级别

  3. 对每个中断调用函数NVIC_Init()进行初始化

Tips:

进入中断要首先清除中断标志

你可能感兴趣的:(stm32自学笔记,stm32,中断,单片机)