#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define D P0 //段选
#define W P2 //位选
sbit IO=P3^3; //数据口
sbit SCLK=P3^4; //控制数据时钟 1
sbit RST=P3^2; //使能端、复位端 2
/************按键引脚定义***********/
sbit s1=P3^5; //按键 加
sbit s2=P3^6; //按键 减
sbit s3=P3^7; //按键 选择
sbit led=P2^3; //闪烁的小数点
uchar s, knum=0,snum,fnum;
bit flag;
/***********写时分秒地址************/
#define write_shi 0x84
#define write_fen 0x82
#define write_miao 0x80
/***********读时分秒地址************/
#define read_shi 0x85
#define read_fen 0x83
#define read_miao 0x81
bit miao_flag;
char miao_num;
char Dmiao;
char shi,fen,miao; //读出数据存储变量
uchar d[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //段选
/***********延时函数************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/***********中断函数************/
void t0_init()
{
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
/***********1302读数据函数************/
uchar read_1302(uchar add)
{
uchar i,date;
RST=0; //禁止读写数据
for(i=0;i<8;i++)
{
RST=0;
SCLK=1;
IO=add&0x01;
add>>=1;
SCLK=0;
}
for(i=0;i<8;i++)
{
if(IO)
date=date|0x80;
else
date=date|0x00;
SCLK=1;
date>>=1;
SCLK=0;
}
RST=0;
date=date/16*10+date%16;//进制转换 16转10进制
IO=0; //数据读完后,IO口必须为0,不然小时一直显示85 第五处修改
return date;
}
/***********1302写数据函数************/
void write_1302(uchar add,uchar dat)
{
uchar i;
RST=1; //禁止读写数据
SCLK=0;
for(i=0;i<8;i++) //写地址
{
RST=0; //允许读写数据 3
SCLK=0;
IO=add&0x01;
add>>=1;
SCLK=1;
}
for(i=0;i<8;i++) //写数据
{
RST=1; //允许读写数据
SCLK=0;
IO=dat&0x01;
dat>>=1;
SCLK=1;
}
RST=0;
}
/***********1302初始化函数************/
void init_1302()
{
flag=read_1302(0x81);
if(flag&0x80)
write_1302(0x8e,0x80); //保护取消,可以进行读写操作
write_1302(write_miao,0x56);
write_1302(write_fen,0x49); //
write_1302(write_shi,0x14); //
write_1302(0x90,0xa5);
write_1302(0x8e,0x00); //保护启动,不能进行读写操作
}
/***********数码管显示函数************/
void display(uchar shi,uchar fen)
{
if(knum==0)
{
snum=30;
fnum=30;
}
if(knum==1)
{
fnum++;
snum=30;
}
if(knum==2)
{
snum++;
fnum=30;
}
if(snum>=30)
{
W=0x7F; //位选
s=d[shi/10]; //段码先给s,判断其值是否为0?
if(s==0xa0) //段码
{
W=0xff;
D=0x00;
}
D=s; //s不为零则给D,让其显示
delay(50); //延时
D=0Xff; //消隐
if(miao_flag) //小数点闪烁
{
miao_flag=0;
W=0xBF;
D=d[shi%10];
delay(50);
D=0Xff; //消隐
W=0X00;
}
else
{
W=0xBF;
D=d[shi%10];
delay(50);
D=0Xff;
W=0X00;
}
if(snum==60)
snum=0;
}
if(fnum>=30)
{
W=0xDF;
D=d[fen/10];
delay(50);
D=0Xff;
W=0X00; //消隐
W=0xEF;
D=d[fen%10];
delay(50);
D=0Xff;
W=0X00; //消隐
if(fnum==60)
fnum=0;
D=0Xff;
W=0X00;
}
}
void read_sf()
{
miao=read_1302(read_miao);
if(miao!=Dmiao)
{
Dmiao=miao;
TR0=1;
miao_flag=1;
}
fen=read_1302(read_fen);
shi=read_1302(read_shi);
display(shi,fen);
}
/***********按键扫描函数************/
void keyscan()
{
if(s3==1) //选择按键按下
{
delay(10);
if(s3==1)
{
while(!s3)
display(shi,fen); //加上这句,按键按下就不会闪
knum++;
if(knum==1) //分闪烁
{
write_1302(0x8e,0x00); //保护取消
write_1302(write_miao,0x80);
}
if(knum==3) //时钟启动
{
knum=0;
write_1302(write_miao,0x00);
write_1302(0x8e,0x80); //保护启动
}
}
}
if(knum==1) //分钟调节
{
if(s1==0) //加
{
delay(10);
if(s1==0)
{
while(!s1)
display(shi,fen); //加上这句,按键按下就不会闪
fen++;
if(fen==60)
fen=0;
write_1302(write_fen,fen/10*16+fen%10); //写入1302
read_sf(); //读出时间,然后显示
}
}
if(s2==0)
{
delay(10);
if(s2==0)
{
while(!s2)
display(shi,fen); //加上这句,按键按下就不会闪
fen--;
if(fen==-1)
fen=59;
write_1302(write_fen,fen/10*16+fen%10);
read_sf();
}
}
}
if(knum==2)
{
if(s1==0)
{
delay(10);
if(s1==0)
{
while(!s1)
display(shi,fen); //加上这句,按键按下就不会闪
shi++;
if(shi==24)
shi=0;
write_1302(write_shi,shi/10*16+shi%10);
read_sf();
}
}
if(s2==0)
{
delay(10);
if(s2==0)
{
while(!s2)
display(shi,fen); //加上这句,按键按下就不会闪
shi--;
if(shi==-1)
shi=23;
write_1302(write_shi,shi/10*16+shi%10);
read_sf();
}
}
}
}
/***********主函数************/
void main()
{
init_1302();
t0_init();
while(1)
{
if(miao_num<10)
led=0;
if(miao_num>=10)
led=1;
read_sf();
keyscan();
}
}
/***********中断************/
void t0_
timer() interrupt 1
{
TMOD=0X10;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
miao_num++;
if(miao_num>=25)
{
miao_num=0;
miao_flag=1;
}
}
一周热门 更多>