stm32中断的顺序:
1)初始化 IO 口。
2)开启 AFIO 时钟
3)EXTI配置。
4)NVIC配置。
5)编写中断服务函数。

1 NVIC中断优先级管理

CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。但 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。TM32 有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,具有 16 级可编程的中断优先级。而我们常用的就是这 68 个可屏蔽中断,但是 STM32 的 68 个可屏蔽中断,在 STM32F103 系列上面,又只有 60 个(在 107 系列才有 68 个)

1.1 NVIC寄存器

在core_cm3.h中,与 NVIC 相关的寄存器定义了如下的结构体:

typedef struct
{__IO uint32_t ISER[8];                      /*!< Offset: 0x000  Interrupt Set Enable Register           */uint32_t RESERVED0[24];                                   __IO uint32_t ICER[8];                      /*!< Offset: 0x080  Interrupt Clear Enable Register         */uint32_t RSERVED1[24];                                    __IO uint32_t ISPR[8];                      /*!< Offset: 0x100  Interrupt Set Pending Register          */uint32_t RESERVED2[24];                                   __IO uint32_t ICPR[8];                      /*!< Offset: 0x180  Interrupt Clear Pending Register        */uint32_t RESERVED3[24];                                   __IO uint32_t IABR[8];                      /*!< Offset: 0x200  Interrupt Active bit Register           */uint32_t RESERVED4[56];                                   __IO uint8_t  IP[240];                      /*!< Offset: 0x300  Interrupt Priority Register (8Bit wide) */uint32_t RESERVED5[644];                                  __O  uint32_t STIR;                         /*!< Offset: 0xE00  Software Trigger Interrupt Register     */
}  NVIC_Type;

ISER[8]:
Interrupt Set-Enable Registers,这是一个中断使能寄存器组。上面说了 CM3 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。但是STM32F103 的可屏蔽中断只有 60 个,所以对我们来说,有用的就是两个(ISER[0]和 ISER[1]),总共可以表示 64 个中断。而 STM32F103 只用了其中的前 60 位。ISER[0]的 bit0 ~ bit31 分别对应中断 0 ~ 31。ISER[1]的 bit0 ~ 27 对应中断 32~59;这样总共 60 个中断就分别对应上了。你要使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO 口映射等设置才算是一个完整的中断设置)。
ICER[8]:
Interrupt Clear-Enable Registers,是一个中断除能寄存器组。该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和 ICER 一样。这里要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄存器都是写 1 有效的,写 0 是无效的。
ISPR[8]:
Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。每个位对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写 0 是无效的。
ICPR[8]:
Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。其作用与 ISPR 相反,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断接挂。写 0 无效。
IABR[8]:
Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。对应位所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。
IP[240]:
Interrupt Priority Registers,是一个中断优先级控制的寄存器组。这个寄存器组相当重要!STM32 的中断分组与这个寄存器组密切相关。IP 寄存器组由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。而 STM32 只用到了其中的前 60 个。IP[59] ~ IP[0]分别对应中断 59 ~ 0。而每个可屏蔽中断占用的 8bit 并没有全部使用,而是 只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。

1.2 NVIC分组简介

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

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

第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。
举例:假定设置中断优先级组为 2,然后设置中断 3(RTC 中断)的抢占优先级为 2,响应优先级为 1。中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。那么这 3 个中断的优先级顺序为:中断 7>中断 3>中断 6。
上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互
打断!

管理函数主要在 misc.c 文件里面。

1.3 设置中断分组

NVIC_PriorityGroupConfig()

NVIC 中断
这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次,一旦分
组确定就最好不要更改。这个函数我们可以找到其实现:

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{/* Check the parameters */assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

1.4 中断函数初始化

NVIC_Init()

对应的结构体如下

typedef struct
{uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.This parameter can be a value of @ref IRQn_Type (For the complete STM32 Devices IRQ Channels list, pleaserefer to stm32f10x.h file) */uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channelspecified in NVIC_IRQChannel. This parameter can be a valuebetween 0 and 15 as described in the table @ref NVIC_Priority_Table */uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specifiedin NVIC_IRQChannel. This parameter can be a valuebetween 0 and 15 as described in the table @ref NVIC_Priority_Table */FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannelwill be enabled or disabled. This parameter can be set either to ENABLE or DISABLE */
} NVIC_InitTypeDef;

NVIC_InitTypeDef 结构体中间有四个成员变量,这四个成员变量的作用是:

NVIC_IRQChannel:
定义初始化的是哪个中断,这个我们可以在 stm32f10x.h 中找到每个中断对应的名字。例如 USART1_IRQn。
NVIC_IRQChannelPreemptionPriority:
定义这个中断的抢占优先级别。
NVIC_IRQChannelSubPriority:
定义这个中断的子优先级别。
NVIC_IRQChannelCmd:
该中断是否使能。

对应的初始化函数如下

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;            //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;   //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;          //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

2 EXTI外部中断

2.1 外部中断简介

STM32 的每个 IO 都可以作为外部中断的中断输入口。STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的19 个外部中断为:
线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。

STM32 供 IO 口使用的中断线只有 16 个,但是 STM32 的 IO 口却远远不止 16 个,那么 STM32 是怎么把 16 个中断线和 IO 口一一对应起来的呢?
GPIO 的管脚 GPIOx.0 ~ GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 0~15。这样每个中
断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。

2.2 外部中断初始化

EXTI_Init()

2.3 初始化结构体

typedef struct
{uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.This parameter can be any combination of @ref EXTI_Lines */EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.This parameter can be a value of @ref EXTIMode_TypeDef */EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.This parameter can be a value of @ref EXTIMode_TypeDef */FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.This parameter can be set either to ENABLE or DISABLE */
}EXTI_InitTypeDef;

第一个参数是中断线的标号,取值范围为EXTI_Line0~EXTI_Line15。也就是说,这个函数配置的是某个中断线上的中断参数。
第二个参数是中断模式,可选值为中断 EXTI_Mode_Interrupt 和事件 EXTI_Mode_Event。
第三个参数是触发方式,可以是下降沿触发 EXTI_Trigger_Falling,上升沿触发 EXTI_Trigger_Rising,或者任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling。
最后一个参数就是使能中断线了。
我们设置好中断线和 GPIO 映射关系,然后又设置好了中断的触发模式等初始化参数。既
然是外部中断,涉及到中断我们当然还要设置 NVIC 中断优先级。

2.4 初始化实例

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);
EXTI_InitStructure.EXTI_Line=EXTI_Line15;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);     //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

3 中断处理函数

3.1 中断处理函数

中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中
断线 10-15 共用中断函数 EXTI15_10_IRQHandler。
在编写中断服务函数的时候会经常使用到两个函数:
一个函数是判断某个中断线上的中断是否发生(标志位是否置位):

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)

另一个函数是清除某个中断线上的中断标志位:

void EXTI_ClearITPendingBit(uint32_t EXTI_Line)

3.2 中断标志函数

固件库还提供了两个函数用来判断外部中断状态以及清除外部状态标志位的函数:

EXTI_GetFlagStatus 和 EXTI_ClearFlag

他们的作用和前面两个函数的作用类似。只是在 EXTI_GetITStatus 函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而EXTI_GetFlagStatus 直接用来判断状态标志位。

【stm32】中断详解相关推荐

  1. STM32 中断详解

    目录 1 EXTI控制器 2 NVIC控制器 3 code 中断,在单片机中占有非常重要的地位.代码默认地从上向下执行,遇到条件或者其他语句,会按照指定的地方跳转.而在单片机执行代码的过程中,难免会有 ...

  2. stm32位操作详解

    stm32位操作详解 STM32位操作原理 思想:把一个比特分成32位,每位都分配一个地址,这样就有32个地址,通过地址直接访问. 位操作基础 位运算 位运算的运算分量只能是整型或字符型数据,位运算把 ...

  3. STM32 定时器详解

    STM32 定时器详解 吃了一个猛亏,自己理解花了大半天时间,结果一看代码发现巨简单 算了,把自己理解的放上来吧 目录 STM32 定时器详解 前言 一.定时器种类和区分 二.时钟源 三.计数过程 3 ...

  4. linux内核中断详解

    linux内核中断详解 1.中断的硬件触发流程 外设:如果外设有操作或者有数据可用,那么就会产生一个电信号,这个电信号发送给中断控制器. 中断控制器:中断控制器接收到外设发来的电信号以后,进行进一步的 ...

  5. STM32开发 -- 外部中断详解

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/87376865 在讲三轴加速度计的时候,提到外部中断.接下来就看看中断为什么这 ...

  6. 【STM32学习笔记】(13)——外部中断详解

    EXTI 简介         EXTI(External interrupt/event controller)-外部中断/事件控制器,管理了控制器的 20 个中断/事件线.每个输入线可以独立地配置 ...

  7. STM32 SPI详解

    目录 1.SPI简介 2.SPI特点 2.1.SPI控制方式 2.2.SPI传输方式 2.3.SPI数据交换 2.4.SPI传输模式 3.工作机制 3.1.相关缩写 3.2.CPOL极性 3.3.CP ...

  8. STM32 GPIO 详解

    0. 实验平台 基于STM32F407ZG 1. GPIO 简介 1.1 简介 GPIO全称:General Purpose Input Output,即通用输入输出端口,一般用来采集外部器件的信息或 ...

  9. STM32 ADC详解

    目录 01.ADC简介 02.STM32的ADC外设 03.STM32ADC框图讲解 04.触发源 05.转换周期 06.数据寄存器 07.中断 08.电压转换 09.电路图设计 10.代码设计 01 ...

最新文章

  1. FPGA(3)验证数字逻辑(与门、与非门、二选一数据选择器、2-4译码器、半加器、全加器)
  2. 2.Java中String,StringBuilder以及StringBuffer的关系与区别
  3. Linux Watchdog 机制
  4. 思科Webex与下一代视频会议
  5. 进程handle获取线程_获取进程中的线程列表
  6. 如何将原图和json融合_双曲知识嵌入:如何将知识“融合”带入新空间?
  7. 水下自动循迹机器人_水下避碰!国内首艘自主航行系统实验船试水
  8. Google浏览器开发者工具:CSSViewer(一个Css查看器)
  9. 【网络安全工程师面试题】数据库存在的漏洞及渗透方法
  10. 【Tensorflow】【损失函数】交叉熵数据验证(下)---BinaryCrossentropy二分类
  11. 日期范围选择类日历(增强版)
  12. everything搭配什么软件_如果你在用Everything,那这个插件你一定会毫不犹豫就装上!...
  13. PR转场插件 MAC版 FilmImpact Transition Pack v1-v2
  14. Sketchup2019安装包安装教程
  15. 2018最佳计算机配置,2018年主流的组装电脑配置是什么样的?
  16. matlab java堆内存溢出,matlab内存溢出的解决方案
  17. c++将函数作为函数参数(函数指针)
  18. 1.4 Git基本操作之删除文件找回及文件比较
  19. android界面设计的解剖,ps cc 2017启动画面的制作解剖
  20. C/C++教师工资管理系统

热门文章

  1. 转载:播放器基本原理(播放四步法)
  2. bootstrap之carousel
  3. PR片头模板|光线扭曲时空穿梭LOGO片头视频模板
  4. 手机浏览器直接唤起微信方案调研
  5. 俄罗斯国家黑客组织 Gamaredon的成员身份和录音曝光(附视频)
  6. 《企业内部控制应用指引第7号——采购业务》全文及解读
  7. 电竞耳机推荐什么牌子好?黑科技加持HyperX夜鹰加强版,重新定义游戏电竞耳机
  8. 要远离邪淫否则危害很严重
  9. IREP_SOA Integration SOAP概述(概念)
  10. 女儿国最终解密--女儿国是谁的天下