当前位置: 首页 > news >正文

STM32——外部中断(EXTI)

目录

前言

一、外部中断基础知识

二、使用步骤

 三、固件库实现

四、STM32CubeMX实现

总结



前言

        外部中断(External Interrupt,简称EXTI)是微控制器用于响应外部事件的一种方式,当外部事件发生时(如按键按下、传感器信号变化等),微控制器会暂时停止当前正在执行的程序,转而执行相应的中断服务程序(ISR),处理完中断后再回到原来的程序继续执行。STM32的外部中断是STM32微控制器中一个重要的功能,用于接收和处理来自外部设备的信号或事件,在一定程度上提升了系统的实时性能。STM32的每个GPIO(通用输入输出)端口都支持外部中断功能,这使得STM32能够灵活地处理各种外部事件。

        对中断概念不清晰的可以参考:什么是中断-CSDN博客


一、外部中断基础知识

        STM32 的每个 IO 都可以作为外部中断 的中断输入口,在STM32F103 的中断控制器支持 19 个外部中断/ 事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的 19 个外部中断分别为:

        线 0~15:对应外部 IO 口的输入中断。

        线 16:连接到 PVD 输出。

        线 17:连接到 RTC 闹钟事件。

        线 18:连接到 USB 唤醒事件。

外部的GPIO引脚与线0~15对应,16条中断线都可以映射给GPIO口,但是每条线只能映射给一个个端口,如0线已经映射给 PA0端口,则就不能再映射给Px0端口(x为B、C、D、E、F等),如下图所示:

STM32中断具有以下特性:

        1、每个中断/事件都有独立的触发和屏蔽:可以独立配置每个中断/事件的触发条件和屏蔽状态。

        2、每个中断线都有专用的状态位:可以方便地查询和清除中断请求的状态。

        3、支持多达20个软件的中断/事件请求:STM32F1系列等型号具有丰富的外部中断资源。

        4、 检测脉冲宽度低于APB2时钟宽度的外部信号:能够准确检测快速变化的外部信号。

二、使用步骤

初始化 IO 口为输入将需要用作外部中断的GPIO口配置为输入模式,并设置合适的上下拉电阻(如果需要)。

开启 AFIO 时钟使能GPIO和外部中断控制器的时钟。STM32的外部中断控制器的时钟通常挂载在APB2时钟组下。

设置 IO 口与中断线的映射关系通过配置AFIO(模拟功能输入输出)的寄存器,将GPIO口与外部中断线连接起来。STM32的GPIO端口号与外部中断号之间存在对应关系,如所有GPIO组的0管脚对应外部中断0。

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
// 如,把PA0与中断线line0连接起来
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

配置中断触发方式设置外部中断的触发方式(上升沿触发、下降沿触发或上升下降沿触发)。

typedef struct
{uint32_t EXTI_Line; // 中断线选择,EXTI_Line0~EXTI_Line15EXTIMode_TypeDef EXTI_Mode; //中断模式,可选值为中断 EXTI_Mode_Interrupt 和事件EXTI_Mode_EventEXTITrigger_TypeDef EXTI_Trigger; //触发方式,EXTI_Trigger_Falling,EXTI_Trigger_Rising,EXTI_Trigger_Rising_Falling。FunctionalState EXTI_LineCmd; //是否使能中断线
}EXTI_InitTypeDef;

初始化NVIC(嵌套向量中断控制器)配置中断分组,配置中断的优先级和使能中断。STM32支持抢占式优先级和子优先级,可以根据需要配置中断的优先级。

编写中断服务函数编写与中断号对应的中断服务函数,并在其中处理中断逻辑,在多条线共用的中断函数中需要添加具体判断。

EXPORT EXTI0_IRQHandler 
EXPORT EXTI1_IRQHandler 
EXPORT EXTI2_IRQHandler 
EXPORT EXTI3_IRQHandler 
EXPORT EXTI4_IRQHandler 
EXPORT EXTI9_5_IRQHandler 
EXPORT EXTI15_10_IRQHandler

 三、固件库实现

        配置PA0引脚为外部中断,下降沿触发中断。

//外部中断0配置
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE); //使能 PORTA,PORTE 时钟和使能 AFIO 时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IUP; //PA0 设置成输入,上拉
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA0GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructure); //初始化 EXTI 寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);//初始化 NVIC
}

        中断服务函数:

void EXTI0_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line0)!=RESET)//判断某个线上的中断是否发生 {//中断任务EXTI_ClearITPendingBit(EXTI_Line0); //清除 LINE0 上的中断标志位 }}

         其他相关函数:

        中断优先级分组,但凡涉及到中断,必须进行中断优先级分组,系统才能进行中断优先级的设定。

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置 NVIC 中断分组 2

四、STM32CubeMX实现

         同样配置上面固件库的内容。

         配置完成后,生成Keil工程,然后在其中编写中断服务函数。     

         可以在Keil中的任何地方实现该函数,系统会自动搜索识别,如下:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == GPIO_PIN_0){//中断任务实现}
}

        在这里,不需要在进行中断标志位的清除,系统已经帮我们处理好了(如上图所示),我们只需要完成中断任务的功能即可,但是我们需要判断中断线,即GPIO端口。


五、总结

        1、在配置外部中断时,需要确保GPIO口已经正确配置为输入模式,并且已经使能了相应的时钟。

        2、外部中断的触发方式(上升沿、下降沿或上升下降沿)需要根据实际应用场景进行选择。

        3、在中断服务函数中,需要尽快处理完中断逻辑并清除中断标志位,以避免中断嵌套或重复触发。

        4、中断服务函数应该快进快出,避免长时间在中断里跳不出来,影响系统实时性。

       5、尽量不要在中断服务函数里进行延时,特别是HAL_Delay()函数,具体原因请查阅:为什么在中断里调用HAL_Delay时会出现卡死的情况?

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【云原生】Job一次性任务详解
  • xss漏洞(二,xss靶场搭建以及简单利用)
  • 关于使用webflux开发思考
  • Animate软件基本概念:遮罩层和引导层
  • 【Python】解决Yolov8训练时,“OSError: [WinError 1455] 页面文件太小,无法完成操作”错误
  • [自学记录09*]关于模糊效果降采样优化性能的小实验
  • 【异常】npm install 出错几种解决方案
  • Git 的基本概念和使用方式。
  • 期权价格的奥秘:深入理解影响因素
  • C++入门基础知识(笔记):静态成员函数,所有对象共享同一个函数静态成员函数只能访问成员变量,类外访问不到私有静态成员函数
  • 河南萌新(2024)(河南农业大学)(旅途的终点)
  • 爬虫入门--了解相关工具
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
  • 密码学基础:搞懂Hash函数SHA1、SHA-2、SHA3(1)
  • Golang | Leetcode Golang题解之第328题奇偶链表
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • 【个人向】《HTTP图解》阅后小结
  • Apache Pulsar 2.1 重磅发布
  • CSS魔法堂:Absolute Positioning就这个样
  • express + mock 让前后台并行开发
  • JSONP原理
  • Mocha测试初探
  • mysql中InnoDB引擎中页的概念
  • passportjs 源码分析
  • PAT A1050
  • tensorflow学习笔记3——MNIST应用篇
  • Vue 重置组件到初始状态
  • 从setTimeout-setInterval看JS线程
  • 飞驰在Mesos的涡轮引擎上
  • 缓存与缓冲
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 配置 PM2 实现代码自动发布
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 深度学习中的信息论知识详解
  • 使用 @font-face
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 自制字幕遮挡器
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​如何防止网络攻击?
  • # 透过事物看本质的能力怎么培养?
  • #单片机(TB6600驱动42步进电机)
  • $(selector).each()和$.each()的区别
  • (02)vite环境变量配置
  • (2024最新)CentOS 7上在线安装MySQL 5.7|喂饭级教程
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (二) 初入MySQL 【数据库管理】
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (分享)自己整理的一些简单awk实用语句
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (四)图像的%2线性拉伸
  • (一)Java算法:二分查找
  • (转)负载均衡,回话保持,cookie
  • .FileZilla的使用和主动模式被动模式介绍
  • .gitignore文件_Git:.gitignore