正点原子--STM32中断系统学习笔记(2)

引言

上篇帖子STM32中断系统学习笔记(1)是理论,这篇帖子开始实战,目标是通过按键实现LED的控制。

1.工程建立

以正点原子HAL库 实验1 跑马灯实验为基础,复制工程,在“Drivers--BSP”目录下建立EXTI文件夹,并创建exti.c和exti.h文件;

2.导入C文件

第一步:

第二步: 

 

第三步:添加exti.c 

 

第四步:跳转到exti.h 

 添加这部分代码

#ifndef _EXTI_H
#define _EXTI_H

#include "./SYSTEM/sys/sys.h"

#endif

 3.查看原理图

我们想要最终实现的效果是按下KEY0使LED0灯翻转,按下KEY1使LED1翻转。

 配置LED0和LED1引脚为推挽输出模式(之前工程已经配置过),KEY0和KEY1引脚为中断输入模式;

 4.编写代码

按照正点原子给的步骤一步步来配置,最重要的是学习配置思路,一通百通!!

4.1 外部中断初始化

void exti_init(void)
{
	GPIO_InitTypeDef gpio_init_struct;
	__HAL_RCC_GPIOA_CLK_ENABLE();															/* 使能PA引脚时钟 */
	__HAL_RCC_GPIOC_CLK_ENABLE();															/* 使能PC引脚时钟 */
	
	gpio_init_struct.Pin = GPIO_PIN_15;               	/* 按键 KEY1 引脚 */
	gpio_init_struct.Mode =  GPIO_MODE_IT_FALLING;     	/* 外部中断下降沿触发 */
	gpio_init_struct.Pull = GPIO_PULLUP;                  /* 上拉 */
	HAL_GPIO_Init(GPIOA, &gpio_init_struct);         /* 配置初始化 */

	gpio_init_struct.Pin = GPIO_PIN_5;                /* 按键 KEY0 引脚 */
	gpio_init_struct.Mode =  GPIO_MODE_IT_FALLING;   /* 外部中断下降沿触发 */
	gpio_init_struct.Pull = GPIO_PULLUP;            /* 上拉 */
	HAL_GPIO_Init(GPIOC, &gpio_init_struct);       /* 配置初始化 */
	
	HAL_NVIC_SetPriority(EXTI15_10_IRQn,1,0);	/* 配置抢占优先级和响应优先级 */
	HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);			/* 使能中断 */
	
	HAL_NVIC_SetPriority(EXTI9_5_IRQn,2,0);		/* 配置抢占优先级和响应优先级 */
	HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);			/* 使能中断 */	
}

代码解释: 

①由原理图得知KEY0对应PC5,KEY1对应PA15,那么首先我们要使能PA和PC端口的时钟 ;

	GPIO_InitTypeDef gpio_init_struct;
	__HAL_RCC_GPIOA_CLK_ENABLE();															/* 使能PA引脚时钟 */
	__HAL_RCC_GPIOC_CLK_ENABLE();															/* 使能PC引脚时钟 */

②配置引脚号,引脚模式,有无上下拉电阻,以及配置完成初始化,这里需要注意一点的就是引脚模式配置为外部中断下降沿触发

	gpio_init_struct.Pin = GPIO_PIN_15;               	/* 按键 KEY1 引脚 */
	gpio_init_struct.Mode =  GPIO_MODE_IT_FALLING;     	/* 外部中断下降沿触发 */
	gpio_init_struct.Pull = GPIO_PULLUP;                  /* 上拉 */
	HAL_GPIO_Init(GPIOA, &gpio_init_struct);         /* 配置初始化 */

	gpio_init_struct.Pin = GPIO_PIN_5;                /* 按键 KEY0 引脚 */
	gpio_init_struct.Mode =  GPIO_MODE_IT_FALLING;   /* 外部中断下降沿触发 */
	gpio_init_struct.Pull = GPIO_PULLUP;            /* 上拉 */
	HAL_GPIO_Init(GPIOC, &gpio_init_struct);       /* 配置初始化 */

为什么要配置为上拉电阻:由原理图知,当我们按下KEY0时,GND导通,此时KEY0是低电平,我们接一个内置上拉电阻,那么KEY0在空闲状态时就是高电平。当按键按下时,KEY0的电平从高---->低,就是一个下降沿,这时我们配置引脚模式为下降沿触发,就能让外部中断信号顺利进入NVIC中断管家里。

③ 配置中断分组,中断优先级,使能中断

在stm32f1xx_hal.c里HAL_Init函数里,已经默认配置好了中断分组为2,所以我们只需要配置中断优先级以及使能中断就行;

	HAL_NVIC_SetPriority(EXTI15_10_IRQn,1,0);	/* 配置抢占优先级和响应优先级 */
	HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);			/* 使能中断 */
	
	HAL_NVIC_SetPriority(EXTI9_5_IRQn,2,0);		/* 配置抢占优先级和响应优先级 */
	HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);			/* 使能中断 */	

 HAL_NVIC_SetPriority,第一个参数是中断向量,选中它后按F12就能来到枚举类型的中断向量。

由EXTI和IO的重映射关系我们得知,PC5对应的EXTI线是EXTI5,PA5对应的EXTI线是EXTI15,所以我们要在IRQn_Type里找到我们所需要的中断向量, EXTI0~EXTI4有各自对应的中断向量,而EXTI5~EXTI9共用一个中断向量EXTI9_5_IRQn,EXTI10~EXTI15共用一个中断向量EXTI15_10_IRQn;

之后再配置抢占优先级和响应优先级即可,还有使能中断。

4.2 中断处理函数

思路:由HAL库中断回调处理机制得知,当发生中断后,首先进入到对应的中断服务函数里,比如KEY0(对应PC5引脚)按键按下,就会进入EXTI9_5_IRQHandler函数里,并调用HAL库中断处理公用函数HAL_GPIO_EXTI_IRQHandle(),在中断处理公用函数里会进行清中断标志位,调用中断回调函数HAL_GPIO_EXTI_Callback()的操作。

/* KEY1按键中断处理函数 */
void EXTI15_10_IRQHandler(void)
{
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);		/* 公共处理函数 */
	
	/* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
	__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_15);		
}

/* KEY0按键中断处理函数 */
void EXTI9_5_IRQHandler(void)
{
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);		/* 公共处理函数 */
	
	/* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
	__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5);
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	delay_ms(20);    /* 延时消除按键抖动 */
	switch(GPIO_Pin)
	{
		case GPIO_PIN_15 :
			if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15) == 0)    /* 检测KEY1是否按下 */
			{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);		/* 翻转LED0 */ }break;
			
		case GPIO_PIN_5 :
			if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0)     /* 检测KEY0是否按下 */
			{ HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_2);		/* 翻转LED1 */ }break;
		default:
				break;	
	}
}

而 HAL_GPIO_EXTI_Callback()是虚函数,最后按照我们的思路编写HAL_GPIO_EXTI_Callback()就好了。

main函数里只添加exti_init()外部中断初始化。

 

OK,外部中断的原理和实验到此结束,完结撒花*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。


本篇完。

本人博客仅代表个人见解方便记录成长笔记。

若有不足,请指出,感谢您的阅读!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024美国大学生数学建模竞赛A-F题完整思路+配套代码数据+后续高质量参考论文更新

The Mathematical Contest in Modeling (MCM) The Interdisciplinary Contest in Modeling (ICM) 24美赛【完整每问手把手详细思路可修改50页多种思路版本word版保奖论文】配套升级求解代码可视化图表 美赛A-F题完整版获取见文末 下文包含:2024美国大学生数学建模…

美区或其他外区Appstore账号AppleID注册教程,简单快速,苹果必备!

▍前言 现在越来越多的APP在国区APPstore下架,如果想有更好的使用体验,不得不去外区下载APP,那就需要一个外区的apple id,注册也很简单,今天大鹏通过电脑ipad给大家注册一个,建议大家直接使用iPhone或者iPa…

JVM性能分析工具——Arthas及火焰图的使用

Arthas的使用 Arthas常用命令Arthas的安装Linux压测工具Apache Bench安装火焰图的使用火焰图如何分析火焰图的互动 Arthas常用命令 help :查看所有命令dashboard :仪表板,查看线程的CPU信息等heapdump :不同类对象占用内存比重&a…

【微服务核心】Spring Cloud

文章目录 1. 简介2. 微服务项目搭建2.1 父工程2.2 提供者子工程2.3 热部署配置2.4 消费者子工程2.5 项目重构 3. 服务注册与发现3.1 Eureka 服务注册与发现3.1.1 单机版工程搭建3.1.2 单机版改集群版3.1.3 服务发现3.1.4 保护模式 3.2 ZooKeeper 服务注册与发现3.3 Consul 服务…

【五】【C++】类与对象(三)

const只读 在 C 中,const 关键字用于声明一个变量为常量,意味着一旦被初始化之后,它的值就不能被改变。 声明常量: 使用 const 关键字可以声明变量为常量。这意味着这个变量的值不能被修改。 const int MAX_SIZE 100; 指针与…

【江科大】STM32:MPU6050介绍

文章目录 MPU6050介绍结构图MPU6050参数硬件电路模块内部结构框图数据帧格式寄存器地址 MPU6050介绍 MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,通过数据融合,可进一步得到姿态角,常应用于平衡…

【智慧工业】东胜物联定位与跟踪解决方案,为方案商提供蓝牙网关、信标等物联网智能硬件设备

利用东胜物联的蓝牙网关我们的合作伙伴在德国的建筑工地成功实施了基于物联网蓝牙的员工出勤和跟踪管理解决方案,该解决方案简化了员工时间表并增强了工作流程,为经理和主管提供了更多时间来专注于项目洞察,并提高了员工的效率、绩效和生产力…

C++引用、内联函数、auto关键字介绍以及C++中无法使用NULL的原因

文章目录 一、引用1.1 引用概念1.2 引用特性1.3 常引用1.4 使用场景1.4.1 做参数1.4.2做返回值 1.5 引用和指针的区别1.6 小结一下 二、内联函数2.1 内联的概念2.2 内联的特性2.3 【面试题】 三、auto关键字(C11)3.1 类型别名思考3.2 auto简介 四、auto的使用细则4.1 基于范围的…

Linux系统——防火墙

一、防火墙的认识 引言 安全技术 入侵检测系统(Intrusion Detection Systems):特点是不阻断任何网络访问,量化、定位来自内外网络的威胁情况,主要以提供报警和事后监督为主,提供有针对性的指导措施和安全…

假期刷题打卡--Day20

1、MT1173魔数 一个数字,把他乘以二,会得到一个新的数字,如果这个新数字依然由原数中那些数字组成,就称原数为一个魔数。输入正整数N,检查它是否是一个魔数,输出YES或者NO。 格式 输入格式: …

SpringBoot RestTemplate 设置挡板

项目结构 代码 BaffleConfig /*** Description 记录配置信息* Author wjx* Date 2024/2/1 14:47**/ public interface BaffleConfig {// 是否开启挡板的开关public static boolean SWITCH true;// 文件根目录public static String ROOT_PATH "D:\\TIS\\mock";// …

ElementUI Form:Select 选择器

ElementUI安装与使用指南 Select 选择器 点击下载learnelementuispringboot项目源码 效果图 el-select.vue&#xff08;Select选择器&#xff09;页面效果图 项目里el-select.vue代码 <script> export default {name: el_select,data() {return {options: [{value…

LeetCode刷题:使用栈解决150. 逆波兰表达式求值

给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 、-、* 和 / 。每个操作数&#xff08;运算对象&#xff09;都可以是一个整数或者另一个表达式。两个…

泰迪智能科技大模型微调项目训练营已开营

泰迪智能科技大模型微调项目训练营开营 跟张良均老师学大数据人工智能 项目一&#xff1a;医疗诊疗对话意图识别 项目二&#xff1a;中医问答系统 项目三&#xff1a;某平台股票评论情感识别 学习流程&#xff1a; 项目一&#xff1a;医疗诊疗对话…

validator 对象校验,自定义校验实现

一、导入validator工具需要的jar包 <dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>4.1.0.Final</version></dependency><dependency><groupId>javax.valid…

SketchBook 2022下载安装教程,保姆级教程,操作简单,小白也能轻松搞定,附安装包和工具

前言 Autodesk SketchBook是一款新一代的自然画图软件&#xff0c;软件界面新颖动人&#xff0c;功能强大&#xff0c;仿手绘效果逼真&#xff0c;笔刷工具分为铅笔&#xff0c;毛笔&#xff0c;马克笔&#xff0c;制图笔&#xff0c;水彩笔&#xff0c;油画笔&#xff0c;喷枪…

原来你的Windows自带沙盒功能!

什么是Windows沙盒&#xff1f; Windows沙盒是一种虚拟化技术&#xff0c;允许用户在安全隔离的环境中运行不受信任的应用程序。它是Windows 10操作系统的一个特性&#xff0c;旨在提高系统的安全性&#xff0c;防止潜在的威胁对主系统造成影响。 启用Windows沙盒 确保系统满…

【TCP】流量控制和拥塞控制

前言 TCP&#xff08;传输控制协议&#xff09;是互联网协议&#xff08;IP&#xff09;网络传输层协议&#xff0c;负责控制数据包的顺序和流量控制&#xff0c;以防止网络拥塞和数据丢失。TCP流量控制和拥塞控制是确保网络有效通信的重要机制。具体分析如下&#xff1a; 流…

单细胞scRNA-seq测序基础知识笔记

单细胞scRNA-seq测序基础知识笔记 scRNA-seq技术scRNA-seq 分析流程数据预处理聚类标准化数据筛选有用的数据数据降维聚类 Clustering 注释细胞类型 scRNA数据分析结尾 该笔记来源于 B站up 江湾青年 scRNA-seq技术 首先是如何测序&#xff0c;上图瓶中有很多细胞&#xff0c;…

AD24-原理图与PCB交互设置及PCB常用快捷键汇总

一、原理图与PCB交互设置 1、在原理图页&#xff0c;工具-交叉选择模式 2、设置完成后。在原理图页选择器件&#xff0c;然后再PCB页也会相应被选中 3、一般将网络与Pin脚的勾去掉 4、整齐排列 5、TC&#xff1a;查找网络、器件、Pin脚 二、PCB常用快捷键汇总