历史上的今天
今天是:2025年02月05日(星期三)
2021年02月05日 | 基于89C52单片机的独立按键原理图
2021-02-05 来源:eefocus
前面提到了独立按键,可见,独立按键是由矩阵键盘分离而来的。接下来看的是 4*4 的矩阵键盘,这里使用的还是上节所使用的,延时消抖检测。
先附上矩阵键盘的原理图:

在使用据矩阵键盘时,J5 排针处的跳帽连接 1 脚和 2 脚,使所有按键的有效端口全部连接至 I/O 口。
具体的扫描方式为:
先把P3^0~P3^7高四位和第四位赋不一样的电平值,当确定有键按下时,检测按下的是哪一行或哪一列(原本高电平的四位中有一位会变低电平),再将高四位和第四位赋与上一次相反的电平。再检测,即可找到所按下的按键。
实例为:把S4~S19 这16个按键,从上到下、从左至右,分别设置为1~16不同的键值,当S4按下时,数码管显示为 1;当S19按下时,数码管显示为16。
其核心代码如下(数码管段码,显示函数等变量的定义,请参照前面给出的数码管的博文):
uchar temp; //用于存储 P3 口的状态
uchar key_value = 0; //键值的定义
void matrixKeyScan()
{
P3 = 0x0f; //设置P3高四位为0,第四位为1
temp = P3; //用一个变量存储P3口的状态,以免外界影响P3口,从而造成扫描有误
if(temp != 0x0f)
{
delay10ms();
if(temp!= 0x0f) //确定有键按下
{
switch(temp) //查看P3(temp)的状态
{
case 0x0e :key_value = 1; break; //按下的为第一行
case 0x0d :key_value = 5; break;
case 0x0b :key_value = 9; break;
case 0x07 :key_value = 13;break; //按下的为第四行
}
}
P3 = 0xf0; //再将 P3 口重新赋值,高四位为1,第四位为0
temp = P3;
if(temp != 0xf0)
{
switch(temp)
{
case 0xe0 : key_value +=3 ; break; //按下的是第四列,键值key_value加3
case 0xd0 : key_value +=2 ; break;
case 0xb0 : key_value +=1 ; break;
case 0x70 : key_value +=0 ; break; //按下的是第一列,键值key_value加0
}
}
while(P3 != 0xf0); //松手检测,因为最近的一次赋值是P3 = 0xf0
}
}
void main()
{
while(1)
{
matrixKeyScan(); //在主函数中调用矩阵键盘扫描函数
if(key_value > 9) //判断键值,并显示
{
dspbuf[1] = key_value%10;
dspbuf[0] = key_value/10;
}
else
{
dspbuf[0] = key_value;
dspbuf[1] = 10; //若键值小于10,则十位不显示,只显示个位,段码数组第10个为消影
}
display(); //数码管显示函数
}
}
注:在此我们基于的是89C52单片机的按键扫描,但是对于蓝桥杯指定开发板平台(CT107D)所用的单片机为STC15F2K61S2,它与STC89C52在矩阵键盘的区别的是:前者没有P3^6和P3^7这两个 I/O 口,他们分别用P4^2,P4^4代替,具体的可以就参照STC15F2K61S2芯片手册(其他的区别大致有:它的运行速度比51单片机快,工作时可以选择是否分频;它的中断模式比51多,一些 I/O 口有其他功能等等……)。
这里有几点需要注意:
1、在编程时,主函数尽可能少的进行一些数据处理等操作,主函数主要用来调用其他的函数。
2、若使用的是STC15F2K61S2单片机,则在给 P3 口的两次赋值和高四位的电平检测阶段,需要将P4^2,P4^4单独列出来,与其余6个P3引脚的 I/O 口一起检测,并且在使用P4^2,P4^4之前,需要进行sbit位定义,以及 P4 引脚的寻址(srf P4 = 0xC0)。
3、P3口的第二次赋值,应该也囊括在第一个 if 语句之中,因为只有当确定按下之后,才会开始行与列的扫描,行、列扫描是对于一次按键的扫描,所以不可分开。
史海拾趣
|
经济部投审会6月28日晚宣布,正式核准台积电申请间接在大陆地区参股投资中芯国际集成电路制造(上海)有限公司等10家公司案,台积电可顺利取得中芯8%股权。经 济部投审会表示,台积电在2010年3月24日向政府申请间接在大陆地区参股投资中芯国际集成电 ...… 查看全部问答> |
|
如何做到usbserial与usb mass storage动态切换 请问各位大侠,有没有人做过在wince的功能usb function实现两个功能的动态切换,也就是说可以通过应用程序来切换USB转串口通讯与U盘功能。或者说是ActiveSync与usb mass storage动态切换。… 查看全部问答> |
|
说一下我的程序想实现的功能:单片机的定时器0工作在计数方式下,设置计数器的初值,使得但计数器的值达到5时产生一个计时器中断,终端服务子程序中,使P1口的灯闪烁。外部脉冲通过连接在T0的开关来实现。 #include unsigned char count; void m ...… 查看全部问答> |
|
被EnterCriticalSection保护的代码 也可以不被硬件中断打断么? 有一段语句我要连续执行,连中断都不允许打断,EnterCriticalSection可以么? 不可以的话得怎么才能实现呢? 多谢:)… 查看全部问答> |
|
情况简介: 我用245连接在AT89C52的P0口,以增加总线的驱动能力,并且实现数据的双向传输。这个控制系统用低电平有效的方式来控制外部设备,实验时用Vcc接12V的LED来指示。 注明:在245和LED之间还有74LS373来锁存数据,确保在新 ...… 查看全部问答> |
|
MCS—51系列单片机存储器包括片内ROM(或EPROM)和RAM外, 另外还有128个字节的RAM区作为特殊功能寄 存器(SFR)区。 片内、 片外程序存储器和数据存储器各自总容量为64 KB。 --------------------是总共64k,还是每个64k? ================== ...… 查看全部问答> |
|
请教一下,伺服电机电源线(驱动器到电机的电源线)大小怎么选择,有没有常用方法,比如我1KW的电机要配多少平方的线,还有,我选四芯的线,一根黑线接地,那线材带不带屏蔽还重要吗?… 查看全部问答> |
|
我现在在编写一个程序,用的是28035的MCU,在CCS3.3的开发平台,现在需要把浮点型的数据转化为字符串型的数据,我查到c语言的stdlib.h文件内有这个子程序。 gcvt 功 能:把浮点型数转换为字符串,取四舍五入 用 法:char *gcvt(double value, ...… 查看全部问答> |
|
从镍镉到镍氢再到锂电池,由于在高密度、高效能的储能介质上进展缓慢,电池的革命因此正在遭遇瓶颈——这也是为什么摩尔定律不适合考量电池技术发展的根本原因。可是,既然是个“全民痛点”,你好歹也得给人点希望不是? ...… 查看全部问答> |




