#include <reg52.h> #define uchar unsigned char #define uint unsigned int #define D P2 //段选 #define W P0 //位选 sbit IO=P1^1; //数据口 sbit SCLK=P1^2; //控制数据时钟 sbit RST=P1^0; //使能端、复位端 /************按键引脚定义***********/ sbit s1=P1^5; //按键 加 sbit s2=P1^3; //按键 减 sbit s3=P1^4; //按键 选择 sbit led=P1^7; //闪烁的小数点 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[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //不带小数点 uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带小数点 void delay(uint z) //延时函数,z的取值为这个函数的延时ms数,如 delay(200);大约延时200ms. { //delay(500);大约延时500ms. uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void t0_init() //定时50ms一个中断 { TMOD=0X01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; } uchar read_1302(uchar add) //读函数 { uchar i,date; RST=0; //禁止读写数据 for(i=0;i<8;i++) { RST=1; SCLK=0; IO=add&0x01; add>>=1; SCLK=1; } 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; } void write_1302(uchar add,uchar dat) //写函数 { uchar i; RST=0; //禁止读写数据 SCLK=0; for(i=0;i<8;i++) //写地址 { RST=1; //允许读写数据 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; } void init_1302() //初始化函数 设置时间 { flag=read_1302(0x81); if(flag&0x80) write_1302(0x8e,0x00); //保护取消,可以进行读写操作 write_1302(write_miao,0x56); write_1302(write_fen,0x49); write_1302(write_shi,0x14); write_1302(0x90,0xa5); write_1302(0x8e,0x80); //保护启动,不能进行读写操作 } 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=0xF7; //位选 s=d[shi/10];//段码先给s,判断其值是否为0, if(s==0xc0) { W=0xff; D=0xff; } D=s;//s不为零则给D,让其显示 delay(5); D=0Xff; //消隐 if(miao_flag) //小数点闪烁 { miao_flag=0; W=0xFb; D=dd[shi%10]; delay(5); D=0Xff; //消隐 } else { W=0xFb; D=d[shi%10]; delay(5); D=0Xff; } if(snum==60) snum=0; } if(fnum>=30) { W=0xFd; D=d[fen/10]; delay(5); D=0Xff; //消隐 W=0xFe; D=d[fen%10]; delay(5); D=0Xff; //消隐 if(fnum==60) fnum=0; } } 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==0) //选择按键按下 { delay(10); if(s3==0) { 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=0X01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; miao_num++; if(miao_num>=20) { miao_num=0; miao_flag=1; } } |