当前位置: 首页 > news >正文

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博客》

六,效果

http://www.lryc.cn/news/378767.html

相关文章:

  • 解决双击bootstrap.bat没有生成b2.exe文件
  • AI穿戴设备是未来手机的终结者?中国AI商业化的未来预测
  • FPGA+Nvidia Orin NX+AI 异构视频图像处理开发平台在高端医疗和工业检测的应用,支持定制,支持国产化
  • 2000-2023年各省名义GDP、实际GDP、GDP平减指数数据(含原始数据+计算过程+计算结果)(以2000年为基期)
  • python学习—字典(Dictionary)
  • 鸿蒙开发:【组件启动规则(FA模型)】
  • 网络编程5----初识http
  • “用友审批+民生付款”,YonSuite让企业发薪更准时
  • EtherCAT扫盲,都是知识点
  • 开发中遇到的错误 - @SpringBootTest 注解爆红
  • 数据仓库的实际应用示例-广告投放平台为例
  • Beyond VL了解学习
  • AI音乐革命:创意产业的新篇章
  • python从入门到精通1:注释
  • CountDownLatch(应对并发问题的工具类)
  • HarmonyOS开发知识 :扩展修饰器,实现节流、防抖、权限申请
  • 自然语言NLP的基础处理
  • 带颜色的3D点云数据发布到ros1中(通过rviz显示)python、C++
  • python学习—列表和元组
  • c++题目_水仙花数
  • 使用 Iceberg、Tabular 和 MinIO 构建现代数据架构
  • jnp.linalg.norm
  • 20240621在飞凌的OK3588-C开发板的Buildroot系统中集成i2ctool工具
  • ARM32开发--存储器介绍
  • Web服务器
  • 大语言模型-Transformer
  • POI:接收上传上来的excel,解析并导入到数据库
  • 网页的CSS和JavaScript文件没有自动更新, 解决办法
  • Go语言 获取服务器资源磁盘Disk情况
  • 使用上海云盾 CDN 和 CloudFlare 后 Nginx、 WordPress、 Typecho 获取访客真实 IP 方法