#include <reg51.h>
sbit ksec=P3^1;//调节秒
sbit kmin=P3^0; //调节分钟
sbit khour=P3^2;//调节小时
sbit reset=P3^3;//清零
char smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0~F的十六进制
int ssec,sec,min,hour;
char DisplayData[8];//储存段选数据
void delay(int i)//延时函数
{
while(i--);
}
void Timer0Init()//定时器
{
TMOD=0X01;//0模式,工作方式1,仅用TR0打开启动。
TH0=0Xd8; //给定时器赋初值,定时10ms
TL0=0Xf0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
void wei()//位选
{
int i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):P1=0xfe; break;//显示第0位
case(1):P1=0xfd; break;//显示第1位
case(2):P1=0xfb; break;//显示第2位
case(3):P1=0xf7; break;//显示第3位
case(4):P1=0xef; break;//显示第4位
case(5):P1=0xdf; break;//显示第5位
case(6):P1=0xbf; break;//显示第6位
case(7):P1=0X7F; break;//显示第7位
}
P0=DisplayData[i];//发送段码
delay(100); //间隔一段时间扫描
P0=0x00;//消隐
}
}
void duan()//段选
{
DisplayData[0]=smgduan[sec%10];
DisplayData[1]=smgduan[sec/10];
DisplayData[2]=0x40;
DisplayData[3]=smgduan[min%10];
DisplayData[4]=smgduan[min/10];
DisplayData[5]=0x40;
DisplayData[6]=smgduan[hour%10];
DisplayData[7]=smgduan[hour/10];
}
void settime()//调节时间
{
if(ksec==0)
{
delay(100);
if(ksec==0)
{
sec++;
if(sec>=60)//超过60重新置数
{
sec=0;
}
}
}while(!ksec);//防抖
if(kmin==0)
{
delay(100);
if(kmin==0)
{
min++;
sec=0;
if(min>=60)
{
min=0;
}
}
}while(!kmin);
if(khour==0)
{
delay(100);
if(khour==0)
{
hour++;
sec=0;
if(hour>=24)
{
hour=0;
}
}while(!khour);
}
if(reset==0)
{
delay(100);
if(reset==0)
{
sec=0,min=0,hour=0,ssec=0;
}
}while(!reset);
}
void main()//主函数
{
Timer0Init(); //定时器0初始化
while(1)
{
duan();
settime();
wei();
}
}
void Timer0() interrupt 1 //定时器中断
{
TH0=0Xd8; //定时器赋初值,定时10ms
TL0=0Xf0;
ssec++;
if(ssec>=100) //1s
{
ssec=0;
sec++;
if(sec>=60)
{
sec=0;
min++;
if(min>=60)
{
min=0;
hour++;
if(hour>=24)
{
hour=0;
}
}
}
}
}
电路图如下
portues仿真无误。