51单片机键盘程序

51单片机键盘程序,第1张

你的问题是这样的

你每次返回之前应该把相应的扫描线也置高

否则程序第二次执行的时候 就会扫描错误

f(PinA==FALSE)

PinA=TRUE;

Pin2=TRUE; ///////

return 2;}

if( INT_0 != 0 ) //再次判断是否有键按下

{

EA=0;

scan_key();

delay(50);

INT_0 =judge_hitkey();

while( INT_0 !=1); //等待按键释放

EA=1;

}

在EA=0;这句前,有无加上了,重新把 INT_0 =judge_hitkey(); 再赋回来了?,,我在郭天祥的板子上调试不行; EXITEC(93): warning C206: 'manage_key1': missing function-prototype;

这是我花两个多小时写得51单片机,矩阵键盘的显示,希望能对你有帮助;

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

sbit dula=P2^6;

sbit wela=P2^7;

void init();

void display(uchar);

uchar keyscan();

uchar temp,num; //键盘扫描

void delay(uint xms) //延时子函数

{

int i,j;

for(i=xms;i>0;i--) //延时xms毫秒

for(j=110;j>0;j--);

}

void main()

{

init();

while(1)

{

keyscan();//不断扫描键盘;

display(num);

}

}

void init()

{

num=0xff; //控制让程序开始时不出现乱码;

wela=1;

P0=0xc0; //打开数码管显示,静态显示;

wela=0;

}

uchar keyscan()

{

P3=0xfe;

temp=P3;

temp=temp&0xf0;//按位与,只能用&;

if(temp!=0xf0) //在用while语句时,一定要加上去抖动,否则程序会停不下来的哦;

{ //还是统一用if语句吧,只有在去抖动才一定要用if语句;

delay(5); //至于中括号加在那都无所谓啦;

temp=P3;

temp=temp&0xf0;

if(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xee:num=1;

break;

case 0xde:num=2;

break;

case 0xbe:num=3;

break;

case 0x7e:num=4;

break;

}

while (temp!=0xf0) //去抖动只能用while ,只有松开手才会执行下面的,才会有数码显;

{ ////一松开手,就相当于把P3口的电平改变了;所以去抖不能在switch前

temp=P3;

temp=temp&0xf0; //不能不要,只有松开手,才会退出这个循环;

}

}

}

P3=0xfd;

temp=P3;

temp=temp&0xf0;//按位与,只能用&;

if(temp!=0xf0)

{

delay(5);

if(temp!=0xf0)

{

temp=P3;

// temp=temp&0xf0; //该句子一定不能要,因为下面判断的,只是P3口的电平状态而已;

}

switch(temp)

{ case 0xed: num=5; break;

case 0xdd: num=6; break;

case 0xbd: num=7; break;

case 0x7d: num=8; break;

}

}

while (temp!=0xf0)

{

temp=P3;

temp=temp&0xf0;

}

P3=0xfb;

temp=P3;

temp=temp&0xf0;//按位与,只能用&;

if(temp!=0xf0)

{

delay(5);

if(temp!=0xf0)

{

temp=P3;

temp=temp&0xf0;

}

}

if(temp!=0xf0)

{

temp=P3;

// temp=temp&0xf0;

}

switch(temp)

{ case 0xeb: num=9; break;

case 0xdb: num=10; break;

case 0xbb: num=11; break;

case 0x7b: num=12; break;

}

while (temp!=0xf0) //去抖动只能用while ,只有松开手才会执行下面的,才会有数码显;

{ ////一松开手,就相当于把P3口的电平改变了;所以去抖不能在switch前

temp=P3;

temp=temp&0xf0; //不能不要,只有松开手,才会退出这个循环;

}

P3=0xf7;

temp=P3;

temp=temp&0xf0;//按位与,只能用&;

if(temp!=0xf0)

{

delay(5);

if(temp!=0xf0)

{

temp=P3;

temp=temp&0xf0;

}

}

if(temp!=0xf0) //该句子不能用while语句,因为如果用while语句,如果松手了,P3的电平就改变了,temp的值也会改变的。

//因此建议,非必要,还是用if语句;

{

temp=P3;

// temp=temp&0xf0;

}

switch(temp)

{ case 0xe7: num=13; break;

case 0xd7: num=14; break;

case 0xb7: num=15; break;

case 0x77: num=16; break;

}

while (temp!=0xf0) //去抖动只能用while ,只有松开手才会执行下面的,才会有数码显;

{ ////一松开手,就相当于把P3口的电平改变了;所以去抖不能在switch前

temp=P3;

temp=temp&0xf0; //不能不要,只有松开手,才会退出这个循环;

}

return num;

}

void display(uchar num)

{

P0=table[num-1];

dula=1;

dula=0;

}

下面的是郭天祥老师写的

#include<reg52h>

#define uint unsigned int

#define uchar unsigned char

sbit dula=P2^6;

sbit wela=P2^7;

sbit key1=P3^4;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,0};

uchar num,temp,num1;

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

uchar keyscan();

void display(uchar aa);

void main()

{

num=17;

dula=1;

P0=0;

dula=0;

wela=1;

P0=0xc0;

wela=0;

while(1)

{

display(keyscan());

}

}

void display(uchar aa)

{

dula=1;

P0=table[aa-1];

dula=0;

}

uchar keyscan()

{

P3=0xfe;

temp=P3;

temp=temp&0xf0;

while(temp!=0xf0)

{

delay(5);

temp=P3;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xee:num=1;

break;

case 0xde:num=2;

break;

case 0xbe:num=3;

break;

case 0x7e:num=4;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp=temp&0xf0;

}

}

}

P3=0xfd;

temp=P3;

temp=temp&0xf0;

while(temp!=0xf0)

{

delay(5);

temp=P3;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xed:num=5;

break;

case 0xdd:num=6;

break;

case 0xbd:num=7;

break;

case 0x7d:num=8;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp=temp&0xf0;

}

}

}

P3=0xfb;

temp=P3;

temp=temp&0xf0;

while(temp!=0xf0)

{

delay(5);

temp=P3;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xeb:num=9;

break;

case 0xdb:num=10;

break;

case 0xbb:num=11;

break;

case 0x7b:num=12;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp=temp&0xf0;

}

}

}

P3=0xf7;

temp=P3;

temp=temp&0xf0;

while(temp!=0xf0)

{

delay(5);

temp=P3;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P3;

switch(temp)

{

case 0xe7:num=13;

break;

case 0xd7:num=14;

break;

case 0xb7:num=15;

break;

case 0x77:num=16;

break;

}

while(temp!=0xf0)

{

temp=P3;

temp=temp&0xf0;

}

}

}

return num;

}

/ 实验目的:1掌握键盘扫描的原理以及十/十六进制的转换

2了解单片机输入和输出的过程,以及如何对数据进行采集的

实验内容:键盘上对应有16个按键,从0到F,按下相应的键会在数码管上显示相应的数字,

其中K0到K15是采用44的方式连接的

/

;

; 0 1 2 3 ---P30

; 4 5 6 7 ---P31

; 8 9 A B ---P32

; C D E F ---P33

; | | | |

; P34 P35 P36 P37

;

ORG 0000h

LJMP MAIN

ORG 0030h

MAIN:

MOV DPTR,#TAB ;将表头放入DPTR

LCALL KEY ;调用键盘扫描程序

MOVC A,@A+DPTR ;查表后将键值送入ACC

MOV P0,A ;将Acc值送入P0口

CLR P13 ;开显示

LJMP MAIN ;返回调用子程序反复循环显示

KEY: LCALL KS ;调用检测按键子程序

JNZ K1 ;有键按下继续

LCALL DELAY2 ;无键按下调用延时去抖动程序

AJMP KEY ;返回继续检测有无按键按下

K1: LCALL DELAY2

LCALL DELAY2 ;有键按下继续延时去抖动

LCALL KS ;再一次调用检测按键程序

JNZ K2 ;确认有按下进行下一步

AJMP KEY ;无键按下返回继续检测

K2: MOV R2,#0EFH ;将扫描值送入 R2暂存

MOV R4,#00H ;将第一列的列值00H送入R4暂存,R4用于存放列值。

K3: MOV P3,R2 ;将R2的值送入P3口

L6: JB P30,L1 ;P30等于1跳转到L1

MOV A,#00H ;将第一行的行值00H送入ACC

AJMP LK ;跳转到键值处理程序

L1: JB P31,L2 ;P31等于1跳转到L2

MOV A,#04H ;将第二行的行值送入ACC

AJMP LK ;跳转到键值理程序进行键值处理

L2: JB P32,L3 ;P12等于1跳转到L3

MOV A,#08H ;将第三行的行值送入ACC

AJMP LK ;跳转到键值处理程序

L3: JB P33,NEXT ;P33等于1跳转到NEXT处

MOV A,#0cH ;将第四行的行值送入ACC

LK: ADD A,R4 ;行值与列值相加后的键值送入A

PUSH ACC ;将A中的值送入堆栈暂存

K4: LCALL DELAY2 ;调用延时去抖动程序

LCALL KS ;调用按键检测程序

JNZ K4 ;按键没有松开继续返回检测

POP ACC ;将堆栈的值送入ACC

RET

NEXT:

INC R4 ;将列值加一

MOV A,R2 ;将R2的值送入A

JNB ACC7,KEY ;扫描完成跳至KEY处进行下一回合的扫描

RL A ;扫描未完成将A中的值右移一位进行下一列的扫描

MOV R2,A ;将ACC的值送入R2暂存

AJMP K3 ;跳转到K3继续

KS: MOV P3,#0FH ;将P3口高四位置0低四位值1

MOV A,P3 ;读P3口

XRL A,#0FH ;将A中的值与A中的值相异或

RET ;子程序返回

DELAY2: ;40ms延时去抖动子程序8FA2=40ms

MOV R5,#08H

L7: MOV R6,#0FAH

L8: DJNZ R6,L8

DJNZ R5,L7

RET

TAB:

DB 0C0H;0

DB 0F9H;1

DB 0A4H;2

DB 0B0H;3

DB 099H;4

DB 092H;5

DB 082H;6

DB 0F8H;7

DB 080H;8

DB 090H;9

DB 088H;A

DB 083H;b

DB 0C6H;C

DB 0A1H;d

DB 086H;E

DB 08EH;F

END

用不着数组。

只要增加一个数字vlaue,再让 key 从keyscan()函数中,得到0~9,

最后如下计算到vlaue中: vlaue = vlaue 10 + key;

以后,每得到一个按键数值(0~9),都执行一遍上面的算式,即可。

这个我知道有个类似的,

你的意思就是按1下,执行函数1;按第2下,执行函数2

你在检测按键按下的时候。设置个变量sum=0;按1次就sum++

然后就可以区分按下两次的不同了。

void keyscan()

{

if(s==0)

{

delay(5);

if(s==0)

{

while(!s);

snum++;

}

}

if(snum==1)

{

TR0=0;

ET0=0;

}

if(snum==2)

{

TR0=1;

ET0=1;

snum=0;

}

}

比如,我写的一个暂停的函数,按1下,执行一个函数1,暂停;

再按1下,执行另一函数2,开始工作。

不懂的QQ358357912说吧 ,另外你发问题不给分,这个态度是不对滴^-^

以上就是关于51单片机键盘程序全部的内容,包括:51单片机键盘程序、51单片机4*5键盘程序。、51单片机的4*4键盘程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9289784.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存