目录

1 EXTI控制器

2 NVIC控制器

3 code


中断,在单片机中占有非常重要的地位。代码默认地从上向下执行,遇到条件或者其他语句,会按照指定的地方跳转。而在单片机执行代码的过程中,难免会有一些突发的情况需要处理,这样就会打断当前的代码,待处理完突发情况之后,程序会回到被打断的地方继续执行。

1 EXTI控制器

外部中断/事件控制器(EXTI)管理了控制器的 23 个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

外部信号进入经过1的边沿检测电路,检测是否符合(有2和3的上升沿和下降沿选择寄存器决定),产生信号,然后和4软件中断事件寄存器或值,(在这里也就说可以写入软件中断事件寄存器模拟中断和事件),之后产生信号一分为二,看5中断屏蔽寄存器和7事件屏蔽寄存器,如果中断和事件都没有屏蔽,首先会产生事件,进入脉冲发生器。其次,会进入6挂起寄存器,然后进入NVIC。

注意:

1、上面说,我们可以使用寄存器4软件模拟中断事件寄存器模式符合条件的信号进入,为什么不能用6寄存器呢?因为

寄存器是可读可清除的寄存器,通过写1清除。写0无效。所以不能使用

2、关于挂起寄存器,挂起就是,证明有了中断,会在触发中断。但是不会硬件清除。

只能软件清除,或者修改边沿极性的时候清除。如下

先说EXTI吧,

EXTI 控制器的主要特性:

  • 每个中断/事件线上都具有独立的触发和屏蔽
  • 每个中断线都具有专用的状态位
  • 支持多达23个软件事件/中断请求
  • 检测脉冲宽度低于APB2 时钟宽度的外部信号

下图是ST207的框架图

下图为翻译版

从图中看出和外部中断有关的寄存器有:上升沿触发选择、下降沿触发选择、软件中断事件寄存器、中断屏蔽寄存器、挂起请求寄存器、事件屏蔽寄存器和NVIC中断控制寄存器等。此外就是对输入线的理解了。

另外七根 EXTI 线连接方式如下

也就是说对于一个外部中断线可以和多个GPIO相连,当你要使用哪一个IO的时候只要对SYSCFG_EXTICR对应的位设置就好了,在中断屏蔽寄存器或事件屏蔽寄存器对应位可以设置使用哪一个中断线

注:ST的使用SYSCFG_EXTICR来配置,GD的采用AFIO寄存器(在GPIO寄存器中)

EXTI是外部中断吧,上面的主要是针对的这22条中断线的说明,我们还知道还是有很多中断的,比如定时器中断,串口中断等等,他们不属于这22条中断线。

我们可以在中断向量表中看到

其他的中断配置都在各个模块的寄存器中了

2 NVIC控制器

在上面的EXTI寄存器都设置好后就可以设置NVIC了,关于NVIC的芯片编程手册上描述较少,但是说了

所以我们就参考一下M3手册吧

找到AIRCR寄存器,其中8到10位为优先级分组

我们在代码中使用的库函数是

void NVIC_PRIGroup_Enable(uint32_t NVIC_PRIGroup)
{/*Set the priority grouping value */SCB->AIRCR =AIRCR_VECTKEY_MASK | NVIC_PRIGroup;
}

其中我们查到

1、SCB->AIRCR在库函数的地址是0XE000ED0C,不懂的如何查询的,请自行百度

2、查到SCB的结构体定义

我们看到SCB是SystemControl Block的简写

下面我们说一下分组的取值

在misc.c中有

*   ==========================================================================================================================*      NVIC_PriorityGroup   | NVIC_IRQChannelPreemptionPriority |NVIC_IRQChannelSubPriority  |       Description*   ==========================================================================================================================*     NVIC_PriorityGroup_0  |                0                  |           0-15             | 0 bits for pre-emption priority*                          |                                   |                            | 4 bits for subpriority*   --------------------------------------------------------------------------------------------------------------------------*     NVIC_PriorityGroup_1  |                0-1                |           0-7              | 1 bits for pre-emption priority*                          |                                   |                            | 3 bits for subpriority*   --------------------------------------------------------------------------------------------------------------------------  *     NVIC_PriorityGroup_2  |                0-3               |            0-3              | 2 bits for pre-emption priority*                           |                                   |                            | 2 bits for subpriority*   --------------------------------------------------------------------------------------------------------------------------  *     NVIC_PriorityGroup_3  |                0-7               |            0-1              | 3 bits for pre-emption priority*                           |                                   |                            | 1 bits for subpriority*   --------------------------------------------------------------------------------------------------------------------------  *     NVIC_PriorityGroup_4  |                0-15              |            0                | 4 bits for pre-emption priority*                           |                                   |                            | 0 bits for subpriority                      *   ==========================================================================================================================

抢占优先级& 响应优先级区别

  1. 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
  2. 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
  3. 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
  4. 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。

例子:

假定设置中断优先级组为2,然后设置

中断3(RTC中断)的抢占优先级为2,响应优先级为1。

中断6(外部中断0)的抢占优先级为3,响应优先级为0

中断7(外部中断1)的抢占优先级为2,响应优先级为0。

那么这3个中断的优先级顺序为:中断7>中断3>中断6

表现在代码中

NVIC_InitPara NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQ = IRQn;
NVIC_InitStructure.NVIC_IRQPreemptPriority =pri;
NVIC_InitStructure.NVIC_IRQSubPriority = pri1;
NVIC_InitStructure.NVIC_IRQEnable = ENABLE;
NVIC_Init(&NVIC_InitStructure);

分组0,那么pri的取值范围0~0,pri1的取值范围0~16

分组2,那么pri的取值范围0~4,pri1的取值范围0~4

分组4,那么pri的取值范围0~16,pri1的取值范围0~0

下面我们讲解一下NVIC寄存器

__IO uint8_t  IP[240]; //中断优先级控制的寄存器组

__IO uint32_t ISER[8]; //中断使能寄存器组

__IO uint32_t ICER[8]; //中断失能寄存器组

__IO uint32_t ISPR[8]; //中断挂起寄存器组

__IO uint32_t ICPR[8]; //中断解挂寄存器组

__IO uint32_t IABR[8]; //中断激活标志位寄存器组

中断优先级控制的寄存器组:IP[240]

全称是:InterruptPriority Registers

240个8位寄存器,每个中断使用一个寄存器来确定优先级。

比如:STM32F10x系列一共60个可屏蔽中断,使用IP[59]~IP[0]。

每个IP寄存器的高4位用来设置抢占和响应优先级(根据分组),低4位没有用到。

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

中断使能寄存器组:ISER[8]

作用:用来使能中断

32位寄存器,每个位控制一个中断的使能。STM32F10x只有60个可屏蔽中断,所以只使用了其中的ISER[0]和ISER[1]。

ISER[0]的bit0~bit31分别对应中断0~31。ISER[1]的bit0~27对应中断32~59;

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

中断失能寄存器组:ICER[8]

作用:用来失能中断

32位寄存器,每个位控制一个中断的失能。STM32F10x只有60个可屏蔽中断,所以只使用了其中的ICER[0]和ICER[1]。

ICER[0]的bit0~bit31分别对应中断0~31。ICER[1]的bit0~27对应中断32~59;

配置方法跟ISER一样。

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

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

作用:用来挂起中断

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

作用:用来解挂中断

static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn);
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn);
static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn);

中断激活标志位寄存器组:IABR[8]

作用:只读,通过它可以知道当前在执行的中断是哪一个

如果对应位为1,说明该中断正在执行。

static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)

3 code

一定要使能系统时钟

因为配置GPIO和中断线的映射关系需要SYSCFG

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource11);

只要用到外部中断,就一定要打开SYSCFG时钟

开源代码地址:

https://github.com/strongercjd/STM32F207VCT6/tree/master/09-EXTI

点击查看本文所在的专辑,STM32F207教程

关注公众号,第一时间收到文章更新。评论区不能及时看到,需要交流可以到公众号沟通

STM32 中断详解相关推荐

  1. stm32位操作详解

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

  2. STM32 定时器详解

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

  3. linux内核中断详解

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

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

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

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

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

  6. 【stm32】中断详解

    stm32中断的顺序: 1)初始化 IO 口. 2)开启 AFIO 时钟 3)EXTI配置. 4)NVIC配置. 5)编写中断服务函数. 1 NVIC中断优先级管理 CM3 内核支持 256 个中断, ...

  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. distill bert 相关问题
  2. Selenium自动化-清空输入框、输入内容、点击按钮
  3. 怎么查看笔记本内存条型号_笔记本配置参数怎么看 笔记本配置参数查看方法【详解】...
  4. FCKeditor的开发精简
  5. 您需要了解的有关UI测试的所有信息
  6. 1 linux网络诊断命令工具
  7. HDU1061 Rightmost Digit【快速模幂】
  8. python编程入门与案例详解-python编程入门知识练习
  9. 用Java实现断点续传(HTTP)
  10. Creo 由方程创建曲线
  11. QCC304x系列开发教程(实战篇) 之7.3 QCC3040之swift pair
  12. 第十七届时尚COSMO美容大奖盛大启动 亮点多维度升级,2020一起“美就出圈”
  13. android 音标的抓取 腾讯在线词典API
  14. 微信小程序解密出来是乱码的问题
  15. JavaScript实现京东首页轮播图
  16. KendoUI模板引擎 - 结合组件使用
  17. matlab db dbm dbfs,dbfs(dbfs和dbm的换算)
  18. NetStumbler 扫描SSID
  19. pytorch 输出中间层特征
  20. bibi下载的视频批量重命名

热门文章

  1. java 等待提示 事件_Java,Jsp点击事件后,出现等沙漏,处理等待状态时,有提示在动,适合任何事件使用...
  2. java数组硬盘读取,java中如何通过IO流将稀疏数组写入磁盘和从磁盘中读取,整行存,整行取...
  3. VMWare 虚拟机中安装 CentOS 7
  4. Java 算法 素数分解
  5. batch spring 重复执行_spring-batch – Spring批处理:重新启动作业,然后自动启动下一个作业...
  6. 一个事物两个方面的对比举例_《写作教练在你家》:推开写作之门第3课——对比的魔法...
  7. pycharm 修改默认的注释风格(reStructuredText风格、Google风格、Numpy风格)
  8. 网页撤销后ubuntu本地撤销
  9. NOIP前夕:noi.openjudge,滑雪
  10. 新浪sae平台进行数据库的连接