急求一个由89C51单片机的代码!要求用4*4矩阵键盘控制LED矩阵输出0~9的数字!

2024-12-25 06:49:56
推荐回答(3个)
回答1:

/*
分别按下4×4键盘的按键,显示0~16键值

*/
#include
sbit speaker=P3^7;
/////////////////键盘
sbit v1=P2^0;
sbit v2=P2^1;
sbit v3=P2^2;
sbit v4=P2^3;

sbit h1=P2^4;
sbit h2=P2^5;
sbit h3=P2^6;
sbit h4=P2^7;

/////////////////显示
sbit shu1=P1^3;/*第1位数码管共阴端*/
sbit shu2=P1^2;/*第2位数码管共阴端*/
sbit shu3=P1^1;/*第3位数码管共阴端*/
sbit shu4=P1^0;/*第4位数码管共阴端*/

////////////////
void delayms(unsigned int i);

unsigned char yima[]={0xeb,0x88,0xb3,0xba,0xd8,0x7a,0x7b,0xa8,0xfb,0xfa};/*译码表,此表数据和硬件相关*/
unsigned int b=0;/*要显示的数据*/
unsigned int b_count=0;/*扫描次数*/

void delayms(unsigned int i);
unsigned int keyboar();

unsigned int b;

void t0()interrupt 1 using 1 /*中断程序负责显示b的值 */
{
unsigned char a1=0,a2=0,a3=0,a4=0;

static int k=0;
/*数码管扫描显示*/
a1=b/1000;/*取b的千位*/
a2=b%1000/100;/*取b的百位*/
a3=b%100/10;/*取b的十位*/
a4=b%10;/*取b的个位*/
if(k==0){shu4=1;shu1=0;shu2=0;shu3=0;P0=yima[a1];}
else if(k==1){shu4=0;shu1=1;shu2=0;shu3=0;P0=yima[a4];}
else if(k==2){shu4=0;shu1=0;shu2=1;shu3=0;P0=yima[a3];}
else if(k==3){shu4=0;shu1=0;shu2=0;shu3=1;P0=yima[a2];}
k++;
if(k>3)k=0;

TH0=240;
}

main()
{

EA=1;/*开全局中断 */
TR0=1;/*定时器0开始计数 */
ET0=1;/*定时器0开中断 */
TMOD=0X01;/*定时器0工作在方式1:16位计数模式 */

while(1)
{
b= keyboar(); /*把按键的代表的值给b */
}

}

void delayms(unsigned int i)
{
unsigned int j;
for(;i>0;i--)
for(j=100;j>0;j--);
}
//////////////////////////////////////////////////////////////////////////////////
//扫描法:逐行扫描查询 一般用在按键比较少的场合
int keyscan()
{
unsigned char k k_temp;
P1=0xf0; //低位置0,准备查询按键
k=P1; //取得当前P1口状态
if(k!=0xf0) //如果有变化则表示有按键按下
{
delay(10); //延迟 消抖
k_temp=p1;
if(k==k_temp) //确实有键按下
{
k=0xfe;
do //循环扫描每一行
{
p1=k;
if(k!=p1)
{
switch(P1) //判断按键 并返回键值
{
//第1行
case 0x7e:{return 0; break;}
case 0xbe:{return 1; break;}
case 0xde:{return 2; break;}
case 0xee:{return 3; break;}
//第2行
case 0x7d:{return 4; break;}
case 0xbd:{return 5; break;}
case 0xdd:{return 6; break;}
case 0xed:{return 7; break;}
//第3行
case 0x7b:{return 8; break;}
case 0xbb:{return 9; break;}
case 0xdb:{return 10;break;}
case 0xeb:{return 11;break;}
//第4行
case 0x77:{return 12;break;}
case 0xb7:{return 13;break;}
case 0xd7:{return 14;break;}
case 0xe7:{return 15;break;}
}
}
k=_crol_(k,1); //移位 进入下一行扫描
}
while(k!=0xef); //超过列范围 退出扫描
}
}
}
////////////////////////////////////////////////////////////////////////////////
//线反转法 :只需2步便可获得按键位置,最常用
unsigned int keyboar()/*线反转法 */
{
static unsigned int a=0;
unsigned char a1=0,b1=0;
/*行线为输入线,列线为输出线 */
v1=v2=v3=v4=0;
h1=h2=h3=h4=1;
if(P2<0xf0)/*检查行是否有按键按下 */
{
delayms(10);
if(P2<0xf0)
{
/*行线为输入线,列线为输出线 */
v1=v2=v3=v4=0;
h1=h2=h3=h4=1;
a1=P2;
/*行线为输出线,列线为输入线 */
h1=h2=h3=h4=0;
v1=v2=v3=v4=1;
b1=P2;

a=a1|b1;
}
}
if (a==0xe7) { return 7; }
else if(a==0xeb) { return 8; }
else if(a==0xed) { return 9; }
else if(a==0xee) { return 13;}

else if(a==0xd7) {return 4; }
else if(a==0xdb) {return 5; }
else if(a==0xdd) {return 6; }
else if(a==0xde) {return 12;}

else if(a==0xb7) {return 1; }
else if(a==0xbb) {return 2; }
else if(a==0xbd) {return 3; }
else if(a==0xbe) {return 11;}

else if(a==0x77) {return 0; }
else if(a==0x7b) {return 15;}
else if(a==0x7d) {return 16;}
else if(a==0x7e) {return 10;}

else return 17;
}

/*******************************************
流水灯写法1
while(1)
{
a=0x01; //赋初值00000001
for(i=0;i<8;i++) //循环8次
{
P0=a;
delay(500);
a=a<<1; //左移1位
}
}

流水灯写法2:
a=0x01; //赋初值00000001
while(1)
{
P0=a; //先点亮第1个led
delay(500);
a=_crol_(a,1); //将a循环左移1位后再赋给a
}

流水灯写法3:
while(1)
{
a=0x01; //赋初值00000001
for(i=0;i<7;i++)
{
P0=a;
delay(500);
a=a<<1; //左移
}
for(i=0;i<7;i++)
{
P0=a;
delay(500);
a=a>>1; //右移
}
}

写法3:
void t0() interrupt 1 //中断服务函数
{
TH0=(65536-50000)/256; //计数寄存器高8位重新载入
TL0=(65536-50000)%256; //计数寄存器低8位重新载入
num++;
if(num>=10) //500ms 调整流水速度
{
num=0;
P0=1< i++;
if(i>7) i=0;
}
}

回答2:

可以了吧。能推荐答案给分吗, 也是反转写的,下次自己说要C的就行
#include
#define uchar unsigned char
#define uint unsigned int
void delay(uint k);
void display();
void keyscan();
uchar array[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar shuju[17]={0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,0xbe,0xbd,0xbb,0xb7,0x7e,0x7d,0x7b,0x77,0xff};
uchar z,x,a,b,c;
main()
{
while (1)
{
P2=0X00;
keyscan();
display();
}
}
void keyscan()
{
P1=0xf0;
a=P1;
P1=0x0f;
b=P1;
c=a|b;
for(x=0;c!=shuju[x];x++)
{
}
if(x==16)
{
x=0;
}
if(x!=0)
{
z=x;
}
}
void display()
{
P2=array[z];
delay(10);
}
void Delay(uint k)
{
while(--k);
}

回答3:

这个简单,哥当年单片机考试就考这个,满分!留下邮箱,哥发给你。有完整仿真图。