參考了幾個程序的核心部分,自己修改組合了一下,就想實現一個基本的可調時鐘。一共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;
- }
復制代碼
|