STM32速成笔记—中断

news/2024/10/30 13:33:08/

文章目录

  • 一、什么是中断
  • 二、中断的相关概念
    • 2.1 中断优先级
    • 2.2 中断嵌套
    • 2.3 中断服务函数
    • 2.4 中断标志位
  • 三、外部中断EXIT
  • 四、中断程序配置
    • 4.1 设置中断分组并使能中断
    • 4.2 初始化EXIT
    • 4.3 编写中断服务函数
  • 五、注意事项

一、什么是中断

首先介绍一下什么是中断。在实际开发过程中,中断是很有必要的。比如需要针对某种特殊情况进行快速响应,单纯的使用一个while轮询似乎并不能满足。中断的概念非常好理解,举个经典例子。比如你在家里看电视,忽然有人敲门,你临时把电视暂停了,转去开门。开完门之后再次回来继续看电视。中断也就是这种流程。看电视的行为就类似于程序中main函数的while,轮询执行业务。忽然有人敲门,对应程序运行过程中忽然产生了一个中断请求。此时暂停电视,对应于此时程序中断当前的业务,转而去处理中断业务(开门)。最后,中断业务处理完成后,再继续执行main函数while轮询中的业务。简单用一个图来表示一下

中断概念示意图

根据中文参考手册的介绍,STM32F103ZET6除了一些特殊的中断外,常用的中断有60个,这些中断是通过中断控制器来有条不紊地分配执行的。

二、中断的相关概念

2.1 中断优先级

从字面意思来讲,优先级用来区分中断的响应顺序。当同时接收到多个中断请求时,中断控制器会根据中断优先级来决定中断处理的顺序,优先级高的会先被处理。如果在处理某个中断请求时又来了一个中断,这时会根据两个中断的中断优先级来确定处理方式。如果新来的中断优先级比当前中断的优先级高,则会停止对当前中断的处理,转而处理新的中断。反之,如果新来的中断优先级比当前中断的优先级低,则需要等到当前中断处理完成后,再去处理新来的中断。

中断优先级有两种,一种是抢占优先级,一种是响应优先级。响应优先级通常又被称为“亚优先级”或者“副优先级”。当两个中断的抢占优先级相同时,用相应优先级来决定中断的处理顺序。如果两个中断的抢占优先级和相应优先级相同,则根据芯片手册中的中断向量号来决定中断的处理顺序。比如同时来了两个中断请求,在抢占优先级和响应优先级均相同时,中断向量号为41的中断会比中断向量号为42的中断先被处理。

STM32提供了16个可编程的优先等级(使用了4位中断优先级),优先级分组可以使用库函数提供的NVIC_PriorityGroupConfig()设置。

2.2 中断嵌套

一些低优先级的中断可以被高优先级中断打断,这种情况叫做中断嵌套。

2.3 中断服务函数

中断服务函数就是在进入中断后需要执行的内容。中断服务函数有特定的函数名,可以在下图文件中搜索“IRQ”找到。
中断服务函数名

2.4 中断标志位

不同的中断会有对应的中断标志位,通常标志位默认值为0。当产生中断请求时,标志位被置1。比如设置一个串口接收完成中断,串口接收完成标志位初始值为0。当串口接收完成后对应的串口接收完成标志位会被置1。在中断服务函数中检测该标志位的值,来确定是否是串口接收完成中断产生了。每次中断服务函数执行结束后,需要清除一下对应的中断标志位。

三、外部中断EXIT

STM32F103ZET6有一个外部中断控制器(EXIT),可以支持20个软件的中断/事件请求,其中外部中断的EXIT0~EXIT15同坐IO中断。

外部中断IO对应

其他详细的介绍这里就不再说明。

四、中断程序配置

这里以配置PA0(按键WK UP)的外部中断为例,展示一下库函数开发时,外部中断的配置流程。关于其他中断的配置,后续使用其他外设时会单独介绍。

想要实现的效果是,利用外部中断实现按下WK UP,LED1点亮。

4.1 设置中断分组并使能中断

这里使用外部中断,需要开启AFIO时钟,设置IO与外部中断线的映射关系。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);   // 开启AFIO时钟GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);   //选择GPIO管脚用作外部中断线路

设置中断分组并使能中断时,库函数提供了一个结构体,我们直接配置这个结构体就可以了。

    //EXTI0 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;   //EXTI0中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;   //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;   //子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能NVIC_Init(&NVIC_InitStructure);	   //根据指定的参数初始化VIC寄存器

需要注意的是,配置优先级时,数值越大,优先级越低。

4.2 初始化EXIT

初始化EXIT时,库函数也提供了一个结构体,其中包括中断线,EXIT模式,触发方式以及EXIT使能或者失能。由按键检测一节了解到,WK UP按下时,会产生一个上升沿。因此触发方式我们选择上升沿触发。

    EXTI_InitStructure.EXTI_Line=EXTI_Line0;   // EXIT0EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;   // 中断EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;   // 上升沿触发EXTI_InitStructure.EXTI_LineCmd=ENABLE;   // 使能EXTI_Init(&EXTI_InitStructure);

整体配置函数如下

/**==============================================================================*函数名称:Exit_Init*函数功能:初始化外部中断*输入参数:无*返回值:无*备  注:无*==============================================================================*/
void Exit_Init (void)
{NVIC_InitTypeDef NVIC_InitStructure;EXTI_InitTypeDef  EXTI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);   // 开启AFIO时钟GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);   //选择GPIO管脚用作外部中断线路//EXTI0 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;   //EXTI0中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;   //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;   //子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能NVIC_Init(&NVIC_InitStructure);	   //根据指定的参数初始化VIC寄存器EXTI_InitStructure.EXTI_Line=EXTI_Line0;   // EXIT0EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;   // 中断EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;   // 上升沿触发EXTI_InitStructure.EXTI_LineCmd=ENABLE;   // 使能EXTI_Init(&EXTI_InitStructure);
}

4.3 编写中断服务函数

上面介绍了如何找中断服务函数的函数名,这里直接开始写中断服务函数。这里的中断服务函数比较简单,直接点亮LED1即可。

/**==============================================================================*函数名称:EXTI0_IRQHandler*函数功能:外部中断0中断服务函数*输入参数:无*返回值:无*备  注:无*==============================================================================*/
void EXTI0_IRQHandler(void)
{// 如果EXIT0中断标志位被置1if(EXTI_GetITStatus (EXTI_Line0)==1){Med_Led_StateCtrl (LED1,LED_ON);   // 点亮LED1}EXTI_ClearITPendingBit (EXTI_Line0);   // 清除中断标志位
}

至此,按下WK UP后,LED1会点亮。这种方法与之前的按键点亮LED有什么区别?之前的按键点亮LED是在main函数的while中实现的,而利用外部中断的方法,是在外部中断的中断服务函数中实现的。即使main函数的while轮询业务中没有按键业务,按键依旧可以起作用。

五、注意事项

  • 中断服务函数无需在.h文件中声明
  • 中断服务函数中不要有过长的业务
  • 中断服务函数最后需要清除中断标志位

http://www.ppmy.cn/news/416587.html

相关文章

[CF.Skills]在Pocket PC上编程设置壁纸

写下这篇帖子是来源于kevens的问题,如何编程设置壁纸? 我查看了msdn的一篇文章,提到了注册表中主题的位置,而且你也的确可以在你的设备上找到他. 但是又没有不操作注册表也能编程实现更换壁纸的功能呢? 当然是有的,msdn最后给出的一句PostMessege了给了我提示. 来看看代码吧:…

python实现动态壁纸_如何实现一个 windows 桌面动态壁纸

更新:2018/08/31 WS_MOUSE_LL 钩子,实现底层壁纸交互效果。 一、介绍 国内玩家第一次看到动态壁纸,都是出于一款来自 Wallpaper Engine 的 Steam 程序。它允许将视频、窗口小部件、甚至是有一定交互的网页放置到桌面最下方,2016 年初,被b站up主们广泛传播,被大家熟知。…

PC端网页制作

PC端网页制作 一、relative相对定位二、absolute绝对定位三、fixed和sticky及zlndex四、定位实现下拉菜单五、定位实现居中和装饰点六、css添加省略号七、css精灵及好处八、css圆角设置九、PC端企业类型整页制作1.PC端企业类型整页制作(1)2.PC端企业类型整页制作(2)3.PC端企业类…

【干货】ArcGIS的一些小技巧分享,值得学习!

1、ArcMap突然打不开了或者崩溃: 查看安全软件(例如360安全软件的拦截),是不是误删了ArcGIS相关文件。 2、ArcMap一些功能突然不能用 卸载安装的第三方插件,参见上一个问题 3、ArcMap启动慢 删除Normal.mxt文件&#x…

git在windows及linux(源码编译)环境下安装

git在windows及linux(源码编译)环境下安装 环境信息: 系统版本:CentOS Linux release 7.9.2009 (Core) git指令安装: yum install -y git 一、git在windows下安装 下载地址:https://git-scm.com/ 默认安装即可 验证 git --version 二、git在linux下安装 下载地址…

【Java之JAR包解析】(三)除核心包 rt.jar之外的其他JAR包~

JAR包解析之其他jar包 前言:one: access-bridge-64.jar:two: charsets.jar:three: cldrdata.jar:four: deploy.jar:five: jce.jar:six: jfr.jar:seven: jfxrt.jar:eight: jfxswt.jar:nine: jsse.jar:keycap_ten: localedata.jar11、management-agent.jar12、nashorn.jar13、plu…

计算机组成原理(考研408)练习题#3

用于复习408或计算机组成原理期末考试。如有错误请在评论区指出。 So lets start studying with questions! それでは、問題の勉強を始めましょう! 1. 定点整数原码编码[x]原1110100B 的真值为_________。 首先,1110100B是一个8位二进制数&#xff0c…

flutter:网络请求、json数据转为Model

参考 老孟 flutter: 网络请求-dio http http 是一个可组合,基于Future的库,用于HTTP请求。该软件包包含高级功能和类,可轻松使用HTTP资源。它是多平台的,并且支持移动设备,台式机和浏览器。此软件包为官…