stm32学习笔记-中断系统

问题引入

问题引入:我们想通过 按键 控制灯亮 ,怎么做

一般做法:轮询

2b轮询例子:
2:吃了吗?B:没吃
2:吃了吗?B:没吃
2:吃了吗?B:吃了
2:吃了吗?B:…
2:吃了吗?B:滚!

具体做法
1 将GPIO口设为输入模式,
2 不断判断GPIO口的电平状态,从而得到是否按下按键
这样的 方式叫 “轮询”
轮询 有天生的 缺陷:

  1. 浪费CPU时间
  2. 查询GPIO口的状态时,占用总线

有人提出,能不能这样做,按下或弹起的时候,外设主动通知CPU,这就叫中断

1、中断系统概述。

日常中的中断,有更紧急的事情出现要去处理。比如说看电视的时候,电话响了,暂停电视听电话。

1.1 为什么要中断(中断意义)

  处理器的中断:在处理器中,中断是一个过程。在处理器正常执行程序时,出现内部/外部紧急事件需要去处理,处理器暂停当前的程序,去处理紧急事件,处理完毕后,返回被打断的程序处继续往下执行。
  中断可以提升CPU的处理效率,同时能堆突发事件做出实时的处理。实现程序的并行化,实现嵌入式系统进程之间的切换。

  中断不是动不动就用的,在特定的应用场合应用。

中断和轮询比较:

中断

  • 适于处理对响应要求非常高的事件
  • 适于处理持续事件非常短的事件
  • 适于低功耗的应用
  • 程序设计较复杂

轮询

  • 适于处理对时间响应要求低的场合
  • 程序设计简单

1.2 中断处理过程

在这里插入图片描述
中断处理的简略过程如下:

  1. 保护现场
    保护现场,寄存器的值压栈。

  2. 执行中断
    查询并执行对应的中断服务程序。通过中断向量去寻找中断服务程序。

  3. 返回现场
    恢复现场。

1.3 中断笔试题

中断是什么?请简述单片机中断处理的过程

CPU在正常执行程序的过程中,由于内部/外部事件的触发或程序的预先安排引起CPU暂时中断当前正在运行的程序,而转去执行中断服务子程序,待中断服务子程序执行完毕后,CPU继续执行原来的程序,这一过程称为中断;
中断处理的过程:
第一步:保护现场,将当前位置的PC地址压栈;
第二步:跳转到中断服务程序,执行中断服务程序;
第三步:恢复现场,将栈顶的值回送给PC;
第四步:跳转到被中断的位置开始执行下一个指令;

1.4 中断服务函数

相比于正常子函数,中断服务函数有什么特点和需要注意的地方?

1.相比正常的子函数,中断函数服务函数中不能有耗时的操作,最不能在中断服务函数中有延时函数。
2.不能有引起中断睡眠的函数。
3.不能递归调用自身。
4.在中断服务函数中不能出现可重入函数。比如printf。
5.中断服务函数中没有参数以及没有返回值。

2、STM32中断的体系结构。

2.1 结构框图

在这里插入图片描述
在这里插入图片描述
一个中断要被CPU响应必须通过两级:

  1. 自身外设中断源配置
  2. NVIC: 中断控制器。

每一个外设中断控制器(分管部门):外设中的每一个外设都有一个自己的中断开关,内核中的系统定时器等也有自己中断开关。能够产生中断的设备通过中断请求线(IRQ line)连到NVIC上面,所有能够产生中断的设备必须要有一根中断请求线。

NVIC(主管家):NVIC专门管理中断的,每一个中断都要在NVIC中挂号(使NVIC监听器中断请求)。NVIC收到外设的中断请求,会将其中断请求发送给内核,内核收到NVIC的中断通知之后,就会去判断时哪个中断发生,然后查找FLASH中断向量表去获取相应的中断处理函数。

举例:
由简单GPIO电平引起的中断,由部件脚EXTI(外部中断管理控制器)管理。
某个GPIO需要产生中断,若EXTI使能之后,EXTI会把中断的请求,通知给NVIC;
NVIC若对其使能,则NVIC把这个中断请求通知给CORTEX_M3;
最终由内核CORTEX_M3处理中断。

stm32所有的I/O都可以配置中断。

2.2 NVIC 内嵌向量中断控制器

Nested Vectored interrupt controller,NVIC属于M3内核的一个外设。这个NVIC专门用于管理中断,就像秦朝设立丞相那样减轻皇帝的负担,它帮助CM3处理器管理中断。

它的库函数在core_cm.3和misc.h

NVIC的作用

1、快。(男人就是要快!)
快速的运行的产品需要快,如高铁,飞机,导弹等产品。
2、标准化,同一化。
中断服务程序同一了,方便编程人员。

NVIC的主要功能。

  1. 中断管理。
  2. 支持异常及中断向量化处理。减少中断处理的一个时间。
  3. 支持嵌套中断。例如:一个中断发生了,另一个更加紧急的中断不久也发生了,可以打断当前中断的处理,去执行紧急程度更改的中断。

NVIC的中断优先级

STM32f03支持60个可屏蔽中断,每个中断具备自己的中断优先级控制字节(8位,但是只使用高4位),用于表达优先级的高4位被分为抢占式优先级和响应优先级。
所以STM32(Cortex-M3)中有两个优先级的概念-抢占式优先级(主优先级)和响应优先级(从优先级)。每个中断源都需要被指定这两种优先级。

中断被响应先后顺序:

  1. 抢占式优先级不同:
    高抢占式优先级的中断可以在具有低抢占式优先级的中断在执行的过程中可以被响应,即中断嵌套。(高抢占低)
  2. 抢占式优先级相同:
    当一个中断来到后,另一个中断正在被处理,后来的中断被挂起,等当前的中断处理完后才能被处理。(先来后到)
    当两个中断同时到达,且没有中断正被执行,则中断控制器根据它们的响应优先级高低来决定先处理哪个。
  3. 抢占式优先级,响应优先级都相同:
    根据它们在中断向量表的排位顺序决定先处理哪一个。(看最终位置)
  4. 中断优先级的数值越低,优先等级越高
    优先级越高,比如相应优先级为0和1的中断同时到达将会先响应优先级为0的中断。如果优先级为1的中断正在运行,这时0中断到达,将会先暂停1去执行0,等0执行完毕再回到1.

NIVC中配置中断的相关寄存器

中断号保存在 IPSR

中断优先级控制的寄存器组:IP[240]
因为M3内核最多有 240个可屏蔽的中断,所以有240个确定 中断优先级的寄存器 ,
每个IP寄存器是8位的, 高4位用来设置抢占和响应优先级(根据分组),
低4位没有用到
Stm32f10x有60个中断 ,所以用到了 IP[0]~IP[59]

中断使能寄存器组:ISER[8]
32位寄存器,每个位控制一个中断的使能。
STM32F10x只有60个可屏蔽中断,所以只使用了其中的ISER[0]和ISER[1]。
ISER[0]的bit0~bit31分别对应中断0 ~ 31。ISER[1]的bit0 ~ 27对应中断32 ~59;

中断失能寄存器组:ICER[8]
32位寄存器,每个位控制一个中断的失能。
STM32F10x只有60个可屏蔽中断,所以只使用了其中的ICER[0]和ICER[1]。
ICER[0]的bit0 ~ bit31分别对应中断 0 ~31。ICER[1]的bit0 ~ bit27 对应中断32 ~ 59;
配置方法跟ISER一样。

中断挂起控制寄存器组:ISPR[8]
作用:用来挂起中断

中断解挂控制寄存器组:ICPR[8]
作用:用来解挂中断

2.3 stm32NVIC中断优先级的配置

思路:

  1. 首先设置中断优先级分组。(整个系统执行过程中,只设置一次中断分组,若随意改变会导致中断管理混乱)
  2. 然后针对相应的中断,设置对应的抢占优先级和响应优先级。

系统运行后先设置中断优先级分组(4bits 空间 存储两个优先级)。

1.首先得对优先级进行分组。

调用函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
参数NVIC_PriorityGroup选择如下:

		NVIC_PriorityGroup_0    //抢占优先级占0bits, 响应优先级占4bits
		NVIC_PriorityGroup_1    //抢占优先级占1bits, 响应优先级占3bits
		NVIC_PriorityGroup_2    //抢占优先级占2bits, 响应优先级占2bits
		NVIC_PriorityGroup_3    //抢占优先级占3bits, 响应优先级占1bits
		NVIC_PriorityGroup_4    //抢占优先级占4bits, 响应优先级占0bits

举例:在设置为NVIC_PriorityGroup_2 时,抢占优先级有2^2=4个,同理响应优先级也有4个。
2. 针对每个中断,设置对应的抢占优先级和响应优先级。

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
typedef struct
{
  uint8_t NVIC_IRQChannel; //指定要初始化的中断通道(中断号)
  uint8_t NVIC_IRQChannelPreemptionPriority;//设置响应优先级,0~15数值越低,优先级越
  uint8_t NVIC_IRQChannelSubPriority; //设置抢占优先级,0~15数值越低,优先级越高
  FunctionalState NVIC_IRQChannelCmd; //ENABLE/DISABLE。禁止中断/使能中断
} NVIC_InitTypeDef;

注意:只能指定一个,不能使用 或运算符| 来初始化多个中断通道。

2.4 stm32中断配置思路

  1. 配置中断优先组。
    NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
  2. 配置中断优先级,开启中断通道。
    NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
  3. 配置使能相应外设的中断。
    不同外设的配置函数有差异。如外部中断使用EXTI_Init(),串口使用USART_ITConfig()。
  4. 编写相应中断的中断服务函数。
    xxx_IRQHanlder()

3、stm32F10x产品的向量表。

stm32有许多中断,用中断向量表对中断进行管理。中断向量表给每个中断分配一个地址。这个地址里面是一个跳转语句。可以看到每个向量占用4个字节。而这四个字节就可以存储一个跳转指令。
非阴影部分为外设的中断向量。4个字节
在这里插入图片描述
共60个外部中断。

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值