百度ds1302 寫道
DS1302 是美國DALLAS公司推出的一種高性能、低功耗、帶RAM的實時時鐘電路,它可以對年、月、日、周日、時、分、秒進行計時,具有閏年補償功能,工作電壓為2.5V~5.5V。采用三線接口與CPU進行同步通信,并可采用突發(fā)方式一次傳送多個字節(jié)的時鐘信號或RAM數(shù)據(jù)。DS1302內部有一個31×8的用于臨時性存放數(shù)據(jù)的RAM寄存器。DS1302是DS1202的升級產品,與DS1202兼容,但增加了主電源/后備電源雙電源引腳,同時提供了對后備電源進行涓細電流充電的能力。
DS1302的引腳排列,其中Vcc1為后備電源,VCC2為主電源。在主電源關閉的情況下,也能保持時鐘的連續(xù)運行。DS1302由Vcc1或Vcc2兩者中的較大者供電。當Vcc2大于Vcc1+0.2V時,Vcc2給DS1302供電。當Vcc2小于Vcc1時,DS1302由Vcc1供電。X1和X2是振蕩源,外接32.768kHz晶振。RST是復位/片選線,通過把RST輸入驅動置高電平來啟動所有的數(shù)據(jù)傳送。RST輸入有兩種功能:首先,RST接通控制邏輯,允許地址/命令序列送入移位寄存器;其次,RST提供終止單字節(jié)或多字節(jié)數(shù)據(jù)傳送的方法。當RST為高電平時,所有的數(shù)據(jù)傳送被初始化,允許對DS1302進行操作。如果在傳送過程中RST置為低電平,則會終止此次數(shù)據(jù)傳送,I/O引腳變?yōu)楦咦钁B(tài)。上電運行時,在Vcc>2.0V之前,RST必須保持低電平。只有在SCLK為低電平時,才能將RST置為高電平。I/O為串行數(shù)據(jù)輸入輸出端(雙向),后面有詳細說明。SCLK為時鐘輸入端。 下圖為DS1302的引腳功能圖
.....................................................................................
我在淘寶上花了幾塊錢買了個山寨的1302模塊,湊合著可以用,
但是模塊上的sclk,io,RST這3個腳沒有上拉電阻,自己加上去了,汗!
不加上拉電阻,顯示的時鐘很容易發(fā)生錯誤
好了不多說,貼代碼
本程序只顯示時間,沒有年份和月份...
C代碼
#include"my51.h"
#include"smg.h"
#include"ds1302.h"
voidmain()//ds1302顯示時鐘
{
ds1302_initSet();//初始化
//ds1302_stop();停掉1302,進入省電模式
while(1)
{
ds1302_readRTC();_nop_();//讀取時鐘數(shù)據(jù)
displaySMG(ds1302_processTimeData());//處理數(shù)據(jù)并送數(shù)碼管顯示
}
}
C代碼
#ifndef_DS1302_H
#define_DS1302_H
#include"my51.h"
sbitrst=P3^4;//片選總線
sbitsda=P3^5;//數(shù)據(jù)總線
sbitscl=P3^6;//時鐘線
externu8datasmgWela[7];//數(shù)碼管顯示參數(shù)
externu8datatimeData[7];//年,周,月,日,時,分,秒的初值
//voidds1302_setUnCharger()//充電控制,禁止充電
//voidds1302_stop();//暫停ds1302,進入超低功耗模式
u8*ds1302_processTimeData();//處理時鐘數(shù)據(jù),送給數(shù)碼管顯示
voidds1302_readRTC();//讀取所有時鐘數(shù)據(jù)的BCD碼
voidds1302_initSet();//設置初始化數(shù)據(jù)
u8ds1302_readData(u8addr);//從ds1302讀一個字節(jié),讀的時候會先寫地址
voidds1302_writeByte(u8dat);//寫一個字節(jié)
voidds1302_writeData(u8addr,u8dat);//向指定地址寄存器寫數(shù)據(jù)
#endif
C代碼
#include"ds1302.h"
datau8timeData[7]={10,6,4,17,11,20,55};
codeu8writeAddr[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//寫年周月日時分秒寄存器地址指令
codeu8readAddr[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//讀的指令地址
voidds1302_writeData(u8addr,u8dat)//向指定地址寄存器寫數(shù)據(jù)
{
rst=0;_nop_();
scl=0;_nop_();
rst=1;_nop_();
ds1302_writeByte(addr);//先寫入地址
ds1302_writeByte(dat);
rst=0;_nop_();//關閉
sda=1;//釋放
scl=1;
}
voidds1302_writeByte(u8dat)//寫一個字節(jié)
{
u8i=0;
for(i=0;i<8;i++)
{
scl=0;//時鐘線拉低
sda=dat&0x01;//數(shù)據(jù)從最低位開始賦值
dat>>=1;
scl=1;_nop_();//上升沿寫入一位
}
}
u8ds1302_readData(u8addr)//從ds1302讀一個字節(jié),讀的時候會先寫地址
{
u8i,value=0;
rst=0;_nop_();
scl=0;_nop_();
sda=1;_nop_();
rst=1;_nop_();
ds1302_writeByte(addr);//先寫入要讀的地址
_nop_();
sda=1;_nop_();
for(i=0;i<8;i++)
{
value>>=1;
scl=0;_nop_();//下降沿開始后提取有效數(shù)據(jù)
if(sda)//讀數(shù)據(jù)
{
value|=0x80;//高電平手動置位保存數(shù)據(jù),
}//低電平數(shù)據(jù)value最高位默認已經是0
scl=1;//為下一次讀取數(shù)據(jù)做準備
}
rst=0;
returnvalue;
}
voidds1302_initSet()//設置初始化數(shù)據(jù)
{
u8i,j;
for(i=0;i<7;i++)//將初始化數(shù)據(jù)處理成BCD碼
{
j=timeData[i]/10;
timeData[i]=timeData[i]%10;
timeData[i]=timeData[i]+j*16;
}
ds1302_writeData(0x8e,0x00);//清除寫保護
for(i=0;i<7;i++)
{//將時鐘日歷數(shù)據(jù)經過轉換后的BCD碼寫到7個時鐘日歷寄存器中
ds1302_writeData(writeAddr[i],timeData[i]);
}
ds1302_writeData(0x90,0x5c);//禁止充電,降低功耗,針對不可充電電池
//ds1302_writeData(0x90,0xa6);//開啟充電,用一個二極管,用4k電阻
ds1302_writeData(0x8e,0x80);//使能寫保護
}
voidds1302_readRTC()//讀取所有時鐘數(shù)據(jù)的BCD碼
{
u8i;
for(i=0;i<7;i++)
{//讀取的時候會把時鐘日歷的7個寄存器中的數(shù)據(jù)全部讀取,并保存到timeData[]
timeData[i]=ds1302_readData(readAddr[i]);
}
}
u8*ds1302_processTimeData()//顯示時鐘,暫時只顯示時間
{
smgWela[5]