仿真 实物都通过.stc89c52 11.0592MHz晶振 ;具体电路见仿真图;仿真用5位数码管显示88-88的样式
一个按键调节时间:
1.长按key1,进入调时状态,小时十位开始闪烁,此时再短按key1,小时十位加加,
小时十位在0-2之间变化;(key1可以是按钮,也可以用触摸开关)
2.调好后,过5秒自动跳到小时个位闪烁,此时再短按key1,小时个位加加,如果十位是0、1,
小时个位再0-9之间变化;如果十位是2,小时个位在0-3之间变化;
3.小时个位调好后,过5秒,分钟十位开始闪烁,此时再短按key1,分钟十位加加,分钟十位在0-5
之间变化;
4.分钟十位调好后,过5秒,分钟个位开始闪烁,此时再短按key1,分钟个位加加,分钟个位在0-9
之间变化;
5.分钟个位调好后,过5秒,退出调时状态,时钟正常走时。
在非调时状态,短按key1,开关LED灯;
小时 、分钟的个位、十位分开调节,这样比常规的个位、十位在一起调时快;
单片机源程序如下:
- /*********************************************************************************
- 仿真 实物都通过.stc89c52 11.0592MHz晶振 ;具体电路见仿真图;仿真用5位数码管显示88-88的样式
- 一个按键调节时间:
- 1.长按key1,进入调时状态,小时十位开始闪烁,此时再短按key1,小时十位加加,
- 小时十位在0-2之间变化;(key1可以是按钮,也可以用触摸开关)
- 2.调好后,过5秒自动跳到小时个位闪烁,此时再短按key1,小时个位加加,如果十位是0、1,
- 小时个位再0-9之间变化;如果十位是2,小时个位在0-3之间变化;
- 3.小时个位调好后,过5秒,分钟十位开始闪烁,此时再短按key1,分钟十位加加,分钟十位在0-5
- 之间变化;
- 4.分钟十位调好后,过5秒,分钟个位开始闪烁,此时再短按key1,分钟个位加加,分钟个位在0-9
- 之间变化;
- 5.分钟个位调好后,过5秒,退出调时状态,时钟正常走时。
- 在非调时状态,短按key1,开关LED灯;
- 小时 、分钟的个位、十位分开调节,这样比常规的个位、十位在一起调时快;
- **********************************************************************************/
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit sclk = P1^0;
- sbit dio = P1^1;
- sbit ce = P1^2;
- sbit wela = P2^7;
- sbit dula = P2^6;
- sbit led = P1^7;
- sbit key1=P3^0; //按键 多功能
- uchar knum=0,ssnum,fsnum,sgnum,fgnum; //调时 位 闪烁变量
- uchar shi,fen,miao;
- uchar ss; //秒点闪烁变量
- bit zdyw; //自动移位标志
- uchar count;//自动移位时间计数变量
- /***********写时分秒地址************/
- #define write_shi 0x84
- #define write_fen 0x82
- #define write_miao 0x80
- #define write_ram 0xc0
- /***********读时分秒地址************/
- #define read_shi 0x85
- #define read_fen 0x83
- #define read_miao 0x81
- #define read_ram 0xc1
- // 0 1 2 3 4 5 6 7 8 9
- uchar code d[]={ 0x3F,0x06,0x5B,0x4F,0x66, 0x6D,0x7D,0x07,0x7F,0x6F}; //共阴不带小数点
- uchar code dd[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};// 共阴带小数点
- //uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //共阳带小数点
- //uchar d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //共阳不带小数点
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=120;y>0;y--);
- }
- void t0_init() //定时50ms中断
- {
-
- TMOD=0X01;
- TH0=(65536-46080)/256;
- TL0=(65536-46080)%256;
- EA=1;
- ET0=1;
- TR0=1;
- ET1=1;
- }
- void display(uchar shi,uchar fen) //显示函数
- {
- if(knum==0)
- {
- ssnum=30;
- fsnum=30;
- sgnum=30;
- fgnum=30;
- }
-
- if(knum==3)
- {
- fsnum++;
- ssnum=30;
- fgnum=30;
- sgnum=30;
- }
-
- if(knum==4)
- {
- fgnum++;
- ssnum=30;
- fsnum=30;
- sgnum=30;
- }
- if(knum==1)
- {
- ssnum++;
- sgnum=30;
- fgnum=30;
- fsnum=30;
- }
-
- if(knum==2)
- {
- sgnum++;
- ssnum=30;
- fsnum=30;
- fgnum=30;
- }
-
-
- if(ssnum>=30)
- {
- // if((shi/10)<1) //如果小时十位小于1,
- // {
- // wela=1;
- // P0=0xfe; //第1位
- // wela=0;
- //
- // dula = 1;
- // P0=0xff; // 小时十位就不显示
- // dula = 0;
- // }
- //
- // else
- {
- wela=1;
- P0=0xfe; //第1位
- wela=0;
-
- dula=1;
- P0=d[shi/10];
- dula=0;
- P0=0xff;
- delay(2);
- }
- if(ssnum==60)
- ssnum=0;
- }
- if(sgnum>=30)
- {
- wela=1;
- P0=0xfd; //第2位
- wela=0;
- dula=1;
- P0=d[shi%10]; //时的个位,P0=d[shi%10]时的个位小数点闪烁
- dula=0; // 时的个位,P0=dd[shi%10]时的个位小数点不闪烁
- P0=0xff;
- delay(2);
-
-
-
- if(sgnum==60)
- sgnum=0;
- }
- // if(miao%2==0) //if(miao%2==0) 1秒闪烁1次
- if(ss>=10) // 这里写为ss>=10,闪烁频率可调
- {
- wela=1;
- P0=0xfb; //第3位
- wela=0;
-
- dula=1;
- P0=0x40; //第三位数码管显示“— ”
-
- // P0=0x09; //第三位数码管显示“= ”
- dula=0;
- P0=0xff;
- delay(2);
-
- }
- else
- {
- wela=1;
- P0=0xfb; //第3位
- wela=0;
-
- dula=1;
- P0=0; //第三位数码管不显示
- dula=0;
- P0=0xff;
- delay(2);
- }
-
-
- if(fsnum>=30)
- {
- wela=1;
- P0=0xf7; //第4位
- wela=0;
- dula=1;
- P0=d[fen/10];
- dula=0;
- P0=0xff;
- delay(2);
-
-
- // wela=1;
- // P0=0xef; //第5位
- // wela=0;
- //
- // dula=1;
- // P0=d[fen%10];
- // dula=0;
- // P0=0xff;
- // delay(2);
-
-
- if(fsnum==60)
- fsnum=0;
- }
- if(fgnum>=30)
- {
- wela=1;
- P0=0xef; //第5位
- wela=0;
- dula=1;
- P0=d[fen%10];
- dula=0;
- P0=0xff;
- delay(2);
- if(fgnum==60)
- fgnum=0;
- }
-
- // if(miao%2==0) //if(miao%2==0) 1秒闪烁1次
- // if(ss>=10) //if(ss>=10)闪烁频率可调
- // {
- // wela=1;
- // P0=0xdf; //第6位
- // wela=0;
- // dula=1;
- // P0=0x40; //第六位数码管显示“— ”
- // dula=0;
- // P0=0xff;
- //
- // delay(2);
- // }
- //
- // else
- // {
- // wela=1;
- // P0=0xdf; //第6位
- // wela=0;
- // dula=1;
- // P0=0; //第六位数码管不显示
- // dula=0;
- // P0=0xff;
- //
- // delay(2);
- // }
- //
- //
- // wela=1;
- // P0=0xbf; //第7位
- // wela=0;
- //
- // dula=1;
- // P0=d[miao/10]; //秒十位
- // dula=0;
- // P0=0xff;
- // delay(2);
- //
- //
- // wela=1;
- // P0=0x7f; //第8位
- // wela=0;
- //
- // dula=1;
- // P0=d[miao%10]; //秒个位
- // dula=0;
- // P0=0xff;
- // delay(2);
-
- }
- void write_1302(uchar add,dat) //写1302函数 qx
- {
- uchar i,temp;
- temp=add;
- ce=0;
- _nop_();
- sclk=0;
- _nop_();
- ce=1;
- _nop_();
- for(i=0;i<8;i++)
- {
- sclk=0;
- _nop_();
- if((temp&0x01)==0x01)
- dio=1;
- else
- dio=0;
- temp>>=1;
- sclk=1;
- _nop_();
- }
- temp=dat;
- for(i=0;i<8;i++)
- {
- sclk=0;
- _nop_();
- if((temp&0x01)==0x01)
- dio=1;
- else
- dio=0;
- temp>>=1;
- sclk=1;
- _nop_();
- }
- ce=0;
- sclk=0;
- }
- uchar read_1302(uchar add) //读1302函数 qx
- {
- uchar dat,dat1,i,temp;
- temp=add;
- ce=0;
- _nop_();
- sclk=0;
- _nop_();
- ce=1;
- for(i=0;i<8;i++)
- {
- sclk=0;
- _nop_();
- if((temp&0x01)==0x01)
- dio=1;
- else
- dio=0;
- temp>>=1;
- sclk=1;
- _nop_();
- }
- for(i=0;i<8;i++)
- {
- sclk=0;
- _nop_();
- if(dio)
- dat|=0x80;
- if(i<7)
- dat>>=1;
- sclk=1;
- }
- dat1=dat/16; //读出的数值转为10进制
- dat=dat%16;
- dat=dat1*10+dat;
- ce=0;
- sclk=0;
- return dat;
- }
- void init_1302() //初始化函数 设置第一次上电时显示的时间值
- {
- write_1302(0x8e,0x00); //保护取消,可以进行写操作
- write_1302(write_miao,0x57); //写秒57
- write_1302(write_fen,0x30); //写分30
- write_1302(write_shi,0x12); //写时12
- write_1302(0x8e,0x80); //保护启动,不能进行写操作
- }
- void read_sf() //读时分秒
- {
- shi=read_1302(read_shi);
- fen=read_1302(read_fen);
- miao=read_1302(read_miao);
- display(shi,fen);
- }
- void keyscan() //按键扫描函数
- {
- uchar fs,fg,shs,shg; //分钟十位、个位 ,小时十位、个位
- static uint a; //按键延时变量
- fs = fen/10; fg=fen%10; //分钟十位、个位
- shs = shi/10; shg=shi%10; //小时十位、个位
- if(key1==0)
- {
- a++;
- if(a>50)
- while(!key1)
- {
- display(shi,fen);
- a=0;
- zdyw=1;
- }
- }
- else
- {
- if(a>10 && a<50)
- {
- count=0; //每次按下,count都要清零,松手后,count都是从0开始计数,这句很重要
- a=0;
- if(knum==1) //小时十位调节
- {
- shs++;
- if(shs>2) shs=0;
- shi=shs*16+shg;
- write_1302(write_shi,shi); //写入1302
- read_sf(); //读出时间,然后显示
- }
- /*********************/
- if(knum==2) //小时个位调节
- {
-
- shg++;
- if(shs==0 || shs==1) //如果小时十位为0、1
- {
- if(shg>9) shg=0; //小时个位可以在0-9变化
- }
- else //否则,小时个位可以在0-3变化
- {
- if(shg>3) shg=0;
- }
- shi=shs*16+shg; //10进制转为16进制
- write_1302(write_shi,shi); //写入1302
- read_sf(); //读出时间,然后显示
- }
- /************************/
- if(knum==3) //分钟十位调节
- {
- fs++;
- if(fs>5) fs=0;
- fen=fs*16+fg;
- write_1302(write_fen,fen); //写入1302
- read_sf(); //读出时间,然后显示
- }
- /*******************/
- if(knum==4) //分钟个位调节
- {
- fg++;
- if(fg>9) fg=0;
- fen=fs*16+fg;
- write_1302(write_fen,fen); //写入1302
- read_sf(); //读出时间,然后显示
- }
-
- /***********************/
- if(knum==0) //非调时状态,短按key1,开关LED
- {
- led=~led;
- }
- }
- }
- }
- /************************/
- void main()
- {
- t0_init();
- init_1302();
- while(1)
- {
- read_sf();
- keyscan();
- }
- }
- void temer1() interrupt 1
- {
- TH0=(65536-46080)/256;
- TL0=(65536-46080)%256;
- ss++;
- if(ss==20) //1秒时间到
- {
- ss=0;
- if(zdyw)
- {
- count++;
- if(count==5) //调时的时候,自动移位快慢调这里,要快就把count的值减小,反之亦然。
- {
- count=0;
- knum++;
- if(knum==1)
- {
- write_1302(0x8e,0x00); //写保护取消
- // write_1302(write_miao,0x80); // 写秒80,时钟停止走时;
- }
- if(knum>4)
- {
- knum=0;
- zdyw=0;
- write_1302(write_miao,0x00);
- write_1302(0x8e,0x80); //写保护启动
- }
- }
- }
- }
- }
复制代码 全部资料51hei下载地址:
时钟个十位分开调节 -1键调节.rar
(181.79 KB, 下载次数: 15)
|