proteus矩阵按键计算机,矩阵键盘检测Proteus仿真电路图这里将16个按键按照4*4排列...

该按钮可以说是51单片机项目开发的重要组成部分,是51单片机IO端口输入的重要方式。我们可以通过按下按钮来控制微控制器执行相应的程序,以获得所需的效果。 51单片机的键输入主要有两种。一种是独立密钥。每个键对应一个IO端口,该端口通过循环或中断检测。当键的数量很少时,通常使用此方法。如果按键数量很大,则会为每个按键分配一个IO端口,这将占用大量资源,因此有一个矩阵键盘。矩阵键盘通过单片机扫描键盘的每一行和每一列,并通过行和列唯一地确定键的数目。下面介绍这两种方法。

1个独立按钮

Proteus仿真电路图

f8edebe7e2d76306653669aa599b0173.png

b5e21c457e51a1766f757f0c047380e7.png

图片中的按键通过P 1. 0〜P 1. 3输入,四个LED灯连接到P.0〜P 2. 3,按下不同的键,对应于不同的LED灯,步骤如下:

#include unsigned char num;

void main()

{

TMOD=0x01;

TH0 = (65536-917)/256;//1000/1.09

TL0 = (65536-917)%256;;

EA=1;

ET0=1;

TR0=1;

P1=0xff;

P2=0x00;

while(1){

if(num==20){

num=0;

switch(P1){

case ~0x01:

P2=~0x01;

break;

case ~0x02:

P2=~0x02;

break;

case ~0x04:

P2=~0x04;

break;

case ~0x08:

P2=~0x08;

break;

defult:

break;

}

}

}

}

void Timer0() interrupt 1

{

TH0 = (65536-917)/256;

TL0 = (65536-917)%256;

num++;

}

使用定时器0中断的形式,定时器0每1ms产生一次中断,num加1,并且在while循环中判断num = 20时,定时20ms,读取P1的状态,并判断P1判断的值是按下按钮并且相应的LED灯点亮。效果图如下:

e878c5ca352ae64fc169fb1df1e6976d.png

7e49faf158def9a215783f73032a8e2d.png

独立键非常简单。我认为您有比我更好的例子(例如,具有防抖功能)。今天的重点是矩阵键盘。

2个矩阵键盘检测

110a9f97f5caf609047066d2bd002b76.png

Proteus仿真电路图

12c589e100fcd904c8b086ea47a715d3.png

eddaf9ae56eebf56c4846ac0ec3443d9.png

这里,16个键按4 * 4排列,矩阵键盘的每一行都连接到P 3. 0〜P 3. 3;矩阵键盘的每一列都连接到P 3. 4〜P 3. 7。扫描原理大致如下:首先将P30设置为零,其余设置为1(P3-0xfe),然后读取P3端口的状态。如果P3!= 0xfe(此处高四位将改变,第四位保持不变),则表明已按下某个键,并且该键必须是第一行中的键。然后去判断P3端口的状态,如果按下第一个按钮(左上角),它应该是P 3. 4 = 0,刚才P 3. 0 = 0,那么P3的状态port是P3 = 0xee,依此类推,按下第一行中的第二,第三和第四按钮,分别对应于P3 = 0xde,P3 = 0xbe,P3 = 0x7e。这样,您可以确定按下了哪个按钮。如果P3 = 0xfe,则表示第一行中没有按下按钮。然后采用相同的方法,将P3 = 0xfd设置为判断第二行是否有按钮按下,然后依次将每一行设置为零(P3 = 0xfb,P3 = 0xf 7),读取列的状态,确定按下了哪个按钮,如果没有按下,则表示没有按下按钮。

C51代码:

#include void Delay10ms()//@11.0592MHz

{

unsigned char i, j;

i = 18;

j = 235;

do

{

while (--j);

} while (--i);

}

void key_scan()

{

unsigned char temp;

P3=0xfe;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xee:

P2=0x00;

break;

case 0xde:

P2=0x01;

break;

case 0xbe:

P2=0x02;

break;

case 0x7e:

P2=0x03;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

P3=0xfd;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xed:

P2=0x04;

break;

case 0xdd:

P2=0x05;

break;

case 0xbd:

P2=0x06;

break;

case 0x7d:

P2=0x07;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

P3=0xfb;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xeb:

P2=0x08;

break;

case 0xdb:

P2=0x09;

break;

case 0xbb:

P2=0x0a;

break;

case 0x7b:

P2=0x0b;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

P3=0xf7;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xe7:

P2=0x0c;

break;

case 0xd7:

P2=0x0d;

break;

case 0xb7:

P2=0x0e;

break;

case 0x77:

P2=0x0f;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

}

void main()

{

P2=0x00;

while(1)

{

key_scan();

}

}

key_scan()是键盘扫描功能,分为四个部分,每个部分的核心都是相同的,以实现矩阵键盘扫描的原理。第一段介绍如下:

fbee395cc260b921ea00f3b6c92380db.png

P3=0xfe;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xee:

P2=0x00;

break;

case 0xde:

P2=0x01;

break;

case 0xbe:

P2=0x02;

break;

case 0x7e:

P2=0x03;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

首先,P3 = 0xfe,然后将P3分配给temp,然后将temp与0xf0进行“与”运算。如果P3的高四位为0,则temp不能等于0xf0,但不能直接判断是否有按下按钮。可能会有一些干扰,并且在按下按钮的初始阶段不稳定。它不是理想的下降沿,因此需要消除抖动。实际上,要重新读取P3端口状态要延迟10毫秒。如果tmep仍不等于0xf0,则可以判断按钮被按下,然后可以将p3幅度赋予temp,然后判断temp的状态。

然后下面的程序将确定按钮是否被抬起,否则它将保留在此循环中并且无法执行其他程序:

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

以上代码是通过while循环实现的,或者可以被中断:

#include unsigned char num;

void Delay10ms()//@11.0592MHz

{

unsigned char i, j;

i = 18;

j = 235;

do

{

while (--j);

} while (--i);

}

void key_scan()

{

unsigned char temp;

P3=0xfe;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xee:

P2=0x00;

break;

case 0xde:

P2=0x01;

break;

case 0xbe:

P2=0x02;

break;

case 0x7e:

P2=0x03;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

P3=0xfd;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xed:

P2=0x04;

break;

case 0xdd:

P2=0x05;

break;

case 0xbd:

P2=0x06;

break;

case 0x7d:

P2=0x07;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

P3=0xfb;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xeb:

P2=0x08;

break;

case 0xdb:

P2=0x09;

break;

case 0xbb:

P2=0x0a;

break;

case 0x7b:

P2=0x0b;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

P3=0xf7;

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

delay10ms();

temp=P3;

temp&=0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xe7:

P2=0x0c;

break;

case 0xd7:

P2=0x0d;

break;

case 0xb7:

P2=0x0e;

break;

case 0x77:

P2=0x0f;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp&=0xf0;

}

}

}

}

void main()

{

TMOD=0x01;

TH0 = (65536-917)/256;//1000/1.09

TL0 = (65536-917)%256;;

EA=1;

ET0=1;

TR0=1;

P2=0x00;

while(1)

{

if(num==2)

{

num=0;

key_scan();

}

}

}

void Timer0() interrupt 1

{

TH0 = (65536-917)/256;

TL0 = (65536-917)%256;

num++;

}

核心内容相同,因此不再赘述。

本文来自电脑杂谈,转载请注明本文网址:

http://www.pc-fly.com/a/bofangqi/article-357440-1.html

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值