详细代码讨论加我QQ:1271370903
1.设计概述:
由单片机 AT89C51芯片和动态数码显示管为核心,辅以必要的电路,构成一个数字时钟。时钟显示方式为:时-分-秒-星期。时钟计时周期为24小时,显满刻度为“23时59分59秒”。具有调整功能。设置有六个按键,三个分别对时、分、秒进行设置增减时间。外加可当秒表使用,清零-暂停-启动。
2.设计思想:
数字时钟主要由 AT89C51、显示模块、控制模块和计时运算模块四大部分组成。其中,控制模块和计时运算模块主要对时、分、秒的数值显示和调整进行操作,并且秒计算到60时,自动清零并向分进1﹔分计算到60时,自动清零并向时进1﹔时计算到24时,自动清零。这样,就形成了循环计时,显示模块主要用来显示当前计数值。AT89C51是整个设计的核心,主要用来产生定时中断,传输数据和控制各部件工作。
2.整体仿真图
如23:59:14 星期一
然后会变成周二
unsigned char code LED[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //定义共阴极LED7段显示码
unsigned char dispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义数码管位码
unsigned char hour=23,min=58,sec=52,week=1; //定义初始时间为23时58分52秒
unsigned char tcount; //定义50ms计数变量
unsigned char flag=0;
sbit KEY1=P1^0;
sbit KEY2=P1^1;
sbit KEY3=P1^2;
sbit key1=P1^3;
sbit key2=P3^6;
sbit key3=P3^7;
sbit LED1=P1^7;
sbit LED2=P1^6;
sbit LED3=P1^5;
sbit LED4=P1^4;
sbit BEEP=P3^0;
void display(unsigned char,unsigned char,unsigned char,unsigned char);
void delay(unsigned int time)//定义延时函数
{
unsigned int j = 0;
for(;time>0;time--)
for(j=0;j<125;j++);
}
void Delay100us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 100;
do
{
while (--j);
} while (--i);
}
void main(void)
{
TMOD=0x01; //定时/计数器0设为方式1
TH0=(65536-50000)/256; //定时50ms初值的高八位送入TH0
TL0=(65536-50000)%256; //定时50ms初值的低八位送入TL0
EA=1; //开CPU中断
ET0=1; //开定时/计数器0的中断
TR0=1; //启动定时器0
switch(flag)
{
case 1: LED1=0;LED2=1;LED3=1;LED4=1;
if(KEY2==0)
{
delay(180);
if(KEY2==0)
{
hour++;
if(hour>23)
hour=0;
}
}
if(KEY3==0)
{
delay(150);
if(KEY3==0)
{
hour--;
if(hour<0)
hour=23;
}
}
display(hour,min,sec,week);
break;
case 2: LED1=1;LED2=0;LED3=1;LED4=1;
if(KEY2==0)
{
delay(180);
if(KEY2==0)
{
min++;
if(min>59)
min=0;
}
}
if(KEY3==0)
{
delay(180);
if(KEY3==0)
{
min--;
if(min<0)
min=59;
}
}
display(hour,min,sec,week);
break;
case 3: LED1=1;LED2=1;LED3=0;LED4=1;
if(KEY2==0)
{
delay(180);
if(KEY2==0)
{
sec++;
if(sec>59)
sec=0;
}
}
if(KEY3==0)
{
delay(180);
if(KEY3==0)
{
sec--;
if(sec<0)
sec=59;
}
}
display(hour,min,sec,week);
break;
case 4:LED1=1;LED2=1;LED3=1;LED4=0;
if(KEY2==0)
{
delay(180);
if(KEY2==0)
{
week++;
if(week>7)
week=1;
}
}
if(KEY3==0)
{
delay(180);
if(KEY3==0)
{
week--;
if(week<1)
week=7;
}
}
display(hour,min,sec,week);
break;
case 5:LED1=1;LED2=1;LED3=1;LED4=1;flag=0;TR0=1;
default:break;
}
display(hour,min,sec,week);
}
}
void display(unsigned char hour,unsigned char min,unsigned char sec,unsigned char week)
{
P0=LED[hour/10]; //小时的十位送数码管1位显示
P2=0xfe;
delay(1);
P2=0xff;
P0=LED[hour%10]; //小时的个位送数码管2位显示
P2=0xfd;
delay(1);
P2=0xff;
P0=LED[min/10]; //横杠送数码管3位显示
P2=0xfb;
delay(1);
P2=0xff;
P0=LED[min%10]; //分的十位送数码管4位显示
P2=0xf7;
delay(1);
P2=0xff;
P0=LED[sec/10]; //分的个位送数码管5位显示
P2=0xef;
delay(1);
P2=0xff;
P0=LED[sec%10]; //横杠送数码管6位显示
P2=0xdf;
delay(1);
P2=0xff;
P0=LED[10]; //秒的十位送数码管7位显示
P2=0xbf;
delay(1);
P2=0xff;
P0=LED[week]; //秒的个位送数码管8位显示
P2=0x7f;
delay(1);
P2=0xff;
}
void T0_time() interrupt 1 //定时器中断处理函数
{
TH0=(65536-50000)/256; //重新将定时50ms初值的高八位送TH0
TL0=(65536-50000)%256; //重新将定时50ms初值的低八位送TH0
tcount++; //定时50ms时间到加1
if(tcount==20) //判断是否到1s
{
tcount=0; //到1s,变量清0
sec++; //秒计数变量加1
}
}