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

news2024/12/26 23:04:05

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

软件方法就是在首次检测到低电平时加延时,通常延时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

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

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

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

相关文章

SystemUI GlobalActions plugin解析

com.android.systemui.action.PLUGIN_GLOBAL_ACTIONS 系统的默认实现为GlobalActionsImpl: 是谁发送了showShutdownUi指令? GlobalActionsImpl 是通过inject的方式创建的 GlobalActionsComponent是一个system UI services,配置在config.xml中&#xff…

架构师系列-Nginx、OpenResty(一)- 基本使用配置

Nginx 模块 高度模块化的设计是 Nginx 的架构基础,Nginx 服务器被分解为多个模块,每个模块就是一个功能模块,只负责自身的功能,模块之间严格遵循“高内聚,低耦合”的原则。 核心模块 核心模块是 Nginx 服务器正常运行…

vue2项目升级到vue3经历分享

依据vue官方文档,vue2在2023年12月31日终止维护。因此决定将原来的岁月云记账升级到vue3,预计工作量有点大,于是想着把过程记录下来。 原系统使用的技术栈 "dependencies": {"axios": "^0.21.1","babel-…

博士困境::博士毕业出路何在

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验,帮助大家尽早适应研究生生活,尽快了解科研的本质。祝一切顺利!—…

Windows 搭建自己的大模型-通义千问

1、安装 pytorch https://pytorch.org/get-started/locally/ 点击进入官网,如图选择自己的环境得到pip安装依赖的命令: pip3 install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cpu 2、拉取代码并安…

欢乐钓鱼大师一键钓鱼,解放双手!

《钓鱼欢乐大师》是一款让玩家体验钓鱼乐趣的游戏,在游戏中,玩家可以通过技巧和策略钓到各种各样的鱼。为了提高钓鱼效率,让玩家更快地钓到大鱼,下面将介绍如何利用脚本来优化游戏体验。 第一步:准备工作 创建云机&…

开源贡献代码之​探索一下Cython

探索一下Cython 本篇文章将会围绕最近给Apache提的一个feature为背景,展开讲讲Cython遇到的问题,以及尝试自己从0写一个库出来,代码也已经放星球了,感兴趣的同学可以去下载学习。 0.背景 最近在给apache arrow提的一个feature因为…

在win下,python如何调用.so库

#撰写c代码 #通过gcc命令编译成.so库 gcc -shared -o ./lib/pointlib.so point.c #python调用.so库 #运行结果

聊聊 Linux iowait

哈喽大家好,我是咸鱼。 我们在使用 top 命令来查看 Linux 系统整体 CPU 使用情况的时候,往往看的是下面这一列: %Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 68.0 wa, 0.0 hi, 0.0 si, 0.0 st其中,man 手册解释 wa 表示 …

什么是大语言模型以及如何构建自己的大型语言模型?

一、关于大语言模型 LLM 对于无数的应用程序非常有用,如果我们自己从头开始构建一个,那我们可以了解底层的ML技术,并可以根据特定需求定制LLM,但是对资源的需求巨大。大型语言模型是一种 ML 模型,可以执行各种自然语言…

C语言 三目运算符

C语言 逻辑分支语句中 还有一种 三目运算符 我们编写代码如下 #include <stdio.h>int main() {const char* a 1 1 ? "表达式1" : "表达式2";printf("%s", a);return 0; }这里 我们根据逻辑 先定义一个a 然后 它的值 等于一个 三目运算…

CSS动画(css、js动画库:各种动画效果)

第一种方法&#xff1a;文字从上到下显示动画&#xff1b; <div class"text-container"><div class"text">文字从上到下显示</div></div><style scoped> /*确保 keyframes 规则在引用它的任何选择器之前定义&#xff0c;以避…

Centos之yum安装好玩的命令

1.会动的小火车 我在root下使用的 yum install sl.x86_64sl2.figlet yum install figlet.x86_64figlet 55553.cowsay会说话 yum install cowsay

MySQL无法打开情况下读取frm文件的表结构

一、背景&#xff1a; 开发人员通过MySQL客户端工具&#xff0c;可以访问MySQL5.7.6&#xff0c;可以访问具体的DB&#xff0c;可以查看小写表的数据&#xff0c;但是无法查看大写表的数据&#xff0c;报错信息为“table does not exist”。 二、检查与分析&#xff1a; ssh登录…

深度学习基础:循环神经网络中的长期依赖问题

循环神经网络中的长期依赖问题 在深度学习中&#xff0c;循环神经网络&#xff08;RNN&#xff09;是一种经典的模型&#xff0c;用于处理序列数据&#xff0c;如自然语言处理、时间序列预测等任务。然而&#xff0c;传统的RNN存在着一个长期依赖问题&#xff0c;即在处理长序…

element-ui et -i 编译默认主题报错:ReferenceError: primordials is not defined

报错信息如下 fs.js:40 } primordials;^ ReferenceError: primordials is not defined导致这个问题的原因&#xff1a;node和gulp版本冲突&#xff01;&#xff01; 我使用的是node 14版本 解决方法&#xff1a; 看了好几个帖子&#xff0c;都推荐使用node 11.15.0版本&am…

Docker基本管理和虚拟化

一、docker的发展历史 https://www.cnblogs.com/rongba/articles/14782624.htmlhttps://www.cnblogs.com/rongba/articles/14782624.html 二、docker的概述 Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源。 Docker是在Linux容器里运行…

B站评论无限点赞

网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x 提取码&#xff1a;0b8x

申请泛域名证书步骤

泛域名证书的广泛应用范围&#xff1a; 泛域名证书不同于普通的单域名数字证书和多域名数字证书&#xff0c;可以一次以一张证书对应无限多的域名&#xff0c;在功能性和方便性上远优于一般证书。 单域名证书顾名思义&#xff0c;一张证书只对应一个独立域名&#xff0c;多域…

页面分页打印,echarts图解决办法;生成PDF

1&#xff1a;echarts图片前端打印不是很完美&#xff0c;对于VUE2.0版本不是很有好 2&#xff1a;360浏览器不支持vue的最新版本的插件vue3-print-nb 3&#xff1a;vue-print-nb 可以打印带有echarts 一页内容&#xff0c;并且还存在bug&#xff0c;第一次点击打印没有&…