51单片机4位LED电子钟怎么编程

不用8155,键盘是2*4的,要求:能显示日期和时间,且日期和时间都可调,能复位,只有4个数码管,模块化怎么编程???

以下是6位数码管显示;供参考

#include "reg51.h"
#include "intrins.h"
#include <absacc.h>

#define unit unsigned int
#define char unsigned char
sbit deng1=P0^1;
sbit deng2=P0^2;
sbit kongzhi=P0^0;

char code dis_7[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00, 0xff };
/*共阴LED数码管段码 0 1 2 3 4 5 6 7 8 9 10 A B C D E F 灭 */
char data timedata[6]={0x00,0x00,0x00,0x00,0x00,0x00};//定义计数单元初值0,6个
unsigned long data miao;
char code weisao[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位扫描控制字
char data BUFFER[1]={0}; //定时器记数变量
char data wei=-1; //时间设置时选种位
char c=0; //闪烁次数变量
bit flag=0; //标志位
char j1,j; //计数标志
void delayxms( char t) //1*T毫秒延时
{
char i,j;
for(i=0;i<t;i++)
for(j=0;j<120;j++);
}

ledxian() //LED显示子程序
{
char k;
for(k=0;k<6;k++)
{
if(wei==-1) //当WEI为-1时正常显示
{
P1=dis_7[timedata[k]];//各位时间显示值转段码
}
else //WEI不为-1时再判断哪一位K闪
{
if(k==wei) //K=WEI时闪等扫过128次时闪
{
if(j==128)
{
//j1++;
//if(j1==1)
flag=~flag; //J到128时标志位取反
}
j++;

if(!flag)
{
P1=dis_7[16]; //灭LED灯
if(j==0)
{
if(c<15) //选种后闪烁次数
{
c++ ;
}
else //20次到了清WEI标志,清闪烁次数标志
{
wei=-1;
c=0;
ET0=1; //定时中断开
}

}
}
else
{
P1=dis_7[timedata[k]]; //FLAG=1时正常显示

}
}
else
{
P1=dis_7[timedata[k]]; //J不到128则正常显示
}
}
P2=~weisao[k]; //位扫描
delayxms(1); //1毫秒延时
P2=~0xff; //屏蔽

}
}
//////////////////主函数///////////////////
void main(void)
{
P1=0xff; //初始化端口
IT0=1; //外部中0断为跳沿触发方式
EX0=1; //外部中0允许
IT1=1; //外部中1断为跳沿触发方式
EX1=1; //外部中1允许
EA=1; //开中断
ET0=1; //允许定时器0
TMOD=0x11; //T0中断工作方式1
TH0=-5240/256; //
TL0=-5240%256;
TR0=1; //TRO为T0的运行控制位,开启中断,启动定时器
TH1=-5240/256; //
TL1=-5240%256;
ET1=1;

while(1)
{
ledxian() ; //调用LED显示子程序
}

}

void timer0(void) interrupt 1 using 1 //定时器0中断,用第1组寄存器
{
ET0=0; //关T0中断
TH0=-5240/256;//定时器初值5MS
TL0=-5240%256;
BUFFER[0]=BUFFER[0]+1;
if(BUFFER[0]==200) //1秒时间到加1
{
BUFFER[0]=0;//时间到附0
/*timedata[0]++; //秒个位加1
if(timedata[0]>=10) //秒个位到10则进秒十位
{
timedata[0]=0;timedata[1]++;
if(timedata[1]>=6) //秒十位到6则进分个位
{
timedata[1]=0;timedata[2]++;
if(timedata[2]>=10) //分个位位到10则进分十位
{
timedata[2]=0;timedata[3]++;
if(timedata[3]>=6) //分十位到6则进小时个位
{
timedata[3]=0;timedata[4]++;
if(timedata[4]>=10) //小时个位到10则进小时十位
{
timedata[4]=0;timedata[5]++;
}
if(timedata[5]==2) //当小时为24时下一个变0
{
if (timedata[4]==4)
{
timedata[4]=0;timedata[5]=0;
}
}
}
}
}
}*/

miao++;
if(miao==86400)
{
miao=0;
}
timedata[0]=miao%10;
timedata[1]=(miao%60)/10;
timedata[2]=(miao/60)%10;
timedata[3]=((miao/60)%60)/10;
timedata[4]=(miao/3600)%10;
timedata[5]=(miao/3600)/10;

}
ET0=1; //开中断
}

void timer1(void) interrupt 3
{
TR1=0;
ET1=0; //关T1中断
EX0=1;
EX1=1;
TH1=-5240/256;//定时器初值5MS
TL1=-5240%256;
ET1=1;
}

void INT00(void) interrupt 0 using 2 //外部中断0设置时间时调准位,用第2组寄存器
{

EX0 = 0; //关中断
TR1=1;
wei++; //中断一次加1
ET0=0; //定时中断关
if(wei>=6)
{
wei=-1; //当到最高位5时付初值-1
ET0=1; //定时中断开

}
j=0;
//j1=0;

/*for (k=0;k<9;k++)
{
P1=dis_7[16];//各位时间显示值转段码
//P1=0X06;
P2=~weisao[wei]; //位扫描

delayxms(300); //1毫秒延时
P1=dis_7[0];
delayxms(300);
//TR0=0;
}*/

//EX0 = 1; //开中断
}

void INT11(void) interrupt 2 using 3 //外部中断时种调准(+1),用第3组寄存器
{
EX1 = 0; //关中断
TR1=1;
switch(wei) //判断要调准的是哪一位
{
case 0 :
{
if(timedata[wei]<9) // 秒个位时加到10时返回0
{

timedata[wei]=timedata[wei]+1;
}
else
{
timedata[wei]=0;
}
}
break;
case 1 :
{
if(timedata[wei]<5) // 秒十位时加到6时返回0
{

timedata[wei]=timedata[wei]+1;
}
else
{
timedata[wei]=0;
}
}
break;
case 2:
{
if(timedata[wei]<9) // 分个位时加到10时返回0
{

timedata[wei]=timedata[wei]+1;
}
else
{
timedata[wei]=0;
}
}
break;
case 3:
{
if(timedata[wei]<5) // 分十位时加到6时返回0
{

timedata[wei]=timedata[wei]+1;
}
else
{
timedata[wei]=0;
}
}
break;
case 4:
{ // 小时个位设置
if(timedata[5]==0 || timedata[5]==1 ) //当小时十位是0或1时加到10返回到0
{
if(timedata[wei]<9)
{
timedata[wei]=timedata[wei]+1;
}
else
{
timedata[wei]=0;}
}
else //当小时十位是2时加到3返回到0
{
if(timedata[wei]<4)
{
timedata[wei]=timedata[wei]+1;
}
else
{
timedata[wei]=0;
}
}

}
break;
case 5:
{
if(timedata[wei]<2) //小时十位到3返回到0
{

timedata[wei]=timedata[wei]+1;
}
else
{
timedata[wei]=0;
}
}
break;
default: break;
//////////////////////////////////////////
}

miao=(timedata[0]+timedata[1]*10)+(timedata[2]+timedata[3]*10)*60+(timedata[4]+timedata[5]*10)*3600;

//EX1 = 1; //开中断

}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-06-21
4 位LED只能月、日和时、分轮流显示?
相似回答