DS1302實時時鐘,加了調時功能 ,仿真 實物都通過,現(xiàn)在想加一個掉電走時的功能,試了好多方法都不行,
把1302初始化‘init_1302(); ’這句注釋掉,再把程序燒進去,掉電雖然不會初始化時間,但1302不會繼續(xù)走時,時間就
停在掉電那個時候的時間,在上電只能接著掉電那個時候的時間走時
/*********************************************************************************
DS1302實時時鐘,加了調時功能 ,仿真 實物都通過
**********************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//#define W P0 //位選
//#define D P0 //段選
/*sbit IO=P1^1; //數(shù)據(jù)口
sbit SCLK=P1^0; //控制數(shù)據(jù)時鐘
sbit RST=P1^2; //使能端、復位端 */
sbit sclk = P1^0;
sbit dio = P1^1;
sbit ce = P1^2;
sbit wela = P2^7;
sbit dula = P2^6;
sbit s1=P3^0; //按鍵 加
sbit s2=P3^1; //按鍵 減
sbit s3=P3^3; //按鍵 選擇
bit flag;//是否讀取時間的標志位
char knum=0,snum,fnum;
char shi,fen,miao;
bit miao_flag;
uchar miao_num,ss;
/***********寫時分秒地址************/
#define write_shi 0x84
#define write_fen 0x82
#define write_miao 0x80
/***********讀時分秒地址************/
#define read_shi 0x85
#define read_fen 0x83
#define read_miao 0x81
uchar d[]={ 0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F}; //共陰不帶小數(shù)點
uchar dd[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef
};// 共陰帶小數(shù)點
//uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //共陽帶小數(shù)點
//uchar d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //共陽不帶小數(shù)點
//uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //共陽帶小數(shù)點 */
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=120;y>0;y--);
}
/*uchar code table[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
0x76, //"H"
0x38, //"L"
0x37, //"n"
0x3E, //"u"
0x73, //"P"
0x5C, //"o"
0x40, //"-"
0x00, //熄滅
0x00 //自定義
};
void display(uchar shi10,shi,fen10,fen,miao10,miao)
{
dula=1;
P0=table[shi10];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(1);
dula=1;
P0=table[shi]|0x80; // table[shi]|0x80, table[shi]或0x80就可以顯示小數(shù)點
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(1);
dula=1;
P0=table[fen10];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay(1);
dula=1;
P0=table[fen]|0x80;
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
delay(1);
dula=1;
P0=table[miao10];
dula=0;
P0=0xff;
wela=1;
P0=0xef;
wela=0;
delay(1);
dula=1;
P0=table[miao];
dula=0;
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
delay(1);
} */
void t0_init() //定時50ms一個中斷
{
TMOD=0X01;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
EA=1;
ET0=1;
TR0=1;
}
void temer1() interrupt 1
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
ss++;
if(ss==20)
ss=0;
}
void display(uchar shi,uchar fen,uchar miao) //顯示函數(shù)
{
// if(miao%2==0)
if(ss<=10) // 這里寫為ss<=10,第三位數(shù)碼管顯示“— ”閃爍與 第六位數(shù)碼管顯示“= ”
{ //閃爍相反,一個亮時,另一個滅
wela=1;
P0=0xfb;
wela=0;
dula=1;
// P0=0x40; //第三位數(shù)碼管顯示“— ”
P0=0x09; //第三位數(shù)碼管顯示“= ”
dula=0;
P0=0xff;
delay(1);
}
else
{
wela=1;
P0=0xfb;
wela=0;
dula=1;
P0=0; //第三位數(shù)碼管不顯示
dula=0;
P0=0xff;
delay(1);
}
// if(miao%2==0) //if(miao%2==0) 1秒閃爍1次
if(ss>=10) //if(ss>=10)閃爍頻率可調
{
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=0x40; //第六位數(shù)碼管顯示“— ”
dula=0;
P0=0xff;
delay(1);
}
else
{
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=0; //第六位數(shù)碼管不顯示
dula=0;
P0=0xff;
delay(1);
}
if(knum==0)
{
snum=30;
fnum=30;
}
if(knum==1)
{
fnum++;
snum=30;
}
if(knum==2)
{
snum++;
fnum=30;
}
if(snum>=30)
{
if((shi/10)<1) //如果小時十位小于1,
{
wela=1;
P0=0xfe;
wela=0;
dula = 1;
P0=0xff; // 小時十位就不顯示
dula = 0;
}
else
{
wela=1;
P0=0xfe;
wela=0;
dula=1;
P0=d[shi/10];
dula=0;
P0=0xff;
delay(1);
}
/* if(miao%2==0) //小數(shù)點閃爍
{
wela=1;
P0=0xfd;
wela=0;
dula=1;
P0=d[shi%10]; //時的個位,P0=d[shi%10]時的個位小數(shù)點不亮
dula=0; //時的個位,P0=dd[shi%10]時的個位小數(shù)點亮
P0=0xff;
delay(1);
} */
// else
// {
wela=1;
P0=0xfd;
wela=0;
dula=1;
P0=d[shi%10]; //時的個位,P0=d[shi%10]時的個位小數(shù)點閃爍
dula=0; // 時的個位,P0=dd[shi%10]時的個位小數(shù)點不閃爍
P0=0xff;
delay(1);
// }
if(snum==60)
snum=0;
}
if(fnum>=30)
{
wela=1;
P0=0xf7;
wela=0;
dula=1;
P0=d[fen/10];
dula=0;
P0=0xff;
delay(1);
wela=1;
P0=0xef;
wela=0;
dula=1;
P0=d[fen%10];
dula=0;
P0=0xff;
delay(1);
if(fnum==60)
fnum=0;
}
wela=1;
P0=0xbf;
wela=0;
dula=1;
P0=d[miao/10]; //秒十位
dula=0;
P0=0xff;
delay(1);
wela=1;
P0=0x7f;
wela=0;
dula=1;
P0=d[miao%10]; //秒個位
dula=0;
P0=0xff;
delay(1);
}
void write_1302(uchar add,dat) //寫函數(shù) 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) //讀函數(shù) 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;
dat=dat%16;
dat=dat1*10+dat;
ce=0;
sclk=0;
return dat;
}
void init_1302() //初始化函數(shù) 設置時間
{
write_1302(0x8e,0x00); //保護取消,可以進行讀寫操作
write_1302(write_miao,0x57);
write_1302(write_fen,0x55);
write_1302(write_shi,0x15);
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,miao);
}
void keyscan() //按鍵掃描函數(shù)
{
if(s3==0) //選擇按鍵按下
{
delay(10); //延時
if(s3==0)
{
while(!s3) //松手檢測
display(shi,fen,miao); //加上這句,按鍵按下就不會閃
knum++;
if(knum==1) //分閃爍
{
write_1302(0x8e,0x00); //保護取消
write_1302(write_miao,0x80); // write_1302(write_miao,0x80);
}
if(knum==3) //時鐘啟動
{
knum=0;
write_1302(write_miao,0x00);
write_1302(0x8e,0x80); //保護啟動
}
}
}
if(knum==1) //分鐘調節(jié)
{
if(s1==0) //加
{
delay(10);
if(s1==0)
{
while(!s1)
display(shi,fen,miao); //加上這句,按鍵按下就不會閃
fen++;
fen=fen/10*16+fen%10; //轉為16進制
if(fen==0x60)
fen=0x00;
write_1302(write_fen,fen); //寫入1302
read_sf(); //讀出時間,然后顯示
}
}
if(s2==0)
{
delay(10);
if(s2==0)
{
while(!s2)
display(shi,fen,miao); //加上這句,按鍵按下就不會閃
fen--;
fen=fen/10*16+fen%10; //轉為16進制
if(fen==-1)
fen=0x59;
write_1302(write_fen,fen);
read_sf();
}
}
}
if(knum==2)
{
if(s1==0)
{
delay(10);
if(s1==0)
{
while(!s1)
display(shi,fen,miao); //加上這句,按鍵按下就不會閃
shi++;
shi=shi/10*16+shi%10; //轉為16進制
if(shi==0x24)
shi=0x00;
write_1302(write_shi,shi);
read_sf();
}
}
if(s2==0)
{
delay(10);
if(s2==0)
{
while(!s2)
display(shi,fen,miao); //加上這句,按鍵按下就不會閃
shi--;
shi=shi/10*16+shi%10; //轉為16進制
if(shi==-1)
shi=0x23;
write_1302(write_shi,shi);
read_sf();
}
}
}
}
void main()
{
t0_init();
init_1302();
while(1)
{
read_sf();
keyscan();
write_1302(0x8e,0x00);
shi=read_1302(0x85);
fen=read_1302(0x83);
miao=read_1302(0x81);
write_1302(0x8e,0x00);
display(shi,fen,miao);
}
}
|