04:(寄存器开发)使用外部中断按键控制LED

寄存器开发

  • 1、选择外部引脚配置
  • 2、上升沿触发/下降沿触发
  • 3、NVIC的配置
  • 4、完整代码

关于外部中断的AFIO,NVIC的基础知识请参考《stm32标准库入门教程》
链接: link

1、选择外部引脚配置

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
如上图所示:外部中断配置寄存器AFIO_EXTICR(1~4)中选择EXTI(0 ~ 15),在选择好的EXTI中填入对应的数值选择引脚。

本次实验:我们需要对引脚PB0进行外部中断检测,来控制LED灯的亮灭,则选择的寄存器是外部中断配置寄存器1(AFIO_EXTICR1),选择寄存器中的位0~位3(EXTI0)填入数值0001(选择PB0)

实物连接如下图所示:
在这里插入图片描述
具体的配置代码如下:

/* 1. 开启时钟:GPIOB和AFIO */
/* 1.1 GPIOB */
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; 

/* 1.2 AFIO */
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; 

/* 2. 将GPIOB0配置为上拉输入:MODE = 00,CNF = 10,上拉:ODR = 1 */
GPIOB->CRL &= ~GPIO_CRL_MODE0;
GPIOB->CRL &= ~GPIO_CRL_CNF0_0;
GPIOB->CRL |= GPIO_CRL_CNF0_1;
GPIOB->ODR |= GPIO_ODR_ODR0;//ODR = 1:表示上拉

/* 3. 配置AFIO ,选用EXTI0*/
AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI0_PB;//其中EXTIR[0]是EXTIR数组的第一个元素,
										 //AFIO_EXTICR1_EXTI0_PB = 0001

2、上升沿触发/下降沿触发

在这里插入图片描述
在这里插入图片描述

/* 1. 配置EXTI:下降沿触发,使能EXTI中断屏蔽 */
EXTI->FTSR |= EXTI_FTSR_TR0;//配置为下降沿触发
EXTI->IMR |= EXTI_IMR_MR0;//使能EXTI开关,只有使能这个开关中断信号才能传递到NVIC

3、NVIC的配置

NVIC是中断管理器,将请求来的中断进行优先级分组等操作。NVIC和RCC是处于CPU内部,挂载在系统总线AHB上面的,单片机一上电AHB的时钟信号都开启了的,所以不需要我们在用代码开启时钟,关于总线时钟可以参考《stm32标准库入门教程》中的时钟树那一篇。
由于NVIC在参考手册里面没有关于它的寄存器介绍,但是在core_cm3.c的文件里面有关于NVIC的配置函数,如下图所示:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述其中中断源的来源如下图所示:
在这里插入图片描述
由上图得出,中断源和下图的中断向量表的排序是一比一对应的。
在这里插入图片描述
在这里插入图片描述
如上图中断向量表所示:表中黑色部分的中断源是由CPU内部产生的,而其他的都是由片上外设产生的,若没有配置NVIC的优先级,那么则按照表中的默认优先级进行执行中断。其他黑色部分的中断源来自于CPU内部,则无需在使能NVIC_EnableIRQ(),因为只有前面位置值为正数才需要使能NVIC_EnableIRQ()。
在这里插入图片描述

/* 5. 配置NVIC  */
/* 5.1 优先级分组*/
NVIC_SetPriorityGrouping(0x04);//设置4位抢占优先级,0位子优先级

/* 5.2 优先级赋值*/
NVIC_SetPriority(EXTI0_IRQn,0);

/* 5.3 使能中断源请求*/
NVIC_EnableIRQ(EXTI0_IRQn);

综上的分析:总结的外部中断的大体结构如下图所示:

在这里插入图片描述

4、完整代码

①Key.c的文件代码如下:

#include "stm32f10x.h"                  // Device header
#include "Key.h"  
#include "LED.h"
#include "Delay.h"
/*
 * 引脚的初始化:
 * 1、给按键对应的引脚IO口工作模式:上拉输入
 * 2、配置AFIO(复用外部中断)
 * 3、配置EXTI(外部中断控制器)
 * 4、配置NVIC
 */
 
 void Key_EXTI_Init(void)
 {
   /* 1. 开启时钟:GPIOB和AFIO */
   /* 1.1 GPIOB */
   RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; 
   /* 1.2 AFIO */
   RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; 
   
   /* 2. 将GPIOB0配置为上拉输入:MODE = 00,CNF = 10,上拉:ODR = 1 */
   GPIOB->CRL &= ~GPIO_CRL_MODE0;
   GPIOB->CRL &= ~GPIO_CRL_CNF0_0;
   GPIOB->CRL |= GPIO_CRL_CNF0_1;
   
   GPIOB->ODR |= GPIO_ODR_ODR0;//ODR = 1:表示上拉
   
   /* 3. 配置AFIO ,选用EXTI0*/
   AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI0_PB; 
   
   /* 4. 配置EXTI:下降沿触发,使能EXTI中断屏蔽 */
   EXTI->FTSR |= EXTI_FTSR_TR0;
   EXTI->IMR |= EXTI_IMR_MR0;
   
   /* 5. 配置NVIC  */
   /* 5.1 优先级分组*/
   NVIC_SetPriorityGrouping(0x04);
   /* 5.2 优先级赋值*/
   NVIC_SetPriority(EXTI0_IRQn,0);
   /* 5.3 使能中断请求*/
   NVIC_EnableIRQ(EXTI0_IRQn);
 }
 
 
 /*
  * 中断服务函数:按下按键时,执行一次中断函数
  */
void EXTI0_IRQHandler(void)
{
  /* 除中断挂起标志位 */
  EXTI->PR |= EXTI_PR_PR0;
  
  Delay_ms(10);//在中断里面添加延迟是不被允许的,但是这里是学习中断,我们忽略
  
  if((GPIOB->IDR & GPIO_IDR_IDR0) != 0)//检测输入引脚是否被真的按下
  {
    //不等于0说明还在抖动
  }
  else
  {
    /* LED0翻转 */
    LED_Turn(LED0);
  }
}

②LED.c文件的代码如下:

#include "stm32f10x.h"                  // Device header
#include "LED.h"

/*
 * PA0~PA7引脚的初始化
 */
void LED_Init(uint32_t PA_x)
{
	/* 1. 打开GPIOA的时钟 */
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
	
	/* 2. 将PA0~PA7配置为通用输出开漏模式  */
	if(PA_x != PA_ALL)
	{
		GPIOA->CRL |= PA_x; 
		GPIOA->CRL &= ~(PA_x << 2);
	}else{
		GPIOA->CRL |= PA_ALL;
		GPIOA->CRL &= PA_ALL;
	}
}

/*
 * 点亮LEDx
 */
void LED_ON(uint16_t LEDx)
{
	GPIOA->ODR |= LEDx;
}


/*
 * 熄灭LEDx
 */
void LED_OFF(uint16_t LEDx)
{
	GPIOA->ODR &= ~LEDx;
}


/*
 * 翻转LEDx
 */
void LED_Turn(uint16_t LEDx)
{
	/* 如果是关闭那么就打开,如果是打开那么就关闭 */
	if((GPIOA->ODR & LEDx) == 0)//关闭
	{
		LED_ON(LEDx);
	}else{
		LED_OFF(LEDx);
	}
}

③LED.h的文件代码如下:

#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"                  // Device header

#define PA_0  0x00000003 //GPIO_CRH_MODE0
#define PA_1  0x00000030 //GPIO_CRH_MODE1
#define PA_2  0x00000300 //GPIO_CRH_MODE2
#define PA_3  0x00003000 //GPIO_CRH_MODE3
#define PA_4  0x00030000 //GPIO_CRH_MODE4
#define PA_5  0x00300000 //GPIO_CRH_MODE5
#define PA_6  0x03000000 //GPIO_CRH_MODE6
#define PA_7  0x30000000 //GPIO_CRH_MODE7
#define PA_ALL  0x33333333 //GPIO_CRH_MODE

#define LED0 GPIO_ODR_ODR0
#define LED1 GPIO_ODR_ODR1
#define LED2 GPIO_ODR_ODR2
#define LED3 GPIO_ODR_ODR3
#define LED4 GPIO_ODR_ODR4
#define LED5 GPIO_ODR_ODR5
#define LED6 GPIO_ODR_ODR6
#define LED7 GPIO_ODR_ODR7

void LED_Init(uint32_t PA_x);
void LED_ON(uint16_t LEDx);
void LED_OFF(uint16_t LEDx);
void LED_Turn(uint16_t LEDx);

#endif

④主函数文件的代码如下:

#include "stm32f10x.h"                
#include "Delay.h"
#include "LED.h"
#include "Key.h"

/*
	使用外部中断按键控制LED
*/
int main(void)
{
	LED_Init(PA_0);//初始化PA0引脚
	Key_EXTI_Init();//初始化PB0引脚的EXTI
  
	while(1)
	{
        
	}
}

实物演示效果如下:

外部中断

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

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

相关文章

Bootstrap 5 练习 - 显示工具提示

文章目录 引言准备工作创建HTML文件导入Bootstrap 5框架编写页面代码编写JavaScript脚本浏览网页注意事项结束语 引言 大家好&#xff0c;今天我们将一起学习如何在Bootstrap 5中创建一个简单的工具提示&#xff08;Tooltip&#xff09;。工具提示是一个非常实用的用户界面元素…

通过观测云 DataKit Extension 接入 AWS Lambda 最佳实践

前言 AWS Lambda 是一项计算服务&#xff0c;使用时无需预配置或管理服务器即可运行代码。AWS Lambda 只在需要时执行代码并自动缩放。借助 AWS Lambda&#xff0c;几乎可以为任何类型的应用程序或后端服务运行代码&#xff0c;而且无需执行任何管理。 Lambda Layer 是一个包…

Java面试宝典-Java集合02

目录 Java面试宝典-Java集合02 21、TreeMap 和 TreeSet 在排序时如何比较元素&#xff1f; 22、ArrayList 和 LinkedList 的区别是什么&#xff1f; 23、ArrayList 和 Vector 的区别&#xff1f; 24、队列和栈是什么&#xff1f;有什么区别&#xff1f; 25、Queue和Deque的区别…

大模型存储选型 JuiceFS 在关键环节性能详解

从去年开始&#xff0c;LLM大语言模型领域发展迅速、如 LLaMA、ChatGLM、Baichuan、Qwen 和 yi-model 等基础模型&#xff08;Foundation Models&#xff09;的数量显著增加。众多企业也开始基于这些基础模型做 post-training 的相关工作&#xff0c;以开发特定垂直领域的模型实…

小猿口算自动PK脚本

大家好&#xff0c;我是小黄。 近期&#xff0c;众多大学生炸鱼小猿口算APP,把一众小学生都快虐哭了&#xff0c;小黄听闻后&#xff0c;也跃跃欲试。对此小黄也参考网上的资料写了一个自动Pk的脚步。 首先大家需要安装一个pytorch环境过程中&#xff0c;如果小伙伴对此不熟悉的…

Linux相关概念和易错知识点(14)(进程终止、进程退出、退出信息)

1.进程终止 &#xff08;1&#xff09;错误码 对于程序常见错误信息&#xff0c;C/C提供了信息解释&#xff0c;保存在<string.h>&#xff0c;使用strerror(错误码)就可以查询 错误信息成立的前提是错误码要和错误信息匹配&#xff0c;我们需要结合C/C给我们的错误码来…

【计算机网络 - 基础问题】每日 3 题(三十六)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

Open WebUI | 自托管的类 ChatGPT 网站

Open WebUI 是一个扩展性强、功能丰富且用户友好的自托管 WebUI&#xff0c;支持 ChatGPT 网页端的大部分功能&#xff0c;支持各类模型服务&#xff0c;包括 Ollama 和 OpenAI 的 API。该项目在 GitHub 上已有 38k 星&#xff0c;非常受欢迎。 功能介绍 本篇介绍该项目的功能…

考研笔记之操作系统(四) - 文件管理

文件管理 1. 简介1.1 前情回顾1.2 文件的属性1.3 文件内部数据的组织方式1.4 操作系统向上提供的文件功能1.5 文件应如何放在外存 2. 文件的逻辑结构2.1 无结构文件2.2 有结构文件2.2.1 顺序文件2.2.2 索引文件2.2.3 索引顺序文件2.2.4 多级索引顺序文件 3. 文件目录3.1 基本概…

若依前端后打成一个JAR包部署

客户需要将项目前后端作为一个整体打包成jar&#xff0c;不使用nginx方式转发。使用框架是若依前后端分离&#xff0c;后端springboot&#xff0c;前端vue&#xff0c;目的就是把vue打入jar。 一、前端修改 ruoyi-ui/src/router/index.js文件 &#xff0c;将 mode: ‘history’…

数据结构之二叉搜索树(key模型与key_value模型)

二叉搜索树&#xff08;key模型与key_value模型&#xff09; 1. ⼆叉搜索树的概念2. ⼆叉搜索树的性能分析3. ⼆叉搜索树的插⼊4. ⼆叉搜索树的查找5. ⼆叉搜索树的删除6. ⼆叉搜索树的实现代码7. ⼆叉搜索树key和key/value使⽤场景7.1 key搜索场景&#xff1a;7.2 key/value搜…

2-118 基于matlab的六面体建模和掉落仿真

基于matlab的六面体建模和掉落仿真&#xff0c;将对象建模为刚体来模拟将立方体扔到地面上。同时考虑地面摩擦力、刚度和阻尼所施加的力&#xff0c;在三个维度上跟踪平移运动和旋转运动。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a;2-118 基于matla…

Kubernetes系列之一快速部署一套K8s集群(kubeadm方式)

最近本人在重温云原生相关的技术&#xff0c;说到云原生&#xff0c;必然绕不开Kubernetes&#xff0c;今天想跟大家聊的就是大名顶顶的Kubernetes。相信很多朋友在学习和使用Kubernetes的过程遇到各式各样不同的问题。我将从一个初学者的角度来给大家讲解一下Kubernete从安装、…

字节跳动青训营开始报名了!

关于青训营&#xff1a; 青训营是字节跳动技术团队发起的技术系列培训 &人才选拔项目;面向高校在校生&#xff0c;旨在培养优秀且具有职业竞争力的开发工程师。 本次技术训练营由掘金联合豆包MarsCode 团队主办课程包含前端、后端和 A 方向&#xff0c;在这个飞速发…

Ajax面试题:(第一天)

目录 1.说一下网络模型 2.在浏览器地址栏键入URL&#xff0c;按下回车之后会经历以下流程&#xff1a; 3.什么是三次握手和四次挥手&#xff1f; 4.http协议和https协议的区别 1.说一下网络模型 注&#xff1a;各层含义按自己理解即可 2.在浏览器地址栏键入URL&#xff0c;…

Spring Boot 进阶-详解Spring Boot整合数据库

在之前的例子中&#xff0c;我们介绍了如何在Spring Boot 框架中添加数据源配置。这篇文章我们来详细介绍一下如何整合Mybatis框架。 整合Mybatis框架 还是按照之前的套路&#xff0c;我们要整合Mybatis框架&#xff0c;首先需要加载对应的场景启动器。这里我们引入由Mybatis提…

gitlab-ci 集成 k3s 部署spring boot 应用

环境 一台ECS gitlab 16.10 一台ECS gitlab-runner docker方式 一台腾讯云服务器 k3s k3s version v1.30.5k3s1 (9b586704) go version go1.22.6 本地: idea 2024 准备开始 gitlab上创建"api"仓库,本地IDEA 创建spring boot web demo项目k8s-gitlab-demo. 确保能…

C语言-常见文件操作函数详解(fgetc,fputc,fgets,fputs,fscanf,fprintf,fread,fwrite)

&#x1f30f;个人博客&#xff1a;尹蓝锐的博客 希望文章能够给到初学的你一些启发&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏支持一下笔者吧&#xff5e; 顺序读写数据常用函数 函数名调用形式功能返回值fgetcfgetc(fp)从指针变量fp指向的文件中读…

(五)Proteus仿真STM32单片机串口数据流收发

&#xff08;五&#xff09;Protues仿真STM32单片机串口数据流收发 – ARMFUN 1&#xff0c;打开STM32CubeMX&#xff0c;找到USART1,配置模式Asynchronous&#xff0c;此时PA9、PA10自动变成串口模式 串口默认参数:115200bps 8bit None 1stop 2&#xff0c;NVIC Settings使能…

Kafka之基本概念

1、Kafka是什么&#xff1f; Kafka是由Scala语言开发的一个多分区、多副本&#xff0c;基于Zookeeper集群协调的系统。 那这个所谓的系统又是什么系统呢&#xff1f; 回答这个问题要从发展的角度来看&#xff1a;起初Kafka的定位是分布式消息系统。但是目前它的定位是一个分布…