51单片机STC89C52RC——4.1 独立按键(数码管显示按键值)
目录
目录
目的
一,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博客》
六,效果

相关文章:
51单片机STC89C52RC——4.1 独立按键(数码管显示按键值)
目录 目录 目的 一,STC单片机模块 二,矩阵按键模块 2.1 针脚定义 编辑 2.2 矩阵按键位置 2.3 如何理解按键按下后针脚的高低电平 2.3.1 错误理解1 2.3.2 错误理解2 2.3.3 正确判定按下的是那个按键的逻辑 2.3.4 判定按键按下的依次扫描程…...
解决双击bootstrap.bat没有生成b2.exe文件
双击bootstrap.bat但是并没有没有生成b2.exe文件,会报如下错误: "cl" 不是内部或外部命令,也不是可运行的程序 或批处理文件。D:\cppsoft\boost_1_85_0\tools\build\src\engine>dir *.exe 驱动器 D 中的卷是 Data 卷的序列号是…...
AI穿戴设备是未来手机的终结者?中国AI商业化的未来预测
AI技术的发展正处于商业化应用的关键阶段,而中国在互联网时代已凭借商业化应用逆袭。AI算法大模型虽强大,但真正普惠民众需与设备深度结合。穿戴式智能设备就成为了新战场,AI算法与穿戴设备结合能释放更大工作效率。私人助理AI将成趋势&#…...
FPGA+Nvidia Orin NX+AI 异构视频图像处理开发平台在高端医疗和工业检测的应用,支持定制,支持国产化
FPGAGPU 异构架构视频图像处理开发平台,它结合了 AMD Zynq UltraScale MPSoC(FPGA)与 NVIDIA Jetson Orin NX(GPU)的强大功能,能够应用于对图像精准度和实时性有着严苛要求的行业领域。 Zynq UltraScale MP…...
2000-2023年各省名义GDP、实际GDP、GDP平减指数数据(含原始数据+计算过程+计算结果)(以2000年为基期)
2000-2023年各省名义GDP、实际GDP、GDP平减指数数据(含原始数据计算过程计算结果)(以2000年为基期) 1、时间:2000-2023年 2、范围:31省 3、指标:名义GDP、国内生产总值指数、实际GDP、GDP平减…...
python学习—字典(Dictionary)
系列文章目录 python学习—列表和元组 python学习—循环语句-控制流 python学习—合并TXT文本文件 python学习—统计嵌套文件夹内的文件数量并建立索引表格 python学习—查找指定目录下的指定类型文件 python学习—年会不能停,游戏抽签抽奖 python学习—合并多个Ex…...
鸿蒙开发:【组件启动规则(FA模型)】
组件启动规则(FA模型) 启动组件是指一切启动或连接应用组件的行为: 启动PageAbility、ServiceAbility,如使用startAbility()等相关接口。连接ServiceAbility、DataAbility,如使用connectAbility()、acquireDataAbili…...
网络编程5----初识http
1.1 请求和响应的格式 http协议和前边学过的传输层、网络层协议不同,它是“一问一答”形式的,所以要分为请求和响应两部分看待,同时,请求和响应的格式是不同的,我们来具体介绍一下。 1.1.1 请求 在介绍请求之前&…...
“用友审批+民生付款”,YonSuite让企业发薪更准时
随着现代企业经营模式的不断创新和市场竞争的加剧,企业薪资管理和发放的效率、准确性和及时性已成为企业管理的重要一环。然而,在实际操作中,许多企业面临着薪资管理复杂、发放流程繁琐、数据不准确等难点和痛点。为了解决这些问题࿰…...
EtherCAT扫盲,都是知识点
1. 什么是EtherCAT EtherCAT,全称Ethernet for Control Automation Technology,字面意思就是用于控制自动化技术的以太网。它是一种基于以太网的实时工业通信协议,简单说,就是让机器们通过网线互相聊天的高级方式。 EtherCAT 是最…...
开发中遇到的错误 - @SpringBootTest 注解爆红
我在使用 SpringBootTest 注解的时候爆红了,ait 回车也导不了包,后面发现是因为没有加依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId>…...
数据仓库的实际应用示例-广告投放平台为例
数据仓库的数据分层通常包括以下几层: ODS层:存放原始数据,如日志数据和结构化数据。DWD层:进行数据清洗、脱敏、维度退化和格式转换。DWS层:用于宽表聚合值和主题加工。ADS层:面向业务定制的应用数据层。…...
Beyond VL了解学习
Beyond VL:多模态处理的前沿 在今天的数据驱动时代,我们经常需要处理和分析多种类型的数据,例如文本、图像、视频和音频。Beyond VL 是一个先进的多模态模型,专为处理这些多种数据而设计。它能够同时处理多种模态的数据ÿ…...
AI音乐革命:创意产业的新篇章
随着科技的飞速发展,人工智能(AI)在各个领域的应用越来越广泛,特别是在音乐产业中,AI音乐大模型的涌现,正在重新定义音乐创作的边界。最近一个月,随着多个音乐大模型的轮番上线,素人…...
python从入门到精通1:注释
在Python编程中,注释是一种非常重要的工具,它不仅可以帮助我们记录代码的目的、工作方式以及任何需要注意的地方,还可以使代码更具可读性。Python提供了两种主要的注释方式:单行注释和多行注释。下面我们将深入探讨这两种注释方式…...
CountDownLatch(应对并发问题的工具类)
CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成操作以后,再执行当前线程;比如我们在主线程需要开启2个其他线程,当其他的线程执行完毕以后我们再去执行主线程,针对这 个需求我们就可以使用CountDownLatch来进…...
HarmonyOS开发知识 :扩展修饰器,实现节流、防抖、权限申请
引言 防重复点击,利用装饰器面向切面(AOP)的特性结合闭包,实现节流、防抖和封装权限申请。 节流 节流是忽略操作,在触发事件时,立即执行目标操作,如果在指定的时间区间内再次触发了事件&…...
自然语言NLP的基础处理
NLP基本处理从句子的情感分析、实体与实体直接的关系,句子结构来分析 情感分析 1.句子的情感分析找出句子表达的是正面、负面还是中性的情感。 情感分析的影响因素: 词语顺序:词语的顺序可以影响句子的整体情感。例如,“我喜欢…...
带颜色的3D点云数据发布到ros1中(通过rviz显示)python、C++
ros中发布点云数据xyz以及带颜色的点云数据xyzrgb ros中发布点云数据xyz可以直接用python来做或者C(看个人偏好) ros中发布带颜色的点云数据xyzrgb环境1.新建ROS工作空间2.创建功能包 ros中发布点云数据xyz 可以直接用python来做或者C(看个人偏好) 在这里我们带有颜色的点云数…...
python学习—列表和元组
系列文章目录 python学习—合并TXT文本文件 python学习—统计嵌套文件夹内的文件数量并建立索引表格 python学习—查找指定目录下的指定类型文件 python学习—年会不能停,游戏抽签抽奖 python学习—循环语句-控制流 python学习—合并多个Excel工作簿表格文件 文章目…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
