51单片机(二十九)—— 矩阵键盘输入实验

发布者:HarmoniousVibes最新更新时间:2021-07-14 来源: eefocus关键字:51单片机  矩阵键盘  输入实验 手机看文章 扫描二维码
随时随地手机看文章

一、矩阵键盘原理介绍

在之前的文章中,我们介绍过独立按键的使用,独立按键需要每个按键使用一个IO口进行读取,如果按键比较多,对IO资源的占用比较多。使用矩阵键盘,并采用扫描的方式对按键进行读取是解决按键多的一个有效办法。采用矩阵按键的方式就可以有效的节省I/O资源。4*4的矩阵键盘只需要8个I/O口进行采集。6*6的矩阵键盘只需要12个I/O口就可以采集。


本实验的硬件电路是一个4X4的矩阵键盘。矩阵键盘的原理图如下图所示。

由原理图可以看出J23的1~4与矩阵键盘的每一行相连。5~8与矩阵键盘的每一列相连。每一列上设置了上拉电阻。矩阵键盘扫描时,令J23的1~4中的一个为低电平,如果相应的行有按键按下,则J23的5~8中与这个按键对应的信号也被拉低。从而可以判断出按下的按键。


电路图中D21~D24的作用是实现中断功能。若令J23的1~4都为低电平,有按键按下时,必有一个列信号为低电平,由于二极管的作用,J24也被拉为低电平。如果将J24接在外部中断口上,就可以触发中断。


二、实验例程测试

实验1:查询扫描


在这个实验中,我们采用查询的方式对矩阵键盘进行读取,这个实验的代码的主函数如下所示。


main()

{

init_T0();

for(;;)

{

keyma=KEYscan();

keyvalue=Keychange(keyma);

if(keyvalue!=0xff)

{

for(n=0;n<7;n++)

  showdata[n]=showdata[n+1];  //显示的数据向左移位

showdata[7]=BJTY_DuanMa[keyvalue];     //读取最新的显示值

}

}

}

在主函数中,先初始化T0,T0主要是设置数码管的扫描定时器。在定时器中断中,进行数码管的扫描。之后进入for循环,在否循环中,先调用KEYscan()函数,对矩阵键盘进行扫描,返回值为IO的码值。再调用Keychange(keyma); 函数把码值转换为按键的键值,最后将按键值赋值给数码管的断码进行显示。


KEYscan()函数是对矩阵键盘进行扫描的函数,函数定义如下所示。函数返回值是8个IO口的码值。


unsigned char KEYscan(void) 

{

unsigned char key;

KEYboard=0xf0;     //低四位全部拉低

if(KEYboard!=0xf0) //表示有按键按下

{

delay1ms(10);  //去抖

if(KEYboard!=0xf0)

{           //表示有按键按下

KEYboard=0xfe; //扫描第一行将第一行拉低

if(KEYboard!=0xfe)

{

delay1ms(10); //去抖

if(KEYboard!=0xfe)

key=KEYboard;

while(KEYboard!=0xfe);   //等待按键释放

return key;

}

KEYboard=0xfd; //扫描第二行将第二行拉低

if(KEYboard!=0xfd)

{

delay1ms(10); //去抖

if(KEYboard!=0xfd)

key=KEYboard;

while(KEYboard!=0xfd);   //等待按键释放

return key;

}

KEYboard=0xfb; //扫描第三行将第三行拉低

if(KEYboard!=0xfb)

{

delay1ms(10); //去抖

if(KEYboard!=0xfb)

key=KEYboard;

while(KEYboard!=0xfb);   //等待按键释放

return key;

}

KEYboard=0xf7; //扫描第四行将第四行拉低

if(KEYboard!=0xf7)

{

delay1ms(10); //去抖

if(KEYboard!=0xf7)

key=KEYboard;

while(KEYboard!=0xf7);   //等待按键释放

return key;

}

}

}

return 0xff;

}

Keychange(keyma)函数的定义如下所示。


unsigned char Keychange(unsigned char y)

{

switch(y)

{

case 0xee:return 0;break;//0 

case 0xde:return 1;break;//1

case 0xbe:return 2;break;//2

case 0x7e:return 3;break;//3

case 0xed:return 4;break;//4

case 0xdd:return 5;break;//5

case 0xbd:return 6;break;//6

case 0x7d:return 7;break;//7

case 0xeb:return 8;break;//8

case 0xdb:return 9;break;//9

case 0xbb:return 10;break;//a

case 0x7b:return 11;break;//b

case 0xe7:return 12;break;//c

case 0xd7:return 13;break;//d

case 0xb7:return 14;break;//e

case 0x77:return 15;break;//f

default:return 0xff;break;

}

}

        烧写之后可以看到实验现象,按下矩阵键盘S1~S16中的任意一个按键,S1~S16这16个按键,分别与数值0~F相对应。按下的按键可以在数码管上显示出来。每按一次按键,数码管上的显示内容向左移一位。


 


    矩阵键盘的扫描与数码管的扫描大同小异。扫描个过程如下:


    1、令行线输出全为0;


    2、如果列线输入不全是1,则有按键按下;


    3、扫描第一行,如果列线不全是1,则第一行有按键按下,返回按键码值;


    4、扫描第二行,如果列线不全是1,则第二行有按键按下,返回按键码值;


    5、扫描第三行,如果列线不全是1,则第三行有按键按下,返回按键码值;


    6、扫描第四行,如果列线不全是1,则第四行有按键按下,返回按键码值。


实验2:中断扫描

        在这个实验中,我们采用中断方式进行矩阵键盘的读取。例程的主函数如下所示。


main()

{

init_T0();

EX0=1;         //打开外部中断0

IT0=1;         //外部中断采用边沿触发

 

for(;;)

{

KEYboard=0xf0;     //低四位全部拉低

if(flag==1)

{

flag=0;

keyma=KEYscan();

keyvalue=Keychange(keyma);

if(keyvalue!=0xff)

{

for(n=0;n<7;n++)

  showdata[n]=showdata[n+1];  //显示的数据向左移位

showdata[7]=BJTY_DuanMa[keyvalue];     //读取最新的显示值

}

}

}

}


在主函数中,使能了外部中断的通道0,采用边沿触发模式。一旦有按键按下,则会触发外部中断,在中断处理函数中,将标志位flag置1。在主函数中,判断标志位为1时,进行键盘的扫描,并在数码管上显示。具体的扫描方法及显示方法与查询扫描方式是相同的。

关键字:51单片机  矩阵键盘  输入实验 引用地址:51单片机(二十九)—— 矩阵键盘输入实验

上一篇:51单片机(三十)—— 矩阵键盘计算器
下一篇:51单片机(二十八)—— 外部中断实验

推荐阅读最新更新时间:2024-11-04 18:54

8051单片机(STC89C52)两个倒计时器同步计数
此处需要定时器0提供5ms精准定时, 则每个定时周期都需要(5*10^-3)/(1*10^-6)=5000次加1计数, 所以这里定时器0的初始值设为65536 - 5000 = 60536 = EA84H. 这里先实现两个倒计时器同时工作, 下一步该考虑怎么实现两个倒计时器不同步工作. #include STC89C5xRC.H void delay()//用定时器0实现5ms精准定时 { TMOD = 0x01; TH0 = 0xEA; TL0 = 0x84;//65536 - 5000 = 60036 TF0 = 0;//置溢出标志位为0 TR0 = 1;//开启定时器0 w
[单片机]
80<font color='red'>51单片机</font>(STC89C52)两个倒计时器同步计数
基于51单片机的多功能电子时钟设计
设计任务: 1、设计任务:利用单片机、时钟芯片 DS1302、温度传感器 DS18B20、1602 液晶 等实现日期、时间、温度的显示即一个简单的万年历。 2、设计要求 (1)通过 DS1302 能够准确的计时,时间可调并在液晶上显示出来。 (2)通过 DS18B20 能够实时、准确的检测当前环境温度。 (3)利用单片机自身功能实现闹钟 总体方案论证与设计 总体方案论证与设计 本系统以 AT89S52 单片机为控制核心,通过与 DS1302 和 DS18B20 通信获取实时时间和实时环境温度,并将得到的数据通过 1602 液晶 显示出来,同时通过相应的按键调整相应的值。因此本设计可分为一 下模块:显示模块、实时时间计算模块、实
[单片机]
基于<font color='red'>51单片机</font>的多功能电子时钟设计
MCS-51单片机与CPLD/FPGA接口逻辑设计
在功能上,单片机与大规模CPLD有很强的互补性。单片机具有性能价格比高、功能灵活、易于人机对话、良好的数据处理能力潍点;CPLD/FPGA则具有高速、高可靠以及开发便捷、规范等优点。以此两类器件相结合的电路结构在许多高性能仪器仪表和电子产品中仍将被广泛应用。本文就单片机与CPLD/FPGA的接口方式作一简单介绍,希望对从事单片机和CPLD/FPGA研发的朋友能有所启发。 单片机与CPLD/FPGA的接口方式一般有两种,即总线方式与独立方式,分别说明如下: 一、总线方式 单片机以总线方式与CPLD/FPGA进行数据与控制信息通信有许多优点。 (1)速度快。如图一所示,其通信工作时序是纯硬件行为,对于MCS-51单片机,只需一条单字节
[单片机]
51单片机串口打印不管是中文还是英文都是乱码的问题
讲道理都tm大三暑假了还搞51单片机而且关键是还遇到了一个问题解决了一天才解决出来真的是很丢人了。 不过我会珍惜这个机会的,毕竟这有可能是我辈子最后一次跟着老师搞这个破玩意了。 好了不废话了 收! 昨天遇到的问题是单片机用串口给电脑发数据,本人用串口助手查看时乱码了,发送的数据是英文和数字,没有存在中文,马上进行问题排除: 解决方案一:printf的原因吗? 代码里用piintf函数来进行串口发送数据,可能printf只适合于stm32不能适用于51,但是仔细一想又不对啊,我tm大三上的单片机大作业就是用printf函数进行串口发送数据的啊,怎么当时就可以啊。于是我把当时的代码拿过来修改,还是不行。 解决方
[单片机]
基于51单片机的TLC5615电压发生器
//本程序是基于51单片机的,可由矩阵键盘设置TLC5615 ad芯片要输出的电压值, //并由1602液晶屏显示输入的电压值. //完整代码下载: http://www.51hei.com/f/TLC56151602.rar //此程序测试成功,51hei版权所有,如果需要应用到你的项目中只需更改端口即可 #include reg51.h #include intrins.h //_nop_();延时函数用 #define uchar unsigned char #define uint unsigned int sbit CLK=P2^5; //三线控制 sbit DIN=P2^4; sbit CS=P2
[单片机]
51单片机计数器计数数码管显示
#include reg52.h #define uint unsigned int #define uchar unsigned char uchar code smg_tab ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//{0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60,0x30,0x25,0xa9,0x26,0xa1,0Xb1}; uchar code bit_tab ={0x7f,0xbf}; uchar Counts=0; uchar Display_Buffer ={0,0}; void _del
[单片机]
基于51单片机的定时器
在这里,小编带你一起 从零开始学51 单片机 定时器。基于单片机的定时器 电路 原理图如下所示:   我们学单片机是首先学的就是 LED 闪烁,那是用延时程序做的,现在回想起来,这样做不很恰当,为什么呢?我们的主程序做了灯的闪烁,就不能再干其它的事了,难道单片机只能这样工作吗?当然不是,我们能用定时器来实现灯的闪烁的功能。   例 1:查询方式   ORG 0000H   AJMP START   ORG 30H   START:   MOV P1,#0FFH ;关所 灯   MOV TMOD,#00000001B ;定时/计数器 0 工作于方式 1   MOV TH0,#15H  
[单片机]
基于<font color='red'>51单片机</font>的定时器
51单片机课程设计:基于DS18B20的温度报警器
本程序用于读取DS18B20温度,同时具备报警功能,工程分为3个文件,main.c、temp.c、temp.h,经本人修改部分代码,适用于吉林农业大学51开发板,其他朋友亦可移植到其他型号开发板。工程文件及对应开发板的电路图在文章最下方。 关于粘贴复制乱码的问题:如果程序复制到Keil编译器上出现注释乱码,可以先建一个.c文件,也就是说不在keil里面编辑,然后用记事本打开.c文件,将源码复制进去,再在keil中添加文件即可,其他操作方法一样。 1.main.c文件 /*********************************说明*****************************************
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved