参考了几个程序的核心部分,自己修改组合了一下,就想实现一个基本的可调时钟。一共3个按键,设置,加,减。按设置可以在时,分钟之间切换,同时相应位会闪烁。秒是采用的led指示,通过定时器中断试验出的计数值来控制,不是特别准确,主要起装饰作用。。目前的现象是,能按照初始时间走时,按设置能切换闪烁,但无法加减小时或者分钟,应该是往1302写数据的程序有问题,但也没看出来有什么问题,没有解决的思路了,希望各位高手指点一下错误。
单片机源程序如下:- #include<reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- uint milsec;
- uchar i,t,a,d,sec,hour,hour1,min,min1,flag,temp,key=0,S_flag=0,k=0;
- unsigned char led[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; //用一维数组定义0-9、横杠、全灭
- unsigned char b[4]={0x07,0x0b,0x0d,0x0e}; //扫描
- unsigned char c[4];
- sbit dula=P2^6;
- sbit wela=P2^7;
- sbit SCLK=P1^0; //1302接口
- sbit IO=P1^1;
- sbit RST=P1^2;
- sbit ACC0=ACC^0;
- sbit ACC7=ACC^7;
- //sbit key=P3^7; //按键接口
- sbit key1=P3^3;
- sbit key2=P3^1;
- sbit key3=P3^2;
- sbit S5=P1^3; //指示秒的led
- void delay(uint xms)//ms延时函数
- {
- uint x,y;
- for(x=xms;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*********************over***********************/
- /********************ds1302****************************/
- void write_byte(uchar dat)
- {
- ACC=dat;
- RST=1;
- for(a=8;a>0;a--)
- {
- IO=ACC0;
- SCLK=0;
- SCLK=1;
- ACC=ACC>>1;
- }
- }
- uchar read_byte()
- {
- RST=1;
- for(a=8;a>0;a--)
- {
- ACC7=IO;
- SCLK=1;
- SCLK=0;
- ACC=ACC>>1;
- }
- return (ACC);
- }
- void write_1302(uchar add,uchar dat)
- {
- RST=0;
- SCLK=0;
- RST=1;
- write_byte(add);
- write_byte(dat);
- SCLK=1;
- RST=0;
- }
- uchar read_1302(uchar add)
- {
- uchar temp;
- RST=0;
- SCLK=0;
- RST=1;
- write_byte(add);
- temp=read_byte();
- SCLK=1;
- RST=0;
- return(temp);
- }
- uchar BCD_Decimal(uchar bcd)
- {
- uchar Decimal;
- Decimal=bcd>>4;
- return(Decimal=Decimal*10+(bcd&=0x0F));
- }
- uchar Decimal_BCD(uchar dec)
- {
- uchar bcd;
- bcd=((dec%10)&0x0f)|(((dec/10)<<4)&0xf0);
- return bcd;
- }
- void ds1302_init()
- {
- RST=0;
- SCLK=0;
- write_1302(0x8e,0x00); //关写保护
- write_1302(0xc0,0xfe);
- write_1302(0xc2,0xff);
-
- write_1302(0x80,0x00); //写初始sec
- write_1302(0x82,0x10); //写初始min
- write_1302(0x84,0x18); //写初始hour
-
- write_1302(0x8e,0x80); //开写保护
- }
- void display()
- {
-
- switch(key)
- {
- case 0: c[0]=led[hour/10];
- c[1]=led[hour%10];
- c[2]=led[min/10];
- c[3]=led[min%10];
- break;
- case 1: if(S_flag==0)
- {
- c[0]=led[hour/10];
- c[1]=led[hour%10];
- }
- else
- {
- c[0]=0xff;
- c[1]=0xff;
- }
-
- c[2]=led[min/10];
- c[3]=led[min%10];
- break;
- case 2: c[0]=led[hour/10];
- c[1]=led[hour%10];
-
- if(S_flag==0)
- {
- c[2]=led[min/10];
- c[3]=led[min%10];
- }
- else
- {
- c[2]=0xff;
- c[3]=0xff;
- }
- break;
- }
- }
-
- void init()
- {
- TMOD=0x01;
- TH0=0xfc; //定时1ms
- TL0=0x18;
- EA=1;
- ET0=1;
- TR0=1;
- S5=0;
- }
- void cmg(void)//数码管锁存函数
- {
- dula=1;
- P0=0x00;
- dula=0;
- wela=1;
- P0=0x00;
- wela=0;
- }
- void keyscan()
- {
- if(key1==0)//key1为功能键
- {
- delay(2);
- if(key1==0)
- {
- //while(!key1);
- for(i=0;((i<10)&&(key1==0));i++) //检测按键释放
- {
- delay(1);
- }
- key++;
-
- if(key>2)
- key=0;
-
- if(key!=0)
- {
- switch(key)
- {
-
- case 1:
- if(key2==0) //调时
- delay(2);
- if(key2==0)
- {
-
- for(i=0;((i<10)&&(key2==0));i++) //检测按键释放
- {
- delay(1);
- }
-
- hour1=hour;
- hour1++;
- if(hour1>23)
- hour1=0;
-
- temp=Decimal_BCD(hour1);
- //temp=(hour1)/10*16+(hour1)%10;
- write_1302(0x8e,0x00);
- write_1302(0x84,temp);
- write_1302(0x8e,0x80);
- }
-
- if(key3==0)
- delay(2);
- if(key3==0)
- {
-
- for(i=0;((i<10)&&(key3==0));i++) //检测按键释放
- {
- delay(1);
- }
- hour1=hour;
- hour1--;
- if(hour1<0)
- hour1=23;
-
- //temp=Decimal_BCD(hour1);
- temp=(hour1)/10*16+(hour1)%10;
- write_1302(0x8e,0x00);
- write_1302(0x84,temp);
- write_1302(0x8e,0x80);
-
- }
-
- break;
- case 2: if(key2==0) //调分
- delay(2);
- if(key2==0)
- {
- for(i=0;((i<10)&&(key2==0));i++)
- {
- delay(1);
- }
- if(min<59)
- min++;
- else
- min=0;
- //temp=(min)/10*16+(min)%10;
- temp=Decimal_BCD(min);
- write_1302(0x8e,0x00);
- write_1302(0x82,temp);
- write_1302(0x80,0x00); //miao复位
- write_1302(0x8e,0x80);
- }
-
- if(key3==0)
- delay(2);
- if(key3==0)
- {
- for(i=0;((i<10)&&(key3==0));i++)
- {
- delay(1);
- }
- if(min>0)
- min--;
- else
- min=59;
- temp=(min)/10*16+(min)%10;
- //temp=Decimal_BCD(min);
- write_1302(0x8e,0x00);
- write_1302(0x82,temp);
- write_1302(0x80,0x00); //miao复位
- write_1302(0x8e,0x80);
- }
- break;
- }
-
- }
- }
- }
- }
-
-
-
- void main()
- {
- cmg();//数码管锁存 (关闭开发板数码管)
- ds1302_init();
- init();
- while(1)
- {
- keyscan();
- display();
- }
- }
- void timer0() interrupt 1
- {
- TH0=0xfc; //定时1ms
- TL0=0x18;
- //TL0 = (65536-1932)/256; //设置定时初值 10ms
- //TH0 = (65536-1932)%256;
- //TH0=0xfb; //定时ms
- //TL0=0x74;
- /*t++;
- if(t==255)
- {
- t=0;
- S5=!S5;
- }
- */
-
- d++;
- if(d==20)
- {
- d=0;
- write_1302(0x8e,0x00);
- //sec = BCD_Decimal(read_1302(0x81));
- min = BCD_Decimal(read_1302(0x83));
- hour = BCD_Decimal(read_1302(0x85));
- write_1302(0x8e,0x80);
- }
-
- milsec++;
- if(milsec==440)
- {
- milsec=0;
- S_flag=!S_flag;
- S5=!S5;
- }
-
- if(k==4)
- k=0;
- P0=c[k];
- P2=b[k++];
- delay(1);
- P2=0xff;
- }
复制代码
|