嵌入式系统实验——【玄武F103开发板】按key1熄灭两个LED灯、松开恢复点亮

news2025/3/1 18:56:32

这里写目录标题

  • 一、任务目标
    • (一)分析
  • 二、设计思路
    • (一)开启`KEY1`对应的`GPIOx`时钟
      • 1.找到`KEY1(PE3)`所在的`GPIOx`端口
      • 2.开启`GPIOE`端口时钟
    • 3.清空`PE3`的端口位
    • 4.设置`PE3`的端口位为输出模式的上拉模式
    • 5.一个易错点!
  • 三、完整代码

项目代码-修改前

一、任务目标

上述压缩包内的项目实现了按下KEY UP按键,LED灯熄灭,松开恢复点亮,要修改原文件夹中的main.c文件,使得按下KEY1开关,LED灯熄灭,松开恢复点亮。

(一)分析

在这里插入图片描述
在这里插入图片描述
首先按钮信号为输入信号,向ODR寄存器写入值,应该设置KEY按钮的端口配置地寄存器(GPIOx_CRL)为输入模式,下面分析KEY1(PE3)采用哪种输入模式:

下面的main.c代码的GPIOA_CRL |= (0x08<<4*0); GPIOA_BRR |= 1;,使得KEY UP设置为输入模式的下拉模式,当松开开关时,KEY UP为低电平,端口输入数据寄存器(IDR)对应的位变为1,执行if语句中的GPIOB_ODR &= (0<<5);GPIOE_ODR &= (0<<5);代码,使小灯点亮,当按下时,WK UP所处电路与VCC3.3导通,此时WK为高电平,端口输入数据寄存器(IDR)对应的位变为0,执行else语句,小灯熄灭。

但是KEY1按钮所处电路与上述WK UP所处电路有不同,其右侧接地,如果设置KEY1(PE3)为输入模式的下拉模式,KEY1为低电平,按下KEY1,按下前后,IDR均为0,无法通过按下按键与否判断小灯的闪灭,因此设置KEY1位输入模式的上拉模式

设置其为上拉模式一般步骤是:
①知道其位于哪个GPIO端口
②开启端口时钟
③清空端口配置低寄存器
④设置端口配置低寄存器。

#include "stm32f10x.h" 
typedef unsigned int u32; 
void delay(u32 i)
{while(i--);}
int main(void)
{	
	delay(0xfffff);
	// 开启GPIOx端口时钟
	RCC_APB2ENR |= (1<<2); 	//A
	RCC_APB2ENR |= (1<<3);	//B
	RCC_APB2ENR |= (1<<6);	//E
	
	// 清空控制PB5、PE5,PA0的端口位
	GPIOB_CRL &= ~( 0x0F<< (4*5));	//PB5
	GPIOE_CRL &= ~( 0x0F<< (4*5));	//PE5
	GPIOA_CRL &= ~( 0x0F<< (4*0));	//PA0
	
	// 配置PB5、PE5位通用推挽输出、速度为10M
	GPIOB_CRL |= (1<<4*5);
	GPIOE_CRL |= (1<<4*5);
	GPIOA_CRL |= (0x08<<4*0);  //PA0为“上拉下拉”输入
	GPIOA_BRR |= 1; // 通过设置ODR为1为上拉,为0则下拉,设置0,下拉
	
	while(1)
	{
		if( (GPIOA_IDR & 0x0001) == 0)
		{
			//输出低,亮灯
			GPIOB_ODR &= (0<<5);
			GPIOE_ODR &= (0<<5);		
		}
		else
		{
			//输出高,灭灯
			GPIOB_ODR |= (1<<5);  
			GPIOE_ODR |= (1<<5);	
		}
	}
}
void SystemInit(void)
{	
}

二、设计思路

(一)开启KEY1对应的GPIOx时钟

1.找到KEY1(PE3)所在的GPIOx端口

在这里插入图片描述
由图可以看出KEYGPIOE端口

2.开启GPIOE端口时钟

源文件已经打开,不需要再进行操作
在这里插入图片描述

3.清空PE3的端口位

在这里插入图片描述
清空的代码如下图,下图代码的逻辑即为把上图中的[15:12]位置为0,这四位即为PE3的对应的寄存器的位(上图中的x即为Ey即为PE3中的3
其他可以实现此功能的代码均可以
在这里插入图片描述

4.设置PE3的端口位为输出模式的上拉模式

设置为输入模式的上拉/下拉模式需要将MODE3[1:0]设置为00CNF3[1:0]设置为10,由于每4位对应一个端口,PE3的处于从低往高位数第44位(从0开始的),原理同上,因此可以使用如下代码:
在这里插入图片描述

但是GPIOE_CRL |= (0x08<<4*3);只是设置了输入模式的上拉/下拉模式,若想设置为上拉模式,还需要设置PE3对应的ODR寄存器,设置ODR1则上拉,为0则下拉(老师说的,还没来得及思考为什么)。
设置寄存器值时,应避免改变寄存器的其他位的值,常采用端口位清除寄存器(BSRR)、端口位设置/清除寄存器(BRR
在这里插入图片描述
在这里插入图片描述

所以采用代码:GPIOE_BSRR |= (1<<3);3是因为PE3中的3),来使得输入模式的上拉/下拉模式变为上拉模式

5.一个易错点!

下图代码中如果不加入划线两条语句,另外四条语句由于没有使用BSRRBRR寄存器,而是对ODR寄存器直接进行操作,如果在这个过程中,改变了PE3对应的ODR的值,则会导致程序逻辑出错,按钮对灯的亮灭不产生影响。(但是划线两条语句不一定都是必要的,本实验过程中偷懒没有做细致研究,以后可能会再深入看一下),除下图写法外,还可采用使用对BSRRBRR寄存器从而改变PE5AE5ODR寄存器的特定位,而不改变其他位的方法,达成实验目的,后续可能会对此部分做补充
if( (GPIOE_IDR & (0x0001<<3)) == 0)是判断PE3(KEY1)对应的输入数据寄存器(IDR)的第3位是否为13是因为PE3中的3IDR寄存器见下下张图片)
在这里插入图片描述
在这里插入图片描述

三、完整代码

(可能有多余的内容,非最优方法)
main.c

#include "stm32f10x.h" 
typedef unsigned int u32; 
lay(u32 i)
{
	while(i--);
}

int main(void)
{	
	delay(0xfffff);
	RCC_APB2ENR |= (1<<2); 	//A
	RCC_APB2ENR |= (1<<3);	//B
	RCC_APB2ENR |= (1<<6);	//E
	
	GPIOB_CRL &= ~( 0x0F<< (4*5));	//PB5
	GPIOE_CRL &= ~( 0x0F<< (4*5));	//PE5
	GPIOA_CRL &= ~( 0x0F<< (4*0));	//PA0
	GPIOE_CRL &= ~( 0x0F<< (4*3));	//PE3

	GPIOB_CRL |= (1<<4*5);
	GPIOE_CRL |= (1<<4*5);
	
	GPIOE_CRL |= (0x08<<4*3);
	GPIOE_BSRR |= (1<<3);
	while(1)
	{
		if( (GPIOE_IDR & (0x0001<<3)) == 0)
		{
			GPIOB_ODR &= (0<<5);
			GPIOE_ODR &= (0<<5);	
			GPIOE_BSRR |= (1<<3);			
		}
		else
		{
			GPIOB_ODR |= (1<<5);  
			GPIOE_ODR |= (1<<5);	
			GPIOE_BSRR |= (1<<3);
	
		}
	}
}
void SystemInit(void)
{	
}

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

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

相关文章

二分——力扣篇

二分——力扣篇搜索旋转排序数组搜索旋转排序数组II寻找旋转排序数组中的最小值寻找旋转排序数组中的最小值II搜索旋转排序数组 定理一&#xff1a;只有在顺序区间内才可以通过区间两端的数值判断target是否在其中。 定理二&#xff1a;判断顺序区间还是乱序区间&#xff0c;只…

案例学习20之内存长期占用导致系统缓慢

前言&#xff1a; 发现问题&#xff0c;解决问题&#xff0c;是贯穿整个项目开发过程的事情&#xff0c;能够处理更多的问题&#xff0c;随着经验的丰富&#xff0c;提前预知更多的问题&#xff0c;让问题不出现是最好的解决问题方式。 问题背景&#xff1a; 项目运行过程中出现…

基于redis实现点赞数,点击数,排行榜

使用场景 对于某些视频或者文章有点赞数和点击数, 通过这些数据就可以进行排行榜的功能了 使用异步队列 redis的集合 A.php //点击数 $redis->zIncrBy(click.:.date(Ymd),1,$videoId); //点赞数 $redis->zIncrBy(love.:.$videoId,1,$$user); //获取当前video的播放数…

PMP项目管理项目范围管理

目录1 项目范围管理概述2 规划范围管理3 收集需求4 定义范围5 创建 WBS6 确认范围7 控制范围1 项目范围管理概述 项目范围管理包括确保项目做且只做所需的全部工作&#xff0c;以成功完成项目的各 个过程。管理项目范围主要在于定义和控制哪些工作应在项目内&#xff0c;哪些工…

界面原型设计

引用锤子科技视觉设计总监——罗子雄在重庆TEDx活动上说的一小段话: 每当我们看到一些美妙的设计的时候,很多人心里面会有一种冲动,这种冲动会让你们想去创造一些新的东西,创造一些美妙的事物。 我们常说用户体验用户体验,用户使用你的软件,第一个会接触的是什么?没错,…

读WiscKey: Separating Keys from Values in SSD-conscious Storage

在我看来本论文的主要贡献在于相对减轻了传统LSM compact所带来的写放大问题。其核心设计在于使key、value分离以及gc只保持有效数据 key、value分离 作者对于key、value分离策略的观察主要来自于排序是以往LSM性能消耗最大的地方&#xff0c;但是真正影响排序的与占用大储存…

推荐五款宝藏软件,身为宝藏男孩和宝藏女孩的你,不试一下吗?

今天带来五款宝藏软件&#xff0c;身为宝藏男孩和宝藏女孩的你们&#xff0c;不试一下吗&#xff1f; 1.EPUB阅读器——Starrea Starrea 是一款Windows平台的EPUB电子书阅读器&#xff0c;它虽然只支持一个平台&#xff0c;但是提供了很多额外的功能&#xff0c;其中包括 文…

Java之线程总结一

Java之线程总结一 线程实现方式 官方文档说的是实现线程的方式有两种&#xff1b;本质上只有一种&#xff0c;就是构造Thread类&#xff0c;而实现线程执行单元的方式有两种&#xff1a; 继承Thread类&#xff0c;重写run方法&#xff1b;实现Runnable接口的run方法&#xf…

RHEL8.5解决libgdiplus绘图问题

最近有客户服务器使用RHEL8.5了。由于之前测试和编译的dotnetcore在Linux下绘图包libgdiplus都是在centos7.6编译的。把CentOS7.6编译的二进制程序之前试CentOS7.9使用没问题&#xff0c;然后RHEL8.5无法正常绘图。由于之前搞统信那些系统发现了包得在对应系统源码编译才行。所…

Java web基于SSM的停车场管理系统的设计与实现

1&#xff0c;项目介绍 Java web基于SSM的停车场管理系统拥有三种角色&#xff0c;分别为用户&#xff0c;管理员&#xff0c;超级管理员。 停车位管理&#xff08;管理员&#xff0c;超级管理员&#xff09;停车卡管理&#xff08;用户&#xff0c;管理员&#xff0c;超级管…

Vue3视频播放器组件Vue3-video-play入门教程

Vue3-video-play适用于 Vue3 的 hls.js 播放器组件 | 并且支持MP4/WebM/Ogg格式。 1、支持快捷键操作 2、支持倍速播放设置 3、支持镜像画面设置 4、支持关灯模式设置 5、支持画中画模式播放 6、支持全屏/网页全屏播放 7、支持从固定时间开始播放 8、支持移动端&#xff0c;移动…

pyqt5环境搭建

1、打开Terminal ,用命令pip install pyqt5-tools 或者 pip install pyqt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple安装PyQt5安装成功后就可看到PyQt5版本2、同上方法&#xff0c;继续安装pyqt5-tools扩展工具&#xff0c;里面包括了QtDesigner等很好用的工具。3、…

二进制哈希码快速搜索:Multi-Index Hashing

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 哈希方法通常包含两个部分&#xff1a; 【编码】将元素通过「data-dependent」或「data-independent」的方式映射为二进制…

C变量区域

C语言中有五大内存分区&#xff0c;分别是栈区、堆区、全局区/静态区、常量区和代码区。1.栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值、局部变量的值等。当调用函数的时候函数中定义的变量会被加到栈中&#xff0c;当函数离开的时候&#xff0c;被添加…

HTML看这一篇就够啦,HTML基础大全,可用于快速回顾知识,面试首选

HTML 1 基础 1.1 DOCTYPE <!DOCTYPE> 文档类型声明&#xff0c;作用就是告诉浏览器使用哪种HTML版本来显示网页。 <!DOCTYPE html> 这句代码的意思是: 当前页面采取的是 HTML5 版本来显示网页. 注意: 声明位于文档中的最前面的位置&#xff0c;处于 标签之前。 …

互联网新理念,对于WEB 3.0 你怎么看?

WEB 3.0 这个名词走进大众视野已经有一段时间了&#xff0c;也曾在各个圈子里火热一时&#xff0c;至今各大互联网企业任旧在 WEB 3.0 上不断探索。但关于 WEB 3.0 是什么这个问题&#xff0c;其实大部分人都没有一个比较明确的认知&#xff0c;包括区块链和元宇宙等相关行业的…

【设计模式】备忘录模式和迭代器模式

备忘录模式和迭代器模式备忘录模式代码示例迭代器模式代码示例使用迭代器遍历集合的同时不能删除/增加元素总结备忘录模式 备忘录模式&#xff0c;也叫快照&#xff08;Snapshot&#xff09;模式。 在 GoF的《设计模式》⼀书中&#xff0c;备忘录模式是这么定义的&#xff1a;…

【Spring6】面向切面:AOP

5.1、场景模拟 搭建子模块&#xff1a;spring6-aop 5.1.1、声明接口 声明计算器接口Calculator&#xff0c;包含加减乘除的抽象方法 public interface Calculator {int add(int i, int j);int sub(int i, int j);int mul(int i, int j);int div(int i, int j);}5.1.2、创建…

计算机视觉与深度学习 | Visual ChatGPT:微软开源视觉(图文)聊天系统——图像生成、迁移学习、边缘检测、颜色渲染等多功能(附代码下载链接)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== Visual ChatGPT: Talking, Drawing and Editing with V

LeetCode 134. 加油站(函数图像法 / 贪心)

题目&#xff1a; 链接&#xff1a;LeetCode 134. 加油站 难度&#xff1a;中等 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中…