ds1302非常容易受幹擾,註意接線盡量短,程序中在恰當的地方加NOP以穩定電路。
#define _k0 P2^0
#define _k1 P2^1
#define _k2 P2^2
#define _bella P2^4
#define _bellb P2^5
#define _ds1302clk P3^5
#define _ds1302io P3^6
#define _ds1302rst P3^7
#include<reg52.h>
#include<intrins.h>
#include<delay.h>
#define DS1302_Write_Second0x80// 秒
#define DS1302_Read_Second0x81
#define DS1302_Write_Minite0x82// 分
#define DS1302_Read_Minite0x83
#define DS1302_Write_Hour0x84//小時
#define DS1302_Read_Hour0x85
#define DS1302_Write_Date0x86// 天
#define DS1302_Read_Date0x87
#define DS1302_Write_Month0x88// 月
#define DS1302_Read_Month0x89
#define DS1302_Write_Week0x8A//星期
#define DS1302_Read_Week0x8B
#define DS1302_Write_Year0x8C// 年
#define DS1302_Read_Year0x8D
#define DS1302_Read_Protect0x8E//寫保護位
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit k0=_k0;
sbit k1=_k1;
sbit k2=_k2;
sbit bella= _bella;
sbit bellb= _bellb;
sbit ds1302rst= _ds1302rst;
sbit ds1302io= _ds1302io;
sbit ds1302clk= _ds1302clk;
bit k0f,k1f,k2f;
uchar time[7]={13,6,4,27,10,50,59};
//ds1302==============///////////////////////////////////
uchar bcd2hex(uchar bcd)
{
return ((bcd>>4)*10+(bcd&0x0f));
}
uchar hex2bcd(uchar hex)
{
return ((hex/10)*16+(hex%10));
}
//寫壹個字節
void write_ds1302_byte(uchar dat)
{uchar i;
ACC = dat;
for(i=8; i>0; i--)
{
ds1302clk = 0;
ds1302io= ACC0; ////由低位到高位
ACC = ACC >> 1;
ds1302clk= 1; //上升沿寫入數據
// _nop_();
}
}
//讀壹個字節
uchar read_ds1302_byte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ds1302clk = 0; //下降沿讀出DS1302的數據
_nop_();
_nop_();
_nop_();
ACC = ACC >>1; //相當於匯編中的 RRC
ACC7 = ds1302io;
ds1302clk = 1;
}
return(ACC);
}
//在指定地址寫入指定的數據
void write_ds1302(uchar addr,uchar dat)//addr為將要寫入的地址,dat為精要寫入的數據
{
ds1302rst = 0;
_nop_();
ds1302clk = 0;
_nop_();
ds1302rst= 1;
_nop_();
//發送地址
write_ds1302_byte(addr);
//發送數據
write_ds1302_byte(dat);
ds1302rst=0;
}
//讀取1302指定地址中的數據
unsigned char Read_DS1302(uchar addr)
{
uchar dat;
ds1302rst = 0;
_nop_();
_nop_();
ds1302clk = 0;
_nop_();
_nop_();
ds1302rst= 1; //RST拉高,啟動數據傳送
_nop_();
_nop_();
write_ds1302_byte( addr|0x01);//地址,命令
dat = read_ds1302_byte(); //讀1Byte數據
ds1302rst =0;
_nop_();//以下為DS1302復位的穩定時間
_nop_();
ds1302rst =0;
ds1302clk = 0;
_nop_();
_nop_();
_nop_();
_nop_();
ds1302clk = 1;
_nop_();
_nop_();
ds1302io=0;
_nop_();
_nop_();
ds1302io=1;//釋放數據總線
_nop_();
_nop_();
return(dat);
}
//////////////////////寫入時間
void settime()
{
uchar i,addr=0x8c;
write_ds1302(DS1302_Read_Protect,0x00);//取消寫保護
for(i=0;i<7;i++)
{
write_ds1302(addr,hex2bcd(time[i]));
addr-=2;
}
write_ds1302(DS1302_Read_Protect,0x80);//啟動寫保護
}
///////////////////////////////////讀取時間
void gettime()
{
uchar i;
uchar addr=0x8d;
for(i=0;i<7;i++)
{
time[i]=bcd2hex(Read_DS1302(addr));
addr-=2;
}
}
void ds1302init(void)
{
uchar temp;
temp = Read_DS1302(DS1302_Read_Second);
if(k0==0&&temp&0x80)//如果時鐘正在運行,則不進行初始化//按著設置鍵重啟時。
{
settime();
}
//開寫保護
}