STM32学习和实践笔记(14):按键控制实验

消除抖动有软件和硬件两种方法

软件方法就是在首次检测到低电平时加延时,通常延时5-10ms,让抖动先过去,然后再来检测是否仍为低电平,如果仍然是,说明确实按下。

硬件方法就是加RC滤波电路,硬件方法会增加成本,通常不采用。

本开发板的按键电路如下:

key up连接到+3.3V,是为了使用STM32的PA0引脚的唤醒功能。PA0片内配置成下拉电阻,平常为低电平,当按键按下时,检测到下拉电阻上有高电平,即表示按键按下。

K1-K3连到PE2-PE4,片内配置成上拉电阻,平常为高电平,按下按键为低电平。

按键控制实验:

使用开发板上的4个按键控制D2D3,D1指示灯

闪烁用于提示系统运行。程序框架如下

1)使能按键端口时钟、初始化GPIO

2)按键检测

        (3)主函数控制

main.c

#include "system.h"
#include "led.h"
#include "SysTick.h"
#include "beep.h"
#include "DigitalTube.h"
#include "key.h"



int main()
{
	u8 key,i=0;
	SysTick_Init(72);
	LED_Init();
//	BEEP_Init();
//	DigitalTube_Init();
	key_Init();

	
	while(1)
	{
		key=KEY_Scan(1);
		switch(key)
		{
			case KEY_UP: 		led2=!led2;break;
			case KEY_DOWN: 	led3=!led3;break;			
			case KEY_LEFT: 	led4=!led4;break;	
			case KEY_RIGHT: led5=!led5;break;
		}
		
		i++;
		if(i%20 ==0)
		{
			led1=!led1;//LED1闪
		}
		delay_ms(10);
		
	}
}


LED1闪,不使用直接在while里延时的方式 ,而是通过一个i做中间变量的方式 ,是因为假设直接使用延时,因为想看到灯闪,延时的时间就需要较长,而在延时的时间里,CPU等于延在那空等,这个时候按动按键,按键的检测可能反应就不够快!

key.c

#include "key.h"
#include "SysTick.h"

void key_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure; 
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//同时打开PA和PE端口时钟
	
	GPIO_InitStructure.GPIO_Pin=KEY_UP_Pin; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;	//配置成输入、下拉电阻模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	//输入模式的频率配不配置不影响
	GPIO_Init(KEY_UP_Port,&GPIO_InitStructure);//初始化KEY_UP_Pin
	
	
	GPIO_InitStructure.GPIO_Pin=KEY_LEFT_Pin|KEY_DOWN_Pin|KEY_RIGHT_Pin; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;	//配置成输入、上拉电阻模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	//输入模式的频率配不配置不影响
	GPIO_Init(KEY_Port,&GPIO_InitStructure);//初始化KEY_LEFT_Pin|KEY_DOWN_Pin|KEY_RIGHT_Pin
}



u8 KEY_Scan(u8 mode) mode =0--单次扫描,mode =1--连接扫描
{
	static u8 key=1;//key用来判断按键是否连续按下;定义成static可以保证程序中断恢复时仍然保持上一次的值
	if(key==1&&(K_UP==1||K_DOWN==0||K_LEFT==0||K_RIGHT==0))//检测是否有按键按下
	{
		key=0;
		delay_ms(10);
		if(K_UP==1)
		{
			return KEY_UP;
		}
		else if (K_DOWN==0)
		{
			return KEY_DOWN;
		}
		else if (K_LEFT==0)
		{
			return KEY_LEFT;
		}	
		else if (K_RIGHT==0)
		{
			return KEY_RIGHT;
		}	
	}
	else if (K_UP==0&&K_DOWN==1&&K_LEFT==1&&K_RIGHT==1)//检测是否松开按键
	{
		key=1;
	}
	if(mode==1)//如果调用Key_Scan传进来的mode=1,则强制key始终等于1,这等于取消了上条的松开按键检测
	{
		key=1;
	}
	return 0;
	
}



key.h

#ifndef _key_H
#define _key_H

#include "system.h"

#define KEY_UP_Pin					GPIO_Pin_0
#define KEY_UP_Port					GPIOA

#define KEY_LEFT_Pin					GPIO_Pin_2
#define KEY_DOWN_Pin					GPIO_Pin_3
#define KEY_RIGHT_Pin					GPIO_Pin_4
#define KEY_Port							GPIOE

//使用位带的方式读取引脚电平
#define K_UP					PAin(0)
#define K_DOWN				PEin(3)
#define K_LEFT				PEin(2)
#define K_RIGHT				PEin(4)

//直接使用库函数的方式读取引脚电平
//#define K_UP					GPIO_ReadInputDataBit(KEY_UP_Port,KEY_UP_Pin)
//#define K_DOWN				GPIO_ReadInputDataBit(KEY_Port,KEY_DOWN_Pin)
//#define K_LEFT				GPIO_ReadInputDataBit(KEY_Port,KEY_LEFT_Pin)
//#define K_RIGHT				GPIO_ReadInputDataBit(KEY_Port,KEY_RIGHT_Pin)

#define KEY_UP					1
#define KEY_DOWN				2
#define KEY_LEFT				3
#define KEY_RIGHT				4

void key_Init(void);
u8 KEY_Scan(u8 mode);


#endif

以上代码经实际上机实验,测试通过!

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

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

相关文章

亚马逊---设计弹性架构

一个好的架构师可以做到以下几点: 根据需求设计事件驱动型架构、微服务架构和/或多层架构 确定架构设计中使用的组件的扩展策略 根据要求确定实现松耦合所需的AWS服务 确定何时使用容器 确定何时使用无服务器技术和模式 根据要求推荐合适的计算、存储、联网和数据库…

HarmonyOS NEXT 网格元素交换案例

网格元素交换案例 介绍 直接进行交换和删除元素会给用户带来不好的体验效果,因此需要在此过程中注入一些特色的动画来提升体验效果,本案例通过Grid组件、attributeModifier、以 及animateTo函数实现了拖拽动画和删除动画。 效果图预览 使用说明&#…

【网络】Burpsuite学习笔记

文章目录 1.介绍1.1 正常客户端与服务端通信&BurpSuite代理后1.2 下载激活参考地址1.3 代理设置1.4 Proxy SwitchyOmega 使用1.4.1 新建情景模式1.4.2 设置代理1.4.2 应用选项 1.5 FoxyProxy 使用1.6 安装证书1.6.1 方式一1.6.2 方式二1.6.3 浏览器安装证书1.6.4 或者直接双…

基于改进遗传算法的配电网故障定位(matlab代码)

1 主要内容 该程序复现文章《基于改进遗传算法的配电网故障定位》,将改进的遗传算法应用于配电网故障定位中, 并引入分级处理思想, 利用配电网呈辐射状的特点, 首先把整个配电网划分为主干支路和若干独立区域, 再利用该算法分别对各独立区域进行故障定位, 然后进行…

独立开源版:零点城市社交电商v2.1.2.4

源码介绍 独立版:零点城市社交电商v2.1.2.4 新增首页新增多弹窗 注意:如果没有此完整程序勿下载 全开源解密版代码,后端完全开源,前端是VUE前端,可自行二开自己想要的功能。 独立版零点城市社交电商 小程序致力于…

tcp bbr pacing 的对与错

前面提到 pacing 替代 burst 是大势所趋,核心原因就是摩尔定律逐渐失效,主机带宽追平交换带宽,交换机不再能轻易吸收掉主机突发,且随着视频类流量激增,又不能以大 buffer 做带宽后备。因此,主机必须 pacing…

CentOS的简单介绍及常用命令

1、CentOS 的简单介绍: CentOS是Community Enterprise Operating System的缩写,也叫做社区企业操作系统。是企业Linux发行版领头羊Red Hat Enterprise Linux(以下称之为RHEL)的再编译版本(是一个再发行版本&#xff09…

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第五套

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第五套 (共9套,有答案和解析,答案非官方,仅供参考)(共九套,每套四十个选择题) 部分题目分享,完整版获取(WX:didadida…

gazebo中vins-fusion在仿真小车上的部署

软件要求:Ubuntu 20.04 ros的noetic版本,我是在虚拟机vitrualbox上运行的 这几天在学ROS,跟着赵虚左老师过了一遍之后,感觉还是有很多不懂的地方,xtdrone上仿真跟着文档走了一遍,好像没学到什么东西&#…

【华为笔试题汇总】2024-04-17-华为春招笔试题-三语言题解(Python/Java/Cpp)

🍭 大家好这里是KK爱Coding ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为近期的春秋招笔试题汇总~ 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢&#x1f…

【计算机考研】考408,还是不考408,性价比高❓

最近刷了很多帖子都偏向408太难了不要报考 但我的看法是408是计算机的考研趋势,并且择校的选择更多,408只是科目更广泛,与自命题相比其实各有各的难度 如果觉得自己数学基础不太好,时间不太够的同学可以了解一下自命题&#xff…

nodejs模块机制

模块机制 CommonJs规范 模块引用 上下文提供require()方法来引人外部模块var math require(math) 模块定义 exports 对象用于到处当前模块中的方法和变量module代表模块自身 exports.add function() {...}在另一个模块中使用require()方法进行导入。就可以使用 区别和联系 …

电力系统卫星授时信号安全隔离装置防护方案

电力系统是国家关键基础设施, 电力安全关系国计民生, 是国家安全的重要保障, 与政治安全、经济安全、 网络安全、社会安全等诸多领域密切关联。电网运行情况瞬息万变,为了在其发生事故时能够及时得到处理,需要统一的时…

Redis中的事务(二)

事务 一个完整的WATCH事务执行过程 假设当前服务端为c10086,而数据库watched_keys字典的当前状态如图所示,那么当c10086执行以下WATCH命令之后 c10086> WATCH "name" OKwatched_keys字典将更新如图所示的状态。接下来客户端c10086继续向…

[2021最新]Java时间戳和日期时间互转换

代码: import java.text.ParseException; import java.text.SimpleDateFormat;public class MainProcess {public static void main(String[] args) throws ParseException {// 1.set formatSimpleDateFormat timeSmat new SimpleDateFormat("yyyy-MM-dd HH:…

Kubernetes中安装部署ActiveMQ集群(手把手式记录)

目录 1、创建命名空间 nacos-cluster 2、配置文件准备 2.1 activemq0.xml 2.2 activemq1.xml 2.3 activemq2.xml 3、创建configMap cm-activemq 4、创建activemq-cluster.yaml 5、执行命令部署 6、部署成功,查看结果 这里以3个borker的集群为例&#xff0…

Facade 外观

意图 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一字系统更加容易使用。 结构 其中: Facade知道哪些子系统负责处理请求;将客户的请求代理给适当的子系统对象。 Subsystem classes…

QGIS插件Geo-SAM使用(基于SAM半自动标注遥感图像)

0.Geo-SAM介绍 Geo-SAM是一个QGIS插件,旨在帮助人们在使用大尺寸地理空间栅格图像时有效地分割、描绘或标记地貌。Segment Anything Model (SAM) 是一个具有超能力的基础 AI 模型,但模型大小巨大,即使使用现代 GPU&am…

C++学习进阶版(一):用C++写简单的状态机实现

目录 一、基础知识 1、状态机 2、四大要素 3、描述方式 4、设计步骤 5、实现过程中需注意 (1) 状态定义 (2) 状态转换规则 (3) 输入处理 (4) 状态机的封装 (5…

Nginx第2篇-HTTPS配置教程

背景 我最近做个项目要上线,接口部署到服务器,总不能给别人个ip地址加端口吧,而且小程序上线要有接口不能是ip和http协议,必须是https协议。这里记录下使用Nginx配置HTTPS的过程,主要包含以下三部分。 申请域名SSL证…