#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit b0=P0^0; //定义第1管位
sbit b1=P0^1; //定义第2管位
sbit b2=P0^2; //定义第3管位
sbit b3=P0^3; //定义第4管位
sbit b4=P0^4; //定义第5管位
sbit b5=P0^5; //定义第6管位
sbit b6=P0^6; //定义第7管位
sbit b7=P0^7; //定义第8管位
sbit clk=P2^0; //定义164时钟端
sbit dat=P2^1; //定义164数据端
//sbit beep=P1^7; //定时时间到提醒控制
uchar LED; //定时器缓存变量
uchar S,F,M; //时、分、秒变量
uchar aa,ab,db1,ba,bb,db2,ca,cb; //定义[时]高,[时]底,[-],[分]高,[分]低,-,[秒]高,[秒]低
void YS(uint z); //声明延时子函数
void SONG(uchar out); //声明送数子函数
void display(uchar aa,ab,db1,ba,bb,db2,ca,cb); //声明动态显示子函数
void init(); //声明初始化子函数
uchar code tab[]={ //定义字符表0-9
0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,
0x40}; //0x40为时、分、秒中的间隔号‘-’
//*************主函数*************
main()
{
init();
while(1)
{
if(LED==8) //仿真中约8次为1秒,实际当定时器中断20次即1秒钟,开始响应
{
LED=0; //将定时器缓存变量清零,以便重新进行响应计数
M++;
while(M==60) //秒到60时
{
F++; //分自加1
M=0; //秒清零
while(F==60) //分到60时
{
S++; //分自加1
F=0; //分清零
while(S==25) //时到25时
{
S=0; //时清零
}
}
}
aa=S/10; //下面6句为将时、分、秒进行分离
ab=S%10;
ba=F/10;
bb=F%10;
ca=M/10;
cb=M%10;
}
display(aa,ab,db1,ba,bb,db2,ca,cb);//传送数据
}
}
//*************延时函数*************
void YS(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//*************送数函数*************
void SONG(uchar temp) //本函数将数值分解成串型数据
{
uchar c;
for(c=0;c<8;c++)
{
clk=0; //送一时钟
dat=temp&0x80; //将变量与10000000按位与,提取最高位给数据脚
clk=1; //送一时钟
temp<<=1; //左移1位
}
}
//*************动态显示函数*************
void display(uchar aa,ab,db1,ba,bb,db2,ca,cb) //动态显示函数
{
SONG(tab[aa]); //送数据到74HC164
b0=0;YS(1);b0=1; //开位选,延时,关位选;下同
SONG(tab[ab]);
b1=0;YS(1);b1=1;
SONG(tab[db1]);
b2=0;YS(1);b2=1;
SONG(tab[ba]);
b3=0;YS(1);b3=1;
SONG(tab[bb]);
b4=0;YS(1);b4=1;
SONG(tab[db2]);
b5=0;YS(1);b5=1;
SONG(tab[ca]);
b6=0;YS(1);b6=1;
SONG(tab[cb]);
b7=0;YS(1);b7=1;
}
//*************初始化函数*************
void init() //初始化函数
{
LED=0;
S=0;
F=0;
M=0;
db1=10;
db2=10;
TMOD=0x01; //设定定时器0工作在1模式下,即16位计数器
TH0=(65536-50000)/256; //装入高8位数
TL0=(65536-50000)%256; //装入低8位数
EA=1; //开总中断
ET0=1; //开定时器中断
TR0=1; //启动定时器
}
//*************定时器中断函数*************
void timer0() interrupt 1 //中断函数(无需声明)
{
TH0=(65536-50000)/256; //重新装入高8位数
TL0=(65536-50000)%256; //重新装入低8位数
LED++; //定时时间到,变量LED自加1
}