STC89c52单片机c语言编程。想用4*4矩阵键盘输入一个数(包括两位数),在1602LCD上显示。急求

2024年11月20日 02:33
有3个网友回答
网友(1):

以下程序除了你所提出的要求外,多了个把按的数发送到串口的功能。
#include
#include
/*******************************************/
#define uchar unsigned char
#define uint unsigned int
/*******************************************/
#define KEYPORT P1
#define DATAPORT P2
sbit e=P3^5;
sbit rs=P3^6;
sbit rw=P3^7;
/*******************************************/
//4X4键盘
/****************4X4按键******************/
//两个延时
//delay(uint x)
void delay(uint x)
{
uint i, j;

for(i = x; i > 0; i--)
{
for (j = 110; j > 0; j--);
}
}
//delay1(uint x)
void delay1(uint x)
{
uint i, j;

for(i = x; i > 0; i--)
{
for (j = 19; j > 0; j--);
}
}
uchar getkey()
{
uchar PP1=0XFF;
uchar key=0xFF;

KEYPORT=0XF0;
PP1=KEYPORT;
key=(PP1&0XF0);
KEYPORT=0X0F;
PP1 = KEYPORT;
key=(key|(PP1&0X0F));
return key;
}
uchar GETKEY_QUDOU()
{
uchar key=0xff;
while((key=getkey())==0xff);
delay(20);
if(key==getkey())
{
while(getkey()!=0xff);
return key;
}
else
return 0xff;
}
uchar yima(uchar key)
{
uchar ktemp=key;
uchar kval=0xff;

switch (ktemp)
{
case 0xee: kval = 1; break;
case 0xed: kval = 2; break;
case 0xeb: kval = 3; break;
case 0xe7: kval = 4; break;

case 0xde: kval = 5; break;
case 0xdd: kval = 6; break;
case 0xdb: kval = 7; break;
case 0xd7: kval = 8; break;

case 0xbe: kval = 15; break;
case 0xbd: kval = 9; break;
case 0xbb: kval = 0; break;
case 0xb7: kval = 14; break;

case 0x7e: kval = 10; break;
case 0x7d: kval = 11; break;
case 0x7b: kval = 12; break;
case 0x77: kval = 13; break;

default: kval=0xff;break;
}

return kval;
}
uchar keyscan()
{
return yima(GETKEY_QUDOU());
}
uchar wkey()
{
uchar kv=0xff;
while((kv=keyscan())==0xff);
return kv;
}
/*******************************************/
//串口
void s_init()
{
SCON = 0X52;//工作方式1,11.0592M.9600 可接收
TMOD=0X20;
TH1=0XFD;
TL1=0XFD;
TR1=1;
}

/*******************************************/
//LCD1602
/**********************************************/

/**********************************************/
//写命令
void Write_Cmd(uchar com)
{
e=0;
rs=0;
rw=0;
DATAPORT=com;
delay1(10);
e=1;
delay1(25);
e=0;
}
/**********************************************/
//写数据
void Write_Data(uchar dat)
{
e=0;
rs=1;
rw=0;
DATAPORT=dat;
delay1(10);
e=1;
delay1(25);
e=0;
}
/**********************************************/
//lcd1602初始化
void lcd_init()
{
delay(15);
Write_Cmd(0x38);
delay(5);
Write_Cmd(0x38);
delay(5);
Write_Cmd(0x38);
Write_Cmd(0x38);
Write_Cmd(0x01);
Write_Cmd(0x0f);
Write_Cmd(0x06);

//Write_Cmd(0x80+0x042);//写入显示缓冲区起始地址为1行2列
}
void lcd_play(uchar kv)
{
static uchar i=3;

i++;
if(i>=10)
{ i=4;
Write_Cmd(0x01);
}
Write_Cmd(0x80+0x40+i);
Write_Data(kv);
}
/*************************主程序****************************************/
void main()
{
uchar kv=0xff;
s_init();
lcd_init();
printf(" WELCOM TO USE: \n");
while(1)
{
kv=wkey();
if(kv<10)
kv=0x30+kv;
else
kv=kv-10+'A';
printf("CURRENT KEY : %c\n",kv);
lcd_play(kv);
}
}

网友(2):

设定一个标志位,确定你输的每二次是接着弟一个数的,我这是一个程序中的一部分,你看看吧
if(flag1)
{
switch(flag)
{
case 0:
flag = 1;
one = key_val;
command(0x80);
data(tab[key_val]);
k1 = (float)one;
break;
case 1:
flag = 2;
two = key_val;
command(0x80+1);
data(tab[key_val]);
k1 = (float)(one*10 + two);
break;
我之前也是遇到这个问题不懂,后来花钱学的,就这么点东西用了我20元钱钱

网友(3):

可以程序不太复杂就是有点巧妙的东西,自己努力点吧