51单片机STC89C52RC——4.1 独立按键(数码管显示按键值)

news2024/11/22 22:16:47

目录

目录

目的

一,STC单片机模块

二,矩阵按键模块

2.1 针脚定义

​编辑 

2.2 矩阵按键位置

2.3 如何理解按键按下后针脚的高低电平

2.3.1 错误理解1

2.3.2 错误理解2

2.3.3 正确判定按下的是那个按键的逻辑

2.3.4 判定按键按下的依次扫描程序代码如下

三,创建Keil项目

四,代码 

五,代码编译、下载到51单片机

六,效果

​​编辑


目的

按下矩阵按键,数码管显示按下的键值

一,STC单片机模块

二,矩阵按键模块

2.1 针脚定义

 

2.2 矩阵按键位置

2.3 如何理解按键按下后针脚的高低电平

2.3.1 错误理解1

初学者:按键按下后就到通,针脚导通就是高电平(我最开始是这么理解的)。这种理解不是不正确,只是没结合实际电路分析

我们按照初学者的逻辑来分析下

假如S1按下

P17和P13 此时是相同的电平。那么他们是同时处于高电平还是低电平呢?我们在程序中怎么去判定呢是S1按下的呢?这里要明白  系统上电后针脚P10-P17都是低电平。那么P13和P17及时接通了也还是都处于低电平。

2.3.2 错误理解2

既然要有电位差,那直接先给P17-P14都给高电平,然后判定P10-P13上的电平。或者先给P10-P14高电平,然后判断P17-P14 的电平。我们看电路图

我们来判定P17 上的电平。如果是高电平,S1按下 P17是高电平,S2按下P17也是高电平,S3按下P17也是高电平,S4按下P17还是高电平。实际上我们不能确定按下的那个按键。

2.3.3 正确判定按下的是那个按键的逻辑

我们只能依次给P10-P13(纵排)或者P17-P14(横排)高电平,为什么要依次给高电平?不能同时给高电平?上面两个错误理解已经说了。

假如按键按下了S10,我们来分析。

我们先给P10 高电平,如下图,然后分别检测P17-P14的电平状态。发现P17-P14全是低电平。

在把P10设置为低电平,P11设置为高电平,如下图。然后分别检测P17-P14的电平状态。发现P17-P14任然全是低电平。

在把P11设置为低电平,P12设置为高电平,如下图。然后分别检测P17-P14的电平状态。发现P15是高电平,P14、P16、P17是低电平。

再把P12设置为低电平,P13设置为高电平,如下图。然后分别检测P17-P14的电平状态。发现P17-P14任然全是低电平。

所以这里只能依次扫描

2.3.4 判定按键按下的依次扫描程序代码如下


unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay_ms(20);while(P1_7==0);Delay_ms(20);KeyNumber=1;}
	if(P1_6==0){Delay_ms(20);while(P1_6==0);Delay_ms(20);KeyNumber=5;}
	if(P1_5==0){Delay_ms(20);while(P1_5==0);Delay_ms(20);KeyNumber=9;}
	if(P1_4==0){Delay_ms(20);while(P1_4==0);Delay_ms(20);KeyNumber=13;}
	
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay_ms(20);while(P1_7==0);Delay_ms(20);KeyNumber=2;}
	if(P1_6==0){Delay_ms(20);while(P1_6==0);Delay_ms(20);KeyNumber=6;}
	if(P1_5==0){Delay_ms(20);while(P1_5==0);Delay_ms(20);KeyNumber=10;}
	if(P1_4==0){Delay_ms(20);while(P1_4==0);Delay_ms(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay_ms(20);while(P1_7==0);Delay_ms(20);KeyNumber=3;}
	if(P1_6==0){Delay_ms(20);while(P1_6==0);Delay_ms(20);KeyNumber=7;}
	if(P1_5==0){Delay_ms(20);while(P1_5==0);Delay_ms(20);KeyNumber=11;}
	if(P1_4==0){Delay_ms(20);while(P1_4==0);Delay_ms(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay_ms(20);while(P1_7==0);Delay_ms(20);KeyNumber=4;}
	if(P1_6==0){Delay_ms(20);while(P1_6==0);Delay_ms(20);KeyNumber=8;}
	if(P1_5==0){Delay_ms(20);while(P1_5==0);Delay_ms(20);KeyNumber=12;}
	if(P1_4==0){Delay_ms(20);while(P1_4==0);Delay_ms(20);KeyNumber=16;}
	
	return KeyNumber;
}

三,创建Keil项目

详细参考:51单片机STC89C52RC——创建Keil项目-CSDN博客

四,代码 

main.c

#include <REGX52.H>
#include "ShuMaGuan.h"
#include "Delay.h"
#include "MatrixKey.h"
/**
 * 函    数:主函数
 * 参    数:无
 * 返 回 值:无
 */
void main()
{
	unsigned int KeyNum=0,ShowKeyNum=0;
	while(1)
	{
		KeyNum=MatrixKey();			//获取按下的键
		if(KeyNum){
			ShowKeyNum=KeyNum;		//将按下的键赋值给显示值
		}
		ShuMaGuan_ShowNumber(ShowKeyNum);//数码管显示
	}
}

ShuMaGuan.c

#include <REGX52.H>
#include "Delay.h"
/*数码管可显示值*/
unsigned int ShuMaGuan_EnableDisplayValue[]={
	0,1,2,3,4,
	5,6,7,8,9,
	'A','C','E','F','H',
	'J','L','P','q','U',
	'.','b','d','u','-'};
/*数码管显示值对应的HEX*/
unsigned int ShuMaGuan_EnableDisplayHEX[]={
	0x3F,0x06,0x5B,0x4F,0x66,
	0x6D,0x7D,0x07,0x7F,0x6F,
	0x77,0x39,0x79,0x71,0x76,
	0x1E,0x38,0x73,0x67,0x3E,
	0x80,0x7C,0x5E,0x1C,0x40};
/**
 * 函    数:获取可显值对应的HEX
 * 参    数:数码管显示的值
 * 返 回 值:数码管显示时对应的HEX
 */
unsigned int ShuMaGuan_GetEnableDisplayValueOfHEX(unsigned int Value)
{
	unsigned int index=0;
	for(index=0;index<24;index++)//遍历显示值的数组
	{
		if(ShuMaGuan_EnableDisplayValue[index]==Value)//找到对应值的索引
		{
			break;
		}
	}
	return ShuMaGuan_EnableDisplayHEX[index];
}
/**
 * 函    数:设置数码管要显示的值
 * 参    数:显示值
 * 返 回 值:无
 */
void ShuMaGuan_SetDisplayValue(unsigned int Value)
{
	/*将要显示的值 复制给P0*/
	P0=ShuMaGuan_GetEnableDisplayValueOfHEX(Value);
}
/**
 * 函    数:设置要显示的数码管 位置
 * 参    数:位置(左起1-8)
 * 返 回 值:无
 */
void ShuMaGuan_SetDisplayLocation(unsigned int Location)
{
	switch(Location)		//位码输出
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
}
/**
 * 函    数:数码管展示
 * 参    数:Location 显示的位置,Value 显示的值
 * 返 回 值:无
 */
void ShuMaGuan_Display(unsigned int Location,unsigned int Value)
{
	/*显示位置*/
	ShuMaGuan_SetDisplayLocation(Location);
	/*显示值*/
	ShuMaGuan_SetDisplayValue(Value);
	/*等待显示稳定*/
	Delay_10us(10);
	/*消除阴影*/
	P0=0x00;
}
/**
 * 函    数:显示一个数字 
 * 参    数:整形数字 -32767到32767
 * 返 回 值:无
 */
void ShuMaGuan_ShowNumber(int Num)
{
	int Location=8,Temp,Flag=1;
	if(Num<0)
	{
		Num=-Num;//再将负数转为正数
		Flag=-1;//表示需要显示‘负号-’
	}
	
	Temp=Num%10;
	while(Location>0&&Num>0)
    {
		ShuMaGuan_Display(Location,Temp); 
		Location--;
		Num=Num/10;
		Temp=Num%10;
    }	
	if(Flag==-1&&Location>0)
	{
		ShuMaGuan_Display(Location,'-');//负数显示负号 
	}
}

ShuMaGuan.h

#ifndef __SHUMAGUAN_H_
#defind __SHUMAGUAN_H_
void ShuMaGuan_Display(unsigned int Location,unsigned int Value);
void ShuMaGuan_ShowNumber(int Num);
#endif

Delay.c


/**
 * 函    数:延时函数 毫秒
 * 参    数:ms 延时多少毫秒
 * 返 回 值:无
 */
void Delay_ms(int ms)	//@12.000MHz
{
	unsigned char data i, j;
	while(ms--)
	{ 
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
/**
 * 函    数:延时函数 毫秒
 * 参    数:ms 延时多少毫秒
 * 返 回 值:无
 */
void Delay_us(int ms)	//@12.000MHz
{
	unsigned char data i, j;
	while(ms--)
	{ 
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
/**
 * 函    数:延时函数  10微秒
 * 参    数:无
 * 返 回 值:无
 */
void Delay_10us(int _10us)	//@11.0592MHz
{
	unsigned char data i;
	while(_10us--)
	{
		i = 2;
		while (--i);
	}
}

 Delay.h

#ifndef __DELAY_H_
#defind __DELAY_H_ 
void Delay_ms(int ms);
void Delay_10us(int _10us);
#endif

 MatrixKey.c

#include <REGX52.H>
#include "Delay.h"
 /**
  * 函    数:矩阵键盘读取按键键码
  * 参    数:无
  * 返 回 值:KeyNumber 按下按键的键码值
			  如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0

  */
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay_ms(20);while(P1_7==0);Delay_ms(20);KeyNumber=1;}
	if(P1_6==0){Delay_ms(20);while(P1_6==0);Delay_ms(20);KeyNumber=5;}
	if(P1_5==0){Delay_ms(20);while(P1_5==0);Delay_ms(20);KeyNumber=9;}
	if(P1_4==0){Delay_ms(20);while(P1_4==0);Delay_ms(20);KeyNumber=13;}
	
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay_ms(20);while(P1_7==0);Delay_ms(20);KeyNumber=2;}
	if(P1_6==0){Delay_ms(20);while(P1_6==0);Delay_ms(20);KeyNumber=6;}
	if(P1_5==0){Delay_ms(20);while(P1_5==0);Delay_ms(20);KeyNumber=10;}
	if(P1_4==0){Delay_ms(20);while(P1_4==0);Delay_ms(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay_ms(20);while(P1_7==0);Delay_ms(20);KeyNumber=3;}
	if(P1_6==0){Delay_ms(20);while(P1_6==0);Delay_ms(20);KeyNumber=7;}
	if(P1_5==0){Delay_ms(20);while(P1_5==0);Delay_ms(20);KeyNumber=11;}
	if(P1_4==0){Delay_ms(20);while(P1_4==0);Delay_ms(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay_ms(20);while(P1_7==0);Delay_ms(20);KeyNumber=4;}
	if(P1_6==0){Delay_ms(20);while(P1_6==0);Delay_ms(20);KeyNumber=8;}
	if(P1_5==0){Delay_ms(20);while(P1_5==0);Delay_ms(20);KeyNumber=12;}
	if(P1_4==0){Delay_ms(20);while(P1_4==0);Delay_ms(20);KeyNumber=16;}
	
	return KeyNumber;
}

 MatrixKey.h

#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__

unsigned char MatrixKey();

#endif

五,代码编译、下载到51单片机

代码编译请参考

《51单片机STC89C52RC——代码编译-CSDN博客》

代码下载请参考

《51单片机STC89C52RC——STCAI-ISP代码下载-CSDN博客》

六,效果

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

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

相关文章

186.二叉树:二叉搜索树中的插入操作(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

ASP.NET Core 6.0 多种部署方式

IIS 环境准备和部署 安装并配置 IIS 安装 IIS&#xff0c;在搜索输入并打开 启用或关闭 Windows 功能。 配置IIS 需要配置 ASPNETCore 部署IS 程序包安装 &#xff08;ASP.NET Core Module v2&#xff09; Download .NET 6.0 (Linux, macOS, and Windows).NET 6.0 downloads…

鸿蒙开发系统基础能力:【@ohos.accessibility (辅助功能)】

辅助功能 说明&#xff1a; 本模块首批接口从 API version 7 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import accessibility from ohos.accessibility;AbilityState 辅助应用状态类型。 系统能力&#xff1a;以下各项对应的…

电子杂志制作工具推荐:让你轻松成为编辑大人

在这个数字化的时代&#xff0c;电子杂志已经成为信息传播的重要载体。它不仅能够满足人们对阅读的需求&#xff0c;还能够提供更加丰富、互动的阅读体验。因此&#xff0c;掌握一款好用的电子杂志制作工具&#xff0c;已经成为每个编辑大人的必备技能。接下来告诉大家一个超简…

永磁同步电机驱动死区补偿

1 死区效应及补偿 1. 1 死区效应 在本文的电机控制嵌入式系统中,逆变器为三 相电压型桥式逆变电路,如图 1 所示。 在理想状态 下,上桥臂和下桥臂的控制信号满足互补通断原则, 即上桥臂开通时,下桥臂关断,反之亦然。 而在实际 应用中,开关管的通断需要一定的开通时…

Java项目:基于SSM框架实现的绿色农产品推广应用网站果蔬商城水果商城蔬菜商城【ssm+B/S架构+源码+数据库+答辩PPT+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的绿色农产品推广应用网站果蔬商城水果商城蔬菜商城 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能…

容器之按钮盒构件演示

代码; #include <gtk-2.0/gtk/gtk.h> #include <glib-2.0/glib.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <stdio.h>int main(int argc, char *argv[]) {gtk_init(&argc, &argv);GtkWidget *window;window gtk_window_new(GTK_WINDO…

如何使用Windows备份轻松将数据转移到新电脑?这里有详细步骤

序言 我们都知道那种买了一台新电脑,就想直接上手的感觉。我记得在过去的日子里,要花几个小时传输我的文件,并试图复制我的设置。在当今传输数据的众多方法中,Windows备份提供了一个简单可靠的解决方案。 登录到你的Microsoft帐户 Microsoft在传输过程中使用其云存储来保…

理解 JTBD 框架和EJ 理念:深挖以用户为中心的设计

在与用户的交流中&#xff0c;我们发现对用户需求的精准洞察普遍困扰着产品经理、设计、企划人员&#xff0c;因为当今消费者行为已经由单品消费转向场景消费&#xff0c;千人千面的个性化需求出现&#xff0c;消费者数据维度极大丰富&#xff0c;这对把握用户体验造成了很大挑…

第六十六天打卡 | 卡码网101 孤岛的总面积、卡码网102 沉没孤岛、卡码网103 水流问题、卡码网104 建造最大岛屿

卡码网101 孤岛的总面积 这一题在昨天的基础上&#xff0c;将比较得出最大孤岛面积的逻辑改为统计所有孤岛面积之和的逻辑即可。 最近做项目的时候也发现&#xff0c;很多时候代码逻辑能够复用最好就不要再自己写&#xff0c;防止出错&#xff0c;当然刷代码题的时候不…

【已解决】手机进入fastboot无法退出

文章目录 报错及效果图报错代码效果图 解决方案必要的解决方法可能有用的解决方法 报错及效果图 报错代码 手机屏幕显示fastboot&#xff0c;长按电源键无法正常启动 效果图 解决方案 必要的解决方法 1.在电脑上下载并安装adb/fastboot驱动&#xff0c;可以在这里免费下载&…

功能测试【测试用例模板、Bug模板、手机App测试】

功能测试 Day01 web项目环境与测试流程、业务流程测试一、【了解】web项目环境说明1.1 环境的定义&#xff1a;项目运行所需要的所有的软件和硬件组合1.2 环境(服务器)的组成&#xff1a;操作系统数据库web应用程序项目代码1.3 面试题&#xff1a;你们公司有几套环境&#xff1…

【对抗去偏】BiasAdv: Bias-Adversarial Augmentation for Model Debiasing

原文标题&#xff1a; BiasAdv: Bias-Adversarial Augmentation for Model Debiasing 原文代码&#xff1a; 暂无 发布年度&#xff1a; 2023 发布期刊&#xff1a; CVPR 摘要 Neural networks are often prone to bias toward spurious correlations inherent in a dataset, …

路由器的Wi-Fi性能是否限制了你的网速?这里有你想要的答案

​你的无线网络速度阻碍了你吗?信不信由你,升级到超快的互联网计划可能不值得。以下是如何判断路由器的Wi-Fi速度是否阻碍了你,以及你能做些什么。 如何测试你的Wi-Fi速度 比较你的有线速度和无线速度可以表明你的路由器是否阻碍了你。虽然很多人认为“Wi-Fi”和“互联网”…

网络虚拟化考题

vrrp讲过吗&#xff1f;&#xff1f;&#xff1f; d 每一层都是什么设备啊 abcd 为啥流量不可控不可视 c是啥意思 讲过吗 abc aNET网络虚拟化是啥啊 为啥&#xff1f;&#xff1f; 啥是CDN&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;

【python】OpenCV——Color Correction

文章目录 cv2.aruco 介绍imutils.perspective.four_point_transform 介绍skimage.exposure.match_histograms 介绍牛刀小试遇到的问题 参考学习来自 OpenCV基础&#xff08;18&#xff09;使用 OpenCV 和 Python 进行自动色彩校正 cv2.aruco 介绍 一、cv2.aruco模块概述 cv2.…

关于微信小程序取消获取用户昵称的一些思考

官方说明&#xff0c;有部分小程序乱用授权&#xff0c;强迫用户提交头像和昵称。 核心是微信担心用户信息被滥用。 其一 &#xff0c;微信头像经常是本人真是照片&#xff0c;在现在人工智能算法的加持下&#xff0c;人脸数据太容易被套取。 其二&#xff0c;微信名称同理&…

node版本过高出现ERR_OSSL_EVP_UNSUPPORTED错误

错误原因&#xff1a; 新版本的nodejs使用的openssl和旧版本不同&#xff0c;导致出错 解决方法&#xff1a; 1.将node版本重新换回16.x 2 windows 下 在package.json文件下添加set NODE_OPTIONS--openssl-legacy-provider && "scripts": {"dev"…

手把手教你java CPU飙升300%如何优化

背景 今天有个项目运行一段时间后&#xff0c;cpu老是不堪负载。 排查 top 命令 TOP 命令 top t 按cpu 排序 top m 按内存使用率排序 从上面看很快看出是 pid 4338 这个进程资源消耗很高。 top -Hp pid top -Hp 4338 找到对应线程消耗的资源shftp cpu占用进行排序&#xf…

拒绝零散碎片, 一文理清MySQL的各种锁

系列文章目录 学习MySQL先有全局观&#xff0c;细说其发展历程及特点 Mysql常用操作&#xff0c;谈谈排序与分页 拒绝零散碎片&#xff0c; 一文理清MySQL的各种锁&#xff08;收藏向&#xff09; 系列文章目录一、MySQL的锁指什么二、排他与共享三、全局锁&#xff08;Global…