分享

我在高职教STM32STM32中断概览重写版(由每个外设的相关中断使能位控制中断服务函数的函数名必须与启动文件预设的一样初始化头文件结构体)

 山峰云绕 2023-02-06 发布于贵州

  (由每个外设的相关中断使能位控制中断服务函数的函数名必须与启动文件预设的一样初始化头文件结构体)


https://m.toutiao.com/is/BDFP19W/ 



大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正是如此,才有了借助头条平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思设计的教学课件分享出来,如果您正是一名单片机爱好者或是一名同行,欢迎点赞+关注,各位的支持是本人持续输出的动力,多谢多谢!#30天学会STM32##STM32单片机##单片机#

【学习目标】

  1. 能从全局角度理解中断机制对单片机的重要性
  2. 明白中断源和中断服务函数在固件库中的规范
  3. 理解中断优先级分组的设计理念

中断可以说是单片机的“灵魂”,后续几乎所有实验都会涉及中断。因此,中断的讲解放在哪一个外设里面去讲都不合适,所以这里单独抽出一篇来做一个概括性的介绍,这样在其他外设涉及到中断部分知识的时候,就不用费很大的篇幅去讲解,只要示意性带过即可。

一、中断的产生背景

在前面的项目实践中,可以看到在经过初始化配置之后,程序会进入一个while(1)循环,这循环也称为主循环,实现任务功能的代码都是在主循环中完成的。那么可以试想一下,如果往主循环里塞进一大堆各种各样的任务(LED、数码管显示、按键扫描、串口收发、传感器采集等等),就好比让你一个人同时应付工作、带孩子、做饭、搞卫生,其结果必然是“顾此失彼”,也就无法实现想要的控制效果。

那要解决上述问题该怎么办呢?在现实生活中,你可以找保洁、保姆或父母帮忙;在单片机的世界里,能做到分身有术的“魔法”就是中断。中断是CPU处理外设(突发)事件的一种手段,当事件发生时,CPU会暂停当前的程序运行,转而去处理突发事件的程序(即中断服务函数),处理完之后又返回到中断点继续执行原来的程序。从一定程度上讲,中断几乎成了单片机的灵魂。如果没有中断,单片机执行起任务将“无所适从”。

中断这个词是咱们根据英文单词interrupt直译过来的,其实在开发体验上,它更像是助手,那下面咱们就来看看STM32一共有多少个中断助手。

二、STM32强大的中断响应系统

ARM的CM3内核支持256个中断,包括16个内核中断和240个外设中断,拥有256个中断优先级别。可以说这样的设计是颇有远见的,给未来预留了很大的拓展空间,毕竟需要的助手总会越来越多的。

STM32F103系列虽然使用的是CM3内核,但并没有使用其全部的中断资源。尽管如此,STM32中断还是非常强大的,每个外设都可以产生中断。把所有中断用一个表管理起来,如表1所示,表中带有灰色背景的为内核异常(10个),之后的60个称为外设中断,这个表就称为中断向量表。这张表没必要记,需要的时候回来查找即可。

表1 CM3内核的16个异常(中断)和STM32的60个外设中断

三、STM32中断的总管家——NVIC

STM32 的中断如此之多,配置起来并不容易,因此需要一个强大的“嵌套中断向量控制器NVIC(Nested Vectored Interrupt Controller)”来对中断进行管理。NVIC控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设,如图1所示。各芯片厂商在设计芯片的时候会对CM3内核里面的NVIC进行裁剪,把不需要的部分去掉。

图1 NVIC在内核中的位置

四、中断优先级管理很重要

下面咱们来重点解释一下NVIC字面意思里“中断嵌套”的含义,这其实是对中断优先级管理的一种方式。首先,STM32的中断优先级具有两个属性,一个为抢占优先级(又称主优先级),另一个为响应优先级(又称子优先级),其属性编号越小,表面它的优先级越高。其次,如果有多个中断同时响应,抢占优先级高的中断就会打断抢占优先级低的中断,即中断嵌套。如果抢占优先级相同,就根据响应优先级的高低来决定先处理哪一个。最后,如果抢占优先级和响应优先级都相同,就根据硬件中断编号顺序(表1中的第一列)来决定哪个先执行,硬件中断编号越小,优先级越高。

4.1 优先级管理方案

在STM32中,优先级由NVIC_IPRx寄存器来配置,这个寄存器是8位的,但只用了高4位来配置,最多支持16种中断优先级,并且有5种优先级分组方式,如表2所示。

表2 STM32的中断优先级的表示和分组

4.2 通俗理解优先级分组

关于中断优先级分组方案,可以拿生活中排队的场景来进行类比,如图2所示,其中每个人就好比是一个中断源。

图2 生活中的排队场景

1. NVIC_PriorityGroup_0(分组方案0)

无抢占优先级,即不允许任何人员插队,哪怕是特殊人群。这种情况仅由响应优先级决定,0号最高,15号最低,就好比是队伍最前和最后那个人。

2. NVIC_PriorityGroup_1(分组方案1)

有2种抢占优先级,可理解为特殊人群(老弱病残孕医军)与非特殊人群两类,特殊人群优先(插队)。每类人群内部的优先权由8种响应优先级决定,好比是军人还是孕妇优先。

3. NVIC_PriorityGroup_2(分组方案2)

有4种抢占优先级,比如从高到低依次为:军人、医生、老弱病残孕、其他常人。有4种响应优先级,比如来了一个残疾人和一个孕妇,同属一类人,按公德伦理,残疾人优先,即响应优先级高于孕妇。

4. NVIC_PriorityGroup_3(分组方案3)

有8种抢占优先级,与分组方案2类似,只是把插队人群的类别再细分了一下。有2种响应优先级,即同类人群中区分度就不明显了。

5. NVIC_PriorityGroup_4(分组方案4)

有16种抢占优先级,无响应优先级,这样就有了更多插队的情况发生。当然这种情况在现实中是不可接受的,人们彼此也不可能区分出究竟是老太太优先还是老头优先。

四、中断编程要点

在配置每个中断的时候,一般有3个编程要点:

1. 使能外设某个中断,这个具体由每个外设的相关中断使能位控制。

2. 初始化NVIC_InitTypeDef结构体,配置中断优先级分组,设置抢占优先级和响应优先级,使能中断请求。这个结构体定义见如下代码清单1。

代码清单1 NVIC初始化结构体

● NVIC_IRQChannel:用来设置中断源,不同中断源的名称不一样,且不可写错,即使写错了程序也不会报错,只会导致不响应中断。具体的成员配置可参考stm32f10x.h头文件里面的IRQn_Type枚举定义,我们摘录在代码清单2中。可以看出,中断源名字的命名方式为xxx_IRQn,记住这个规则很重要。

代码清单2 IRQn_Type枚举定义


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


NVIC_IRQChannelSubPriority:响应优先级,具体的值要根据优先级分组来确定,具体参考表2。

● NVIC_IRQChannelCmd:中断使能(ENABLE)或失能(DISABLE)。

3. 编写中断服务函数。在启动文件startup_stm32f10x_hd.s中,我们预先为每个中断都写了一个中断服务函数,只是这些函数都为空,如代码清单3所示,为的只是初始化中断向量表。从其中我们可以看出中断服务函数的命名规则为xxx_IRQHandler,这才是重点。

代码清单3 启动文件中定义好的中断入口名

实际的中断服务函数都需要我们重写,为了方便管理,ST官方建议(并不强制)把中断服务函数统一写在stm32f10x_it.c这个库文件中。最重要的是,中断服务函数的函数名必须与启动文件预设的一样,如果写错,那么系统就在中断向量表中找不到中断服务函数的入口,也就无法实现中断。而且要命的是,Keil编译不报错,这就给我们排错带来了不小困扰。因此编写中断代码时务必要注意。代码清单4是stm32f10x_it.c给的中断服务函数的编写模板,我们编写的时候只需要将其中的PPP换成需要的中断名并取消注释即可。

代码清单4 中断服务程序编写范例

(本文结束)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多