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

news2024/11/23 12:17:52

目录

目录

目的

一,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/1860180.html

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

相关文章

版本控制工具-git的基本使用

目录 前言一、git简介二、git工作流程三、安装git并配置git3.1 配置用户名和邮箱3.2 配置.gitignore文件&#xff08;可选&#xff09;3.3 配置ssh key&#xff08;可选&#xff09; 四、git基本命令4.1 创建本地仓库4.2 将工作区内容提交到本地仓库4.3 将本地仓库内容推送到远…

Python数据分析-对驾驶安全数据进行预测

一、研究背景和意义 随着汽车保有量的不断增加&#xff0c;交通事故已成为全球范围内的重大公共安全问题。每年因交通事故造成的人员伤亡和财产损失给社会带来了巨大的负担。为了提高驾驶安全&#xff0c;减少交通事故的发生&#xff0c;许多研究致力于探索影响驾驶安全的因素…

C++ | Leetcode C++题解之第190题颠倒二进制位

题目&#xff1a; 题解&#xff1a; class Solution { private:const uint32_t M1 0x55555555; // 01010101010101010101010101010101const uint32_t M2 0x33333333; // 00110011001100110011001100110011const uint32_t M4 0x0f0f0f0f; // 000011110000111100001111000011…

这就是算法:日常生活中的算法应用

日常小例 当我们一听到“算法”这个词&#xff0c;脑海里可能立刻浮现出数学公式和复杂计算的画面。 但事实上&#xff0c;算法并不总是那么高深莫测&#xff0c;很多算法其实是基于我们日常生活中随处可见的基本逻辑。 在深入讨论算法之前&#xff0c;我想先分享一个让人好…

python基础语法 003-2 数据类型字典

1 字典 1.1 字典的表示 字典&#xff1a;也是存储多个数据的&#xff0c;存储多个数据&#xff0c;不记得第二个存储什么用字典&#xff0c;存储多个数据首推列表&#xff1b; 1.1.1 表示方法&#xff1a; {‘key’ : value},用逗号隔开 #列表表示 my_songs [花海, 棉花糖…

2023国家最高科学技术奖薛其坤院士:科学家的幸福感来自于哪里

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 文丨浪味仙 排版丨沛贤 深度好文&#xff1a;2000字丨8分钟阅读 6 月 24 日&#xff0c;2023 年度国家最高科学技术奖在京揭晓&#xff0c;薛其坤院士荣获中国科技界崇高荣誉&#xff0c;这不…

pyCharm项目更改目录后,执行路径未更新的解决办法

最头疼环境问题。 换电脑&#xff0c;原python脚本打成zip包&#xff0c;全部拷贝到新电脑上。一开始放到路径A下&#xff0c;不清楚是路径太长还是路径含有中文&#xff0c;执行失败。于是&#xff0c;更换到路径B&#xff0c;结果&#xff0c;仍然执行失败。Run中显示的信息…

【大数据】—量化交易实战案例双均线策略(移动平均线)

声明&#xff1a;股市有风险&#xff0c;投资需谨慎&#xff01;本人没有系统学过金融知识&#xff0c;对股票有敬畏之心没有踏入其大门&#xff0c;今天用另外一种方法模拟炒股&#xff0c;后面的模拟的实战全部用同样的数据&#xff0c;最后比较哪种方法赚的钱多。 量化交易…

天途重磅推出无人机教管平台3.1版及飞课APP

天途无人机教管平台&#xff0c;是一款为院校和培训机构等企业级客户提供的公开版无人机在线培训系统&#xff0c;包含后台管理的【教管平台】和终端的【掌上天途APP】。 天途历经4年上百次调研和迭代打磨&#xff0c;已为一百多家院校和培训机构等企业级客户解决了无人机教学和…

【2024最新版】Windows11 23H2中文家庭版:免费下载!

Windows 11 23H2中文家庭版系统拥有稳定的性能、丰富的功能和卓越的安全性&#xff0c;很多用户都喜欢给自己的电脑安装上这个版本。但是&#xff0c;许多新手用户不清楚在哪里才能下载到Windows11家庭版&#xff1f;接下来小编给大家带来2024年最新的Windows 11 23H2中文家庭版…

基于rouyi框架的多租户改造

基于rouyi框架的多租户改造&#xff0c;重点是实现权限管理和数据隔离。权限管理相当于从原来的“顶级管理员admin-普通用户user”转变为“顶级管理员admin-租户管理员tanantAdmin-普通用户user”。数据隔离主要通过分库、分表、表内设置tenantId字段进行过滤三种方式。 本文主…

前端项目外包出去,是我痛苦的开始。如何破?

不止一个老铁给我反馈&#xff0c;他们把其前端项目外包出去&#xff0c;非常的痛苦&#xff0c;远不如用自己的员工省心。明面上钱省了&#xff0c;实际精力大量耗费在上面&#xff0c;一算账并没省&#xff0c;反而闹了一肚子气&#xff0c;问我这事该如何破&#xff1f;其实…

IEEE Signal Processing Letters投稿记录

0.写在前面&#xff1a; 该期刊4页正文&#xff0c;第5页只能是参考文献&#xff0c;篇幅紧凑。 最多只有一次小修机会&#xff0c;或者直接接收。网上说平均审稿周期是2.7个月。 祝愿大家都能如愿&#xff0c;一次接收&#xff01; 期刊网址&#xff1a;投稿 投稿网址&…

被忽视的商机:全民拼购模式如何助力企业实现惊人业绩

在当今的商业环境中&#xff0c;一个被大多数人忽视但实则蕴藏着巨大潜力的模式正在悄然崭露头角。不同于传统商业模式的惯性思维&#xff0c;这一模式在细节上进行了巧妙的调整&#xff0c;带来了意想不到的效果。我的一位客户便凭借这一策略&#xff0c;实现了令人瞩目的业绩…

Java项目毕业设计:基于springboot+vue的幼儿园管理系统

数据库:MYSQL5.7 **应用服务:Tomcat7/Tomcat8 使用框架springbootvue** 项目介绍 管理员&#xff1b;首页、个人中心、用户管理、教师管理、幼儿信息管理、班级信息管理、工作日志管理、会议记录管理、待办事项管理、职工考核管理、请假信息管理、缴费信息管理、幼儿请假管理…

轻松驾驭多云存储,不再为文件流转烦恼,可道云teamOS带你走进便捷的多云时代

不知道大家有没有遇到过这样的问题&#xff1a;使用了不同云平台的存储&#xff0c;但不同的平台存储就存在文件不流通、共享困难、管理困难等问题。 对于这种情况&#xff0c;我们该如何进行资源整合&#xff0c;实现不同挂载存储之间的文件管理与流转&#xff1f; 这些问题…

Linux基础 - shell基础

目录 零. 简介 一、常见的 Shell 类型 二、Shell 命令格式 三、基本命令 四、通配符 五、重定向 六、管道 七、变量 八、条件判断和流程控制 零. 简介 Shell 是一种命令解释器&#xff0c;在 Ubuntu 系统中&#xff0c;它负责接收用户在命令行中输入的命令&#xff0c…

AI大神 Sebastian Raschka 发布新书《从零开始构建大语言模型》

Sebastian 热衷于开源软件&#xff0c;还喜欢写作&#xff0c;撰写了畅销书《Python Machine Learning》&#xff08;《Python 机器学习》&#xff09;和《Machine Learning with PyTorch and ScikitLearn》。 最近&#xff0c;Sebastian Raschka 发布了新书《Build a Large L…

pytorch神经网络训练(LeNet-5)

LeNet-5 导包 import osimport torchimport torch.nn as nnimport torch.optim as optimfrom torch.utils.data import Dataset, DataLoaderfrom PIL import Imagefrom torchvision import transforms 定义自定义图像数据集 class CustomImageDataset(Dataset):def __init_…

Git的安装以及使用

一.简单介绍 1.1版本控制 版本控制是指对软件开发过程中各种程序代码,配置文件及说明文档等文件变更管理&#xff0c;是软件配置管理的核心思想之一。 版本控制最重要的内容是追踪文件的变更&#xff0c;它将什么时候&#xff0c;什么人更改了文件的什么内容等信息忠实的记录…