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

news2024/10/6 20:26:44

引言

上篇帖子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,外部中断的原理和实验到此结束,完结撒花*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。


本篇完。

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mfc140.dll丢失的几种修复方式,有效的解决文件丢失问题

mfc140.dll是Microsoft Foundation Class (MFC)库中的一个非常重要的DLL文件。它承载了许多被执行程序使用的函数和资源。这个库主要被广泛应用于开发Windows操作系统上的应用程序。然而,有时候我们可能会遭遇到mfc140.dll缺失或损坏的情况,这会导致依赖…

力扣hot100 二叉树的右视图 DFS BFS 层序遍历 递归

Problem: 199. 二叉树的右视图 文章目录 思路&#x1f496; BFS&#x1f496; DFS 思路 &#x1f469;‍&#x1f3eb; 甜姨 &#x1f496; BFS ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) class Solution {public List<Integer&…

探究HMAC算法:消息认证与数据完整性的完美结合

Hash-based Message Authentication Code&#xff08;基于哈希的消息认证码&#xff0c;简称HMAC&#xff09;算法作为一种广泛应用的消息认证码&#xff08;MAC&#xff09;算法&#xff0c;在现代信息安全领域起着至关重要的作用。本文将从算法原理、优缺点、实际应用等方面&…

linux中vim的操作

(码字不易&#xff0c;关注一下吧w~~w) 命令模式&#xff1a; 当我们按下esc键时&#xff0c;我们会进入命令模式&#xff1b;当使用vi打开一个文件时也是进入命令模式。 光标移动&#xff1a; 1 保存退出&#xff1a;ZZ 2 代码格式化&#xff1a;ggG 3 光标移动&#xff…

【数据结构 07】AVL树

目录 一、二叉搜索树 二、AVL树 2.1 左单旋 2.2 右单旋 2.3 左右双旋 2.4 右左双旋 三、AVL.h 四、test.cpp 一、二叉搜索树 二叉搜索树&#xff0c;又称二叉排序树&#xff08;Binary Search Tree&#xff09;&#xff0c;相比于普通二叉树&#xff0c;BST的特性有&a…

springboot完成一个线上图片存放地址+实现前后端上传图片+回显

1.路径 注意路径 2.代码&#xff1a;&#xff08;那个imagePath没什么用&#xff0c;懒的删了&#xff09;&#xff0c;注意你的本地文件夹要有图片&#xff0c;才可以在线上地址中打开查看 package com.xxx.common.config;import org.springframework.beans.factory.annotat…

一站式在线协作开源办公软件ONLYOFFICE,协作更安全更便捷

1、ONLYOFFICE是什么&#xff1f; ONLYOFFICE是一款功能强大的在线协作办公软件&#xff0c;可以创建编辑Word文档、Excel电子表格&#xff0c;PowerPoint&#xff08;PPT&#xff09;演示文稿、Forms表单等多种文件。ONLYOFFICE支持多个平台&#xff0c;无论使用的是 Windows、…

vue3.0中从proxy中取值

使用vue3.0时&#xff0c;因为底层是使用proxy进行代理的所以当我们打印一些值的时候是proxy代理之后的&#xff0c;是Proxy 对象&#xff0c;Proxy对象里边的[[Target]]才是真实的对象。也是我们需要的 第一种获取target值的方式&#xff1a; import { toRaw } from vue; le…

【Jenkins】配置及使用|参数化|邮件|源码|报表|乱码

目录 一、Jenkins 二、Jenkins环境搭建 1、下载所需的软件包 2、部署步骤 3、其他 三、Jenkins全局设置 &#xff08;一&#xff09;Manage Jenkins——Tools系统管理->全局工具配置分别配置JDK、Maven、Allure、Git&#xff0c;可以配置路径或者直接选择版本安装 1…

[C++]继承(续)

一、基类和派生类对象赋值转换 在public继承时&#xff0c;父类和子类是一个“is - a”的关系。 子类对象赋值给父类对象/父类指针/父类引用&#xff0c;我们认为是天然的&#xff0c;中间不产生临时对象&#xff0c;也叫作父子类赋值兼容规则&#xff08;切割/切片&#xff…

【C/C++ 03】堆排序

堆排序是选择排序算法的进阶&#xff0c;也就是通过二叉树节点存储数组&#xff0c;并通过root节点存储最值与二叉树最后一个节点进行交换完成排序&#xff0c;降低了时间复杂度。在大数据时代&#xff0c;堆排序常用于处理Top-K问题。 排序对象&#xff1a;数组时间复杂度&am…

Maya------创建多边形工具

配合导入图像使用 Tab键可以删除一个点&#xff01; 模型不能超过4边面&#xff01;多切割工具进行连接&#xff01; 15.maya常用命令5.创建多边形工具 反转 双显 挤出_哔哩哔哩_bilibili

政安晨的机器学习笔记——演绎一个TensorFlow官方的Keras示例(对服装图像进行分类,很全面)

导语 Keras是一个高级API接口&#xff0c;用于构建和训练神经网络模型。它是TensorFlow的一部分&#xff0c;提供了一种简洁、直观的方式来创建深度学习模型。 Keras的主要特点如下&#xff1a; 简洁易用&#xff1a;Keras提供了一组简单的函数和类&#xff0c;使模型的创建和…

vue 适配大屏 页面 整体缩放

正常应该放在app.vue 里面。我这里因为用到element-ui 弹框无法缩放&#xff0c;所以加在body上面 (function (doc, win) {var docEl doc.documentElement,resizeEvt orientationchange in window ? orientationchange : resize,recalc function () {var clientWidth docE…

力扣hot100 二叉树的层序遍历 队列 广度优先搜索

Problem: 102. 二叉树的层序遍历 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 路飞 复杂度 时间复杂度: 添加时间复杂度, 示例&#xff1a; O ( n ) O(n) O(n) 空间复杂度: 添加空间复杂度, 示例&#xff1a; O ( n ) O(n) O(n) Code /*** Definition …

CKS1.28【1】kube-bench 修复不安全项

Context 针对 kubeadm 创建的 cluster 运行 CIS 基准测试工具时&#xff0c;发现了多个必须立即解决的问题。 Task 通过配置修复所有问题并重新启动受影响的组件以确保新的设置生效。 修复针对 API 服务器发现的所有以下违规行为&#xff1a; 1.2.7 Ensure that the --authoriz…

Vue3中实现歌词滚动显示效果

目录 &#x1f389;前言 &#x1f389;整体布局 &#x1f389;处理歌词数据 &#x1f389;处理事件 &#x1f389;完整代码 &#x1f389;总结 &#x1f389;前言 在这篇博客中&#xff0c;我将分享如何在 Vue 3 中实现一个简单的歌词滚动效果。我将从歌词数据的处理开始&…

Spring 学习1

1、什么是Spring Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff0c;其目的是用于简化 Java 企业级应用的开发难度和开发周期。Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言…

HTML+CSS+JS的3D进度条

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>HTMLCSSJS的3D进度条</title><style>…

C#,斯特林数(Stirling Number)的算法与源代码

1 斯特林数 在组合数学&#xff0c;斯特林数可指两类数&#xff0c;第一类斯特林数和第二类斯特林数&#xff0c;都是由18世纪数学家James Stirling提出的。它们自18世纪以来一直吸引许多数学家的兴趣&#xff0c;如欧拉、柯西、西尔沃斯特和凯莱等。后来哥本哈根&#xff08;…