2.外部中断(EXTI)
理论
NVIC:嵌套向量中断控制器(解释教程)
外部通用中断线(EXTI0~EXTI15):每个GPIO设置成中断模式,与中断控制器连接的线
外部中断触发方式
上升沿触发、下降沿触发、双边沿触发
外部中断触发函数
在stm32f1xx_it.c文件里(大概204行)
| 中断触发函数 |
|---|
| EXTI0_IRQHandler |
| EXTI1_IRQHandler |
| EXTI2_IRQHandler |
| EXTI3_IRQHandler |
| EXTI4_IRQHandler |
| EXTI9_5_IRQHandler |
| EXTI15_10_IRQHandler |
解析
解析初始化中断过程
//gpio.c中58/*Configure GPIO pins : PEPin PEPin */GPIO_InitStruct.Pin = EXTI_Key1_Pin|EXTI_Key2_Pin;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); //将上面三行代码的数据传入这个函数解析初始化//stm32f1xx_hal_gpio.c中286
/*--------------------- EXTI Mode Configuration ------------------------*/
/* Configure the External Interrupt or event for the current IO */
if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
{
/* Enable AFIO Clock */
__HAL_RCC_AFIO_CLK_ENABLE(); //打开复用时钟
temp = AFIO->EXTICR[position >> 2u];
CLEAR_BIT(temp, (0x0Fu) << (4u * (position & 0x03u)));
SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4u * (position & 0x03u)));
AFIO->EXTICR[position >> 2u] = temp; //把固定引脚设置成复用模式(如复用成外部中断)//配置上升沿还是下降沿
/* Enable or disable the rising trigger */
if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
{SET_BIT(EXTI->RTSR, iocurrent);
}
else
{CLEAR_BIT(EXTI->RTSR, iocurrent);
}/* Enable or disable the falling trigger */
if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
{SET_BIT(EXTI->FTSR, iocurrent);
}
else
{CLEAR_BIT(EXTI->FTSR, iocurrent);
}/* Configure the event mask */
if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
{SET_BIT(EXTI->EMR, iocurrent);
}
else
{CLEAR_BIT(EXTI->EMR, iocurrent);
}//打开或关闭中断
/* Configure the interrupt mask */
if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
{SET_BIT(EXTI->IMR, iocurrent);
}
else
{CLEAR_BIT(EXTI->IMR, iocurrent);
}
中断实现过程
- 确认中断
- 清除中断标志位
- 执行中断回调函数

//stm32f1xx_it.:大概204行
void EXTI3_IRQHandler(void) //中断入口函数
{/* USER CODE BEGIN EXTI3_IRQn 0 *//* USER CODE END EXTI3_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(EXTI_Key1_Pin); //在库函数不能写/* USER CODE BEGIN EXTI3_IRQn 1 *//* USER CODE END EXTI3_IRQn 1 */
}void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) //stm32f1xx_hal_gpio.c:大概546行
{/* EXTI line interrupt detected */if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u) //判断有没有中断触发(有:1,没:0){__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); //若进来则为1,为1则清除中断标志位HAL_GPIO_EXTI_Callback(GPIO_Pin); //回调函数(Callback),执行函数}
}//stm32f1xx_hal_gpio.h中190
#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) //挂起寄存器(EXTI_PR)(参考手册140) 有没有中断触发//stm32f1xx_hal_gpio.h中198
#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) //赋值,(参考手册140)//调用这个函数,__weak:弱声明,若别文件也有相同的函数,优先调用没有弱声明
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //stm32f1xx_hal_gpio.c:大概561行
{/* Prevent unused argument(s) compilation warning */UNUSED(GPIO_Pin);/* NOTE: This function Should not be modified, when the callback is needed,the HAL_GPIO_EXTI_Callback could be implemented in the user file*/
}
若相同有一个PA0设置了中断,别的PB0等等都不能设置成中断

代码编写
实验:按键PE3控制蜂鸣器(PB8)、按键PE4控制LED灯(PB5)
Cube IDE代码
Cube IDE中编写
LED灯、蜂鸣器、按键配置
LED灯、蜂鸣器配置,上一篇已经说过,地址
按键设置下降沿触发(也可上升沿触发),GPIO Pull-up/Pull-down:设置上拉,空闲状态为高电平
按键没按下时高电平,按下时有下降沿和上升沿,所以两个触发都可,按键这里是中断触发功能,不是GPIO输入功能

配置NVIC(嵌套向量中断控制器)

调节不同中断优先级(数字越小优先级越高)
若抢占优先级相同,比较子优先级

调节多少bit对应代码在:
HAL_Init(); //main.c(74)//HAL_StatusTypeDef HAL_Init(void)中的
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); //stm32f1xx_hal.c(157)
代码
main.c:144行(在mian函数外任意一个 /* USER CODE BEGIN / / USER CODE END */中)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{//若需要延时需要将延时中断优先级比外部中断优先级高,优先级高才可以打断低优先级HAL_Delay(10);if(HAL_GPIO_ReadPin(EXTI_Key1_GPIO_Port, EXTI_Key1_Pin) == 0) //读引脚,相同=0,不同=1{HAL_GPIO_TogglePin(BEEP_GPIO_Port, BEEP_Pin);}if(HAL_GPIO_ReadPin(EXTI_Key2_GPIO_Port, EXTI_Key2_Pin) == 0){HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);}
}
中断处理程序要少用延时的原因
中断处理的要求是即时处理,尽快退出。如果在中断中使用延时函数或者使用IO阻塞函数,会影响到系统的实时性。如果下次中断来临,延时或者阻塞还没结束,那么就永远在中断里死循环了。
因此,对于中断处理程序的要求是:
短小精悍,不要处理过多任务
不使用延时函数或者IO阻塞的函数
Keil代码
需要修改的地方如下:
mian.c(144)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{//若需要延时需要将延时中断优先级比外部中断优先级高,优先级高才可以打断低优先级HAL_Delay(10);if(HAL_GPIO_ReadPin(EXTI_Key1_GPIO_Port, EXTI_Key1_Pin) == 0) //读引脚,相同=0,不同=1{HAL_GPIO_TogglePin(BEEP_GPIO_Port, BEEP_Pin);}if(HAL_GPIO_ReadPin(EXTI_Key2_GPIO_Port, EXTI_Key2_Pin) == 0){HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);}
}
main.h(60)
#define EXTI_Key1_Pin GPIO_PIN_3
#define EXTI_Key1_GPIO_Port GPIOE
#define EXTI_Key1_EXTI_IRQn EXTI3_IRQn
#define EXTI_Key2_Pin GPIO_PIN_4
#define EXTI_Key2_GPIO_Port GPIOE
#define EXTI_Key2_EXTI_IRQn EXTI4_IRQn
#define LED1_Pin GPIO_PIN_5
#define LED1_GPIO_Port GPIOB
#define BEEP_Pin GPIO_PIN_8
#define BEEP_GPIO_Port GPIOB
gpio.c(42)
void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOE_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET);/*Configure GPIO pins : PEPin PEPin */GPIO_InitStruct.Pin = EXTI_Key1_Pin|EXTI_Key2_Pin;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);/*Configure GPIO pins : PBPin PBPin */GPIO_InitStruct.Pin = LED1_Pin|BEEP_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/* EXTI interrupt init*/HAL_NVIC_SetPriority(EXTI3_IRQn, 5, 0);HAL_NVIC_EnableIRQ(EXTI3_IRQn);HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0);HAL_NVIC_EnableIRQ(EXTI4_IRQn);
}
stm32f1xx_hal_it.c(204)
void EXTI3_IRQHandler(void)
{/* USER CODE BEGIN EXTI3_IRQn 0 *//* USER CODE END EXTI3_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(EXTI_Key1_Pin);/* USER CODE BEGIN EXTI3_IRQn 1 *//* USER CODE END EXTI3_IRQn 1 */
}void EXTI4_IRQHandler(void)
{/* USER CODE BEGIN EXTI4_IRQn 0 *//* USER CODE END EXTI4_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(EXTI_Key2_Pin);/* USER CODE BEGIN EXTI4_IRQn 1 *//* USER CODE END EXTI4_IRQn 1 */
}
修改延时中断优先级
HAL_Init(); //main.c(74)//HAL_StatusTypeDef HAL_Init(void)中的
HAL_InitTick(TICK_INT_PRIORITY); //stm32f1xx_hal.c(160)//进入参数里修改
#define TICK_INT_PRIORITY 1U //stm32f1xx_hal_conf.h(132)
相关文章:
2.外部中断(EXTI)
理论 NVIC:嵌套向量中断控制器(解释教程) 外部通用中断线(EXTI0~EXTI15):每个GPIO设置成中断模式,与中断控制器连接的线 外部中断触发方式 上升沿触发、下降沿触发、双边沿触发 外部中断触发函数 在stm32f1xx_it.c文件…...
Python | SyntaxError: invalid syntax 深度解析
Python | SyntaxError: invalid syntax 深度解析 在Python编程中,SyntaxError: invalid syntax是一个常见的错误,它表明Python解释器在尝试解析代码时遇到了语法问题。这个错误通常是由于代码中存在拼写错误、缺少符号(如括号、冒号或逗号&a…...
付费进群系统源码原版最新修复全开源版
付费进群,和平时所见到的别人拉你进群是不一样的,付费进群需要先缴费以后,才会看到群的二维码,扫码进群或者是长按二维码图片识别进群,付费进群这个功能广泛应用于拼多多的砍价群,活动的助力群,…...
Docker容器部署的SpringBoot项目jar包,上传文件但是找不到路径的问题
在docker容器内部署的jar包运行后,请求访问都没有问题,在文件上传时,发现上传图片接口响应成功,但是图片路径报404错误,发现找不到路径。 在服务器上查看也没有找到相关图片。 原因: 启动docker镜像时没…...
云计算学习——5G网络技术
系列文章目录 提示:仅用于个人学习,进行查漏补缺使用。 Day1 网络参考模型 Day2 网络综合布线与应用 Day3 IP地址 Day4 华为eNSP网络设备模拟器的基础安装及简单使用 Day5 交换机的基本原理与配置 Day6 路由器的原理与配置 Day7 网络层协议介绍一 Day8 传…...
matlab仿真 信道编码和交织(上)
(内容源自详解MATLAB/SIMULINK 通信系统建模与仿真 刘学勇编著第八章内容,有兴趣的读者请阅读原书) clear all N10;%信息比特的行数 n7;%hamming码组长度n2^m-1 m3;%监督位长度 [H,G]hammgen(m);%产生(n,n-…...
基于YOLOv8的高压输电线路异物检测系统
基于YOLOv8的高压输电线路异物检测系统 (价格88) 包含 【“鸟窝”,“风筝”,“气球”,“垃圾”】 4个类 通过PYQT构建UI界面,包含图片检测,视频检测,摄像头实时检测。 (该系统可以根据数…...
23款奔驰GLS450加装原厂电吸门配置,提升车辆舒适性和便利性
今天是一台22款奔驰GLS450,车主是佛山的 以前被不良商家坑了 装了副厂的电吸门 刚开始就很正常 用了半年之后 就开始开不了门,被锁在里面,刚开始车主以为是零件坏了 后来越来越频繁,本来是为了家里老人小孩关门方便而升级的&#…...
git操作流程笔记
1、在本地项目文件夹右击鼠标点击Git Bash Here 2、输入git init,这个目录变成git可以管理的仓库,会出现一个.git文件夹,如果没出现的话需要选择“显示隐藏文件”(不会的同学自行百度一下) 3、绑定本地仓库与远程仓库…...
【QT】常用控件-上
欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 目录 👉🏻QWidgetenabledgeometryrect制作上下左右按钮 window frame 的影响window titlewindowIcon代码示例: 通过 qrc 管理图片作为图标 windowOpacitycursor使用qrc自…...
帮助网站提升用户参与度的5个WordPress插件
仅靠编写精彩的内容、设计精美的图像和创建简化的客户旅程不足以提高网站参与度。您需要让用户在首次访问后继续与您的网站互动并成为回访者,才能真正吸引您所追求的兴趣。 幸运的是,对于 WordPress 用户来说,有数百种工具可用于提高用户参与…...
理解 Python 中的 @wraps:保留函数元数据
一.介绍 在本文中,我们将了解 wraps。在 Python 中使用装饰器时,您可能会遇到原始函数的元数据丢失的情况。这时,functools 模块中的 wraps 装饰器就可以派上用场了。让我们深入了解 wraps 的作用及其重要性。 二.简单装饰器的问题 首先&a…...
cjson
文章目录 概述编译cjson_test 小结 概述 在网络传输中,网络数据序列化,常用的有那么几种,json,protobuf都是很常用的,这一篇来写下json。 Json常用的有几个,rapidjson,jsoncpp,还有…...
Docker data root 目录更改
有时候受限于系统根目录空间的限制,需要将 docker data root 目录更改为其它目录,如单独挂载一个磁盘或存储。本篇文章介绍如何操作。 修改docker 工作目录 修改配置文件/etc/docker/daemon.json(在19.x 版本之前使用grapth) {&q…...
[CR]厚云填补_SEGDNet
Structure-transferring edge-enhanced grid dehazing network Abstract 在过去的二十年里,图像去雾问题在计算机视觉界受到了极大的关注。在雾霾条件下,由于空气中水汽和粉尘颗粒的散射,图像的清晰度严重降低,使得许多计算机视觉…...
图-基础概念
是什么 图是一种抽象的数据类型,在图中的数据元素通常称作节点,V是所以定点的集合,E是所有边的集合 图的分类 有向图 如果两个订单v,w,只能由v向w,而不能w向v,那么我们就把何种情况叫做一个从…...
Javascript前端基础面试(十)
MVVM Vue MVVM这一篇就够啦!_vue r mvvm-CSDN博客 点容器内的图标,图标边框变成border 1px solid red,点空白处重置 <div id"container"> <img src"icon.png" alt"Icon" class"icon"> <!…...
书生大模型实战营闯关记录----第五关:LlamaIndex+Internlm2 RAG实践Demo:效果对比,文档加载,向量库构建,检索器,模型推理
文章目录 1. 前置知识RAG背景RAG 效果比对 2. 环境、模型准备2.1 配置基础环境2.2 安装 Python环境和依赖包2.3 下载 Sentence Transformer 模型2.4 下载 NLTK 相关资源 3. LlamaIndex HuggingFaceLLM4. LlamaIndex RAG加载文档构建向量存储索引库检索器RAG代码 5. LlamaIndex …...
如何使用极狐GitLab CI/CD Component Catalog?【上】
极狐GitLab 是 GitLab 在中国的发行版,专门面向中国程序员和企业提供企业级一体化 DevOps 平台,用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规,而且所有的操作都是在一个平台上进行,省事省心省钱。可以一键安装极狐GitL…...
详解Xilinx FPGA高速串行收发器GTX/GTP(3)--GTX的时钟架构
目录 1、参考时钟 2、时钟方案 2.1、单个外部参考时钟驱动单个QUAD中的多个transceiver 2.2、单个外部参考时钟驱动多个QUAD中的多个transceiver 2.3、同一个Quad中,多个GTX Transceiver使用多个参考时钟 2.4、不同Quad中,多个GTX Transceiver 使用多个参考时钟 3、QP…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
