急求一个由89C51单片机的代码!要求用4*4矩阵键盘控制LED矩阵输出0~9的数字!
再加一个流水灯控制,用4*4矩阵控制!本人是小白,不是很懂单片机的问题,所以可否将接线也写出来!代码要C语言版的,其他的我看不懂,更加不会弄,急求,各位大师显显灵,帮帮忙...
再加一个流水灯控制,用4*4矩阵控制!本人是小白,不是很懂单片机的问题,所以可否将接线也写出来!
代码要C语言版的,其他的我看不懂,更加不会弄,急求,各位大师显显灵,帮帮忙把! 展开
代码要C语言版的,其他的我看不懂,更加不会弄,急求,各位大师显显灵,帮帮忙把! 展开
3个回答
展开全部
/*
分别按下4×4键盘的按键,显示0~16键值
*/
#include<reg51.h>
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; //进入位移操作,熄灭相对应位的LED P0=1然后P0右移i位
i++;
if(i>7) i=0;
}
}
分别按下4×4键盘的按键,显示0~16键值
*/
#include<reg51.h>
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; //进入位移操作,熄灭相对应位的LED P0=1然后P0右移i位
i++;
if(i>7) i=0;
}
}
追问
大哥,接线啊!我要是能看懂就不上来问了!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
可以了吧。能推荐答案给分吗, 也是反转写的,下次自己说要C的就行
#include<reg52.h>
#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);
}
#include<reg52.h>
#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);
}
追问
大哥,给个接线图或者连线的方法啊,我不会接线!
追答
可以了不,我也初学
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
这个简单,哥当年单片机考试就考这个,满分!留下邮箱,哥发给你。有完整仿真图。
更多追问追答
追问
chen66885206@163.com
追答
已经发送,有问题请追问
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询