STM32-07-STM32_外部中断

文章目录

  • STM32 中断系统
    • 1. 中断
    • 2. NVIC
    • 3. EXTI
    • 4. AFIO
    • 5. 中断配置步骤
    • 6. 外部中断代码

STM32 中断系统

1. 中断

  • 目的:中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。
  • 中断过程:当CPU正在处理某事件的时候外界发生了紧急事件请求 中断发生,要求CPU暂停当前的工作,转而去处理这个紧急事件 中断响应和中断服务,处理完以后,再回到原来被中断的地方,继续原来的工作 中断返回
  • 中断系统:实现中断功能的部件称为中断系统,请求CPU中断的请求源称为中断源。微型机的中断系统一般允许有多个中断源,当几个中断源同时向CPU请求中断,要求它服务的时候,这就存在CPU优先响应哪个中断源请求的问题。因此设置中断优先级,CPU总是先响应优先级别最高的中断请求。
  • 作用与意义
    1. 实时控制
    2. 故障处理
    3. 数据传输

2. NVIC

  • 什么是NVIC?

    Nested vectored interrupt controller 即嵌套向量中断控制器,属于内核。

    支持256个中断,其中包含了16个系统中断和240个外部中断,并且具有256级的可编程中断设置。

    对于STM32F103ZET6的系统中断10个,外部中断60个,16中断优先级

    特性:

    • 68个可屏蔽中断通道
    • 16个可编程的优先等级
    • 低延时的异常和中断处理
    • 电源管理的控制
    • 系统控制寄存器的实现
  • NVIC相关寄存器介绍

    NVIC相关寄存器位数寄存器个数备注
    中断使能寄存器(ISER)328每个位控制一个中断
    中断失能寄存器(ICER)328每个位控制一个中断
    应用程序中断及复位控制寄存器(AIRCR)321位[10:8]控制优先级分组
    中断优先级寄存器(IPR)82408个位对应一个中断,而STM32只使用高4位
  • 工作原理

    内核中断是不可屏蔽中断,直接由SHPR决定优先级,外部中断过来以后,会首先经过ISERICER寄存器进行使能或者失能,之后由IPR寄存器确定优先级,然后去抢占CPU执行中断。
    在这里插入图片描述

  • 中断优先级

    • 抢占优先级:高抢占优先级可以打断正在执行的低抢占优先级中断
    • 响应优先级:当抢占优先级相同时,响应优先级高的先执行,但是不能互相打断
    • 自然优先级:中断向量表的优先级
    • 抢占和响应优先级相同时,自然优先级高的先执行,数值越小,表示优先级越高
  • 优先级分组

    优先级分组AIRCR[10:8]IPRx bit[7:4]分配分配结果
    0111None :[7:4]0位抢占优先级,4位响应优先级
    1110[7] :[6:4]1位抢占优先级,3位响应优先级
    2101[7:6] :[5:4]2位抢占优先级,2位响应优先级
    3100[7:5] :[4]3位抢占优先级,1位响应优先级
    4011[7:4] :None4位抢占优先级,0位响应优先级
  • NVIC的使用

    1. 设置中断分组 SCB_AIRCR
    2. 设置中断优先级 NVIC_IPRx
    3. 使能中断 NVIC_ISER

3. EXTI

  • 什么是EXTI?

    External interrupt/event Controller 即外部中断/事件控制器,由20个产生事件/中断请求的边沿检测器组成,非互联型产品有19个边沿检测器。每个输入线可以独立地配置输入类型和对应的触发事件。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。

  • 特性:

    • 每个中断/事件都有独立地触发和屏蔽
    • 每个中断线都有专用的状态位
    • 支持多达20个软件的中断/事件请求
    • 检测脉冲宽度低于APB2时钟宽度的外部信号
  • 框图
    在这里插入图片描述

    功能框图包含两条主线:一是由输入线到NVIC中断控制器,二是由输入线到脉冲发生器。这就是EXTI的两大功能,产生中断与产生事件,两者从硬件上就存在不同。

    输入线是线路的信息输入端,它可以通过配置寄存器设置为任何一个GPIO口,或者是一些外设的事件。输入线一般都存在电平变化的信号。

    ①:边缘检测上升沿触发选择寄存器(EXTI_RTSR)和下降沿触发选择寄存器(EXTI_FTSR)。边沿检测电路以输入线作为信号输入端,如果检测到边缘跳变,就输出有效信号1,有效信号1会传输到②电路。

    ②:软件触发,两个信号输入端分别为软件中断事件寄存器(EXTI_SWIER)和边沿检测电路的输入信号。或门电路只要输入有效信号1,就会把有效信号输入到③和④电路。通过对软件中断事件寄存器的读写操作就可以启动中断/事件线。

    ③:中断屏蔽/清除,两个信号输入端分别为中断屏蔽寄存器(EXTI_IMR)和②电路,与门电路要求输入都为‘1’才输出‘1’,这样子的情况下,如果中断屏蔽寄存器EXTI_IMR)设置为0时,不管从标号②电路输出的信号特性如何,最终标号③电路输出的信号都是0;假如中断屏蔽寄存器(EXTI_IMR)设置为1时,最终标号③电路输出的信号才由标号②电路输出信号决定,这样子就可以简单控制EXTI_IMR来实现中断的目的。标号④电路输出‘1’就会把请求挂起寄存器(EXTI_PR)对应位置1。

    ④:事件屏蔽请求挂起寄存器(EXTI_PR)的内容就输出到 NVIC 内,实现系统中断事件的控制。

4. AFIO

  • Alternate Function IO,即复用功能IO,主要用于重映射和外部中断映射配置

    寄存器AFIO_EXTICR1~4,配置EXTI中断线0~15具体对应哪个IO口

  • EXTI与IO对应关系
    在这里插入图片描述

5. 中断配置步骤

在这里插入图片描述

  • EXTI配置步骤:
    1. 使能GPIO时钟
    2. 设置GPIO工作模式
    3. 使能AFIO
    4. 设置EXTI和IO对应关系
    5. 设置EXTI屏蔽,上下沿
    6. 设置NVIC
    7. 设计中断服务函数

  • HAL库配置步骤:

    1. 使能GPIO时钟

      __HAL_RCC_GPIOx_CLK_ENABLE();
      
    2. GPIO/AFIO/EXTI配置

      HAL_GPIO_Init();
      
    3. 设置中断分组

      HAL_NVIC_SetPriorityGrouping();
      
    4. 设置中断优先级

      HAL_NVIC_SetPriority();
      
    5. 使能中断

      HAL_NVIC_EnableIRQ();
      
    6. 设计中断服务函数

      EXTIx_IRQHandler();
      
    7. 编写中断处理回调函数

      HAL_GPIO_EXTI_Callback();
      
  • 中断回调处理机制
    在这里插入图片描述

6. 外部中断代码

Exti.h

#ifndef _EXTI_H
#define _EXTI_H#include "./SYSTEM/sys/sys.h"void exti_init(void);#endif

EXTI.c

#include "./BSP/EXTI/exti.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"//外部中断初始化
void exti_init(void)
{GPIO_InitTypeDef gpio_init_struct;//1.打开GPIO的时钟__HAL_RCC_GPIOE_CLK_ENABLE();//2.配置GPIOgpio_init_struct.Pin = GPIO_PIN_4;gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;gpio_init_struct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOE, &gpio_init_struct);gpio_init_struct.Pin = GPIO_PIN_3;gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;gpio_init_struct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOE, &gpio_init_struct);gpio_init_struct.Pin = GPIO_PIN_2;gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;gpio_init_struct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOE, &gpio_init_struct);gpio_init_struct.Pin = GPIO_PIN_0;gpio_init_struct.Mode = GPIO_MODE_IT_RISING;gpio_init_struct.Pull = GPIO_PULLDOWN;HAL_GPIO_Init(GPIOA, &gpio_init_struct);//4.设置中断优先级HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0);HAL_NVIC_SetPriority(EXTI3_IRQn, 3, 0);HAL_NVIC_SetPriority(EXTI2_IRQn, 4, 0);HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0);//5.使能中断HAL_NVIC_EnableIRQ(EXTI4_IRQn);HAL_NVIC_EnableIRQ(EXTI3_IRQn);HAL_NVIC_EnableIRQ(EXTI2_IRQn);HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}void EXTI4_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_4);
}void EXTI3_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_3);
}void EXTI2_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_2);
}void EXTI0_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0);
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{ delay_ms(20);switch(GPIO_Pin){case GPIO_PIN_0: if(KEY_UP == 1)LED0(0); break;case GPIO_PIN_2:if(KEY2 == 0)            LED0(1); break;case GPIO_PIN_3: if(KEY1 == 0)LED1(0); break;case GPIO_PIN_4: if(KEY0 == 0)LED1(1); break;default : break;}
}

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/EXTI/exti.h"int main(void)
{HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72);                     /* 延时初始化 */led_init();                         /* LED初始化 */key_init();     //按键初始化beep_init();    //蜂鸣器初始化exti_init();    //外部中断初始化while(1){     }
}

声明:资料来源(战舰STM32F103ZET6开发板资源包)

  1. Cortex-M3权威指南(中文).pdf
  2. STM32F10xxx参考手册_V10(中文版).pdf
  3. STM32F103 战舰开发指南V1.3.pdf
  4. STM32F103ZET6(中文版).pdf
  5. 战舰V4 硬件参考手册_V1.0.pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/700155.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java构造方法详解

在Java方法内部定义一个局部变量时,必须要初始化,否则就会编译失败,如下: 要让上述代码通过编译,只需在使用a之前给a赋一个初始值即可 如果是对象:下面用一个日期类演示 我们没有给年月日赋值,…

优雅谈论大模型7:重新审视神经网络

这个专栏围绕着大模型的基本知识点深入浅出,章节之间的联系较为紧密。若在某个环节出现卡点,可以回到如何优雅的谈论大模型重新阅读。而斯坦福2024人工智能报告解读则为通识性读物。若对于如果构建生成级别的AI架构则可以关注AI架构设计专栏。技术宅麻烦…

springboot房屋租赁系统

摘要 房屋租赁系统;为用户提供了一个房屋租赁系统平台,方便管理员查看及维护,并且可以通过需求进行设备信息内容的编辑及维护等;对于用户而言,可以随时进行查看房屋信息和合同信息,并且可以进行报修、评价…

【C++】学习笔记——继承_2

文章目录 十二、继承5. 继承与友元6. 继承与静态成员7. 复杂的菱形继承及菱形虚拟继承 未完待续 十二、继承 5. 继承与友元 友元关系不能继承,也就是说父类友元不能访问子类私有和保护成员 。除非子类也设置成友元。 6. 继承与静态成员 父类定义了 static 静态成…

干最毒的事,做最靓的仔,贾诩为何会被称为“汉末第一毒士”?

两汉各有一毒士,西汉陈平,东汉贾诩。 啥叫“毒士”呢?就是那种专出那种缺德的招术、招招要人命的参谋、秘书。 这种人,对于他们的老板来说,那是绝对是嘎嘎好使,因为一出手就能起到立竿见影的效果。但是&a…

IC卡16个扇区详解:揭秘智能卡的存储结构

目录标题 IC卡的基本结构扇区的划分扇区的功能扇区的安全性扇区的应用NFC卡和IC卡,从外观怎样区分总结 在智能卡的世界里,IC卡(Integrated Circuit Card)以其安全性和便捷性成为了现代生活中不可或缺的一部分。无论是用于支付、身…

基于正点原子的FreeRTOS学习笔记——任务挂起与恢复

目录 学习目标: 学习笔记: 一、什么是挂起 二、任务挂起 三、任务恢复 四、中断中恢复任务 1、中断任务恢复函数 2、优先级说明 实验代码: 一、任务 二、中断 学习目标: 掌握任务的挂起与恢复 学习笔记: …

手撸XXL-JOB(二)——定时任务管理

在上一节中,我们介绍了SpringBoot中关于定时任务的执行方式,以及ScheduledExecutorService接口提供的定时任务执行方法。假设我们现在要写类似XXL-JOB这样的任务调度平台,那么,对于任务的管理,是尤为重要的。接下来我们…

C++语法|深入理解 new 、delete

在开发过程中,非常重要的语法就有我们new和delete,周所周知在C中最为强大的能力就是对内存的控制,所以我们再怎么强调new和delete都不为过 文章目录 1.new和delete基本语法new和malloc的区别是什么?(1)开辟单个元素的内存差别(2)开…

DGC-GNN 配置运行

算法 DGC-GNN,这是一种全局到局部的图神经网络,用于提高图像中2D关键点与场景的稀疏3D点云的匹配精度。与依赖视觉描述符的方法相比,这种方法具有较低的内存需求,更好的隐私保护,并减少了对昂贵3D模型维护的需求。DGC-…

卡片笔记写作法 精读笔记 01

元数据 卡片笔记写作法:如何实现从阅读到写作 书名: 卡片笔记写作法:如何实现从阅读到写作作者: 申克阿伦斯简介: 卢曼的“盒中笔记”通常很简短,因为这些只是他庞大繁杂研究中的索引,等需要时&…

工作太闲怎么办?有没有什么副业推荐?

如果您的工作太闲,可以考虑参加一些副业,利用您的空余时间进行一些有意义的活动。以下是一些副业建议 1. 在线兼职 可以通过一些在线平台寻找兼职工作,如做在线调查、参与评估、进行数据输入等。 2.做任务 还可以做下百度的致米宝库&#…