数码管设计时钟表(C语言)
-05-3000:45
声明:
实钟程序刚写成,通过实验板验证.正确无误.但还程序还没最优化.希望有高手看到提宝贵意见,本人感激不尽.
;采用AT51的8位电子钟原理如下图所示,只要硬件连接无误,保证成功。另外图中的SET按纽用于校准时间。按住1秒以上进入校准时间状态及换档和退出,快速点触用于调节时间数值。三极管采用9015即可。数码管最好采用红色的共阳型LED数码管,亮度高些,因为是扫描的显示方式,所以各个数码管的abcdefg各脚采用了总线并联,改动510欧姆的电阻可以改变显示亮度。
;电子钟原理图
;电子钟实物图
;电子钟源程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;AT2051时钟程序;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;定时器T0、T1溢出周期为50MS,T0为秒计数用,T1为调整时闪烁用,
;P3.7为调整按钮,P1口为字符输出口,采用共阳显示管。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
/*====电子时钟设计===============
程序功能:实现时钟能,一键调节时间功能.
作者:w418781840,日期:.5.29*/
//==============================
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineSEGP0//定义数码管接P0口
/*声明T0相关声明*/
#definecount_M150000//计数0.05S
ucharcount_T0=0;//中断次数
/*声明7段LED数码管驱动信号数组(共阳)*/
ucharTAB[]={0xc0,0xf9,0xa4,0xb0,0x99,//0-4
0x92,0x83,0xf8,0x80,0x98};//5-9
/*声明显示区数组初始显示12-00-00*/
uchardisp[]={0xf9,0xa4,0xbf,0xc0,
0xc0,0xbf,0xc0,0xc0};
/*声明基本变量*/
sbitkey=P3^2;//声明key接P3.2
ucharseconds,minutes,hours;//秒,分,时
ucharbiaozhi,shibiao,flag;//定义标志位
/*声明子函数*/
voidinit(void);//声明初始化函数
voiddelay1ms(uchar);//声明延时函数
voidshan_shuo(void);//声明闪数码管闪烁函数
voidscan(void);//声明时间调整函数
voidscanner(uchar);//声明显示函数
/********************主函数******************************/
main()
{init();//调用初始化函数
while(1)//程序一直运行
{scanner(1);//调用显示函数
if(key==0)//键按下?
{scanner(1);//是,调用8MS显示函数消抖
scan();//调用时间调整函数
}
}
}
/*************初始化函数*********************/
voidinit(void)
{EA=1;
ET0=1;
TMOD=0x01;
TH0=(65536-count_M1)/256;
TL0=(65536-count_M1)%256;
TR0=1;
key=1;
hours=12;
minutes=0;
seconds=0;
biaozhi=0;//闪烁标志
shibiao=0;//时闪烁标志
flag=0;//加1与闪烁切掉标志
}
/***************时间调整函数*******************/
voidscan(void)
{flag=1;//闪烁标志l置1
count_T0=0;//开始闪烁计数
while(key==0)//按键释放否?
scanner(1);//否.调用显示函数,防待显示中止.
scanner(1);//是,调用8ms显示延时消抖
while(1)//一直运行
{while(key==1)//键按下否?
scanner(1);//否
scanner(125);//是,调用显示延时,125*8MS=1S
if(key==1)//仍按下.则时间小于1S加1分钟
{minutes++;//分加1
if(minutes==60)
minutes=0;
}
elsebreak;//按下时间大于1S,跳出分调整.
}
/*按下时间大于1秒转调小时状态*/
while(key==0)//键释放否?
scanner(1);//否.
scanner(1);//是.
shibiao=1;//小时调整标志置1
while(1)
{while(key==1)//等待键按下
scanner(1);
scanner(125);//有键按下延时1秒
if(key==1)//仍按下,则按下时间小于1秒
{hours++;//时加1
if(hours==24)
hours=0;
}
elsebreak;//按下时间大于1S,跳出时调整.
}
while(key==0)//调时退出程序。等待键释放
scanner(1);//否
scanner(1);//是,延时消抖
flag=0;//清切换标志.
shibiao=0;//清闪烁标志位.
biaozhi=0;//清时闪烁标志位.
}//结束返回.
/********T0中断服务,用于加1和闪烁之间切换**********/
voidtimer0(void)interrupt1
{TH0=(65536-count_M1)/256;
TL0=(65536-count_M1)%256;
if(flag==0)//标志为0,不切换到闪烁
{if(++count_T0==20)//计数20*50MS=1S
{count_T0=0;//1S到计数归0
seconds++;//秒加1
if(seconds==60)
{seconds=0;//秒60到,秒归0
minutes++;//分加1
}
if(minutes==60)//分60到
{minutes=0;
hours++;//时加1
}
if(hours==24)//时24到
hours=0;//归0
}
disp[0]=TAB[hours/10];//分离时十位
disp[1]=TAB[hours%10];//分离时个位
disp[3]=TAB[minutes/10];//分离分十位
disp[4]=TAB[minutes%10];//分离分个位
disp[6]=TAB[seconds/10];
disp[7]=TAB[seconds%10];
}
else//标志为1,执行闪烁功能
{if(++count_T0==6)//计数6*50=0.3S
{count_T0=0;
shan_shuo();//0.3S到调用闪烁函数
}
}
}
/***************显示函数***************/
voidscanner(ucharx)
{unsignedchari,j,scan;
for(j=0;j
{scan=0xfe;
for(i=0;i<8;i++)//扫描8次
{SEG=0xff;//防闪烁
P2=scan;//送位选通
SEG=disp[i];//送段码
delay1ms(1);//延时
scan=(scan<<1)|0x01;//指向下一个.
}
}
}
/*****************闪烁函数***************/
voidshan_shuo(void)
{biaozhi=~biaozhi;//0.3S到,闪烁标志取反
if(biaozhi==0)//闪烁标志为0,闪烁
{if(shibiao==1)//时标志为1,时闪烁
{disp[0]=0xff;//时十位熄灭
disp[1]=0xff;//时十位熄灭
}
else//时标志为0,分闪烁.
{disp[3]=0xff;
disp[4]=0xff;
}
}
else//闪烁标志为1,正常显示
{disp[0]=TAB[hours/10];
disp[1]=TAB[hours%10];
disp[3]=TAB[minutes/10];
disp[4]=TAB[minutes%10];
}
}/***************延时函数,显示调用***************/
voiddelay1ms(ucharx)
{uchari,j;
for(i=0;i
for(j=0;j<120;j++);
}
/*************************************************/