|
- #include "intrins.h"
- #ifndef _DS1302_H_
- #define _DS1302_H_
- sbit clk = P2^2; //ds1302時鐘線定義
- sbit io = P2^1; //數(shù)據(jù)線
- sbit rst = P2^0; //復(fù)位線
- //秒 分 時 日 月 年 星期
- uchar code write_add[]={0x80,0x82,0x84,0x86,0x88,0x8c,0x8a}; //寫地址
- uchar code read_add[] ={0x81,0x83,0x85,0x87,0x89,0x8d,0x8b}; //讀地址
- uchar code init_ds[] ={0x58,0x29,0x07,0x05,0x10,0x14,0x1};
- extern uchar miao,fen,shi,ri,yue,week,nian;
- extern uchar i;
- void delaynus(unsigned char n)
- {
- unsigned char i;
- for(i=0;i<n;i++);
- }
- //向1302寫一個字節(jié)數(shù)據(jù)
- void Write1302(unsigned char dat)
- {
- unsigned char i;
- clk=0; //拉低CLK,為脈沖上升沿寫入數(shù)據(jù)做準(zhǔn)備
- delaynus(2); //稍微等待,使硬件做好準(zhǔn)備
- for(i=0;i<8;i++) //連續(xù)寫8個二進(jìn)制數(shù)據(jù)
- {
- io=dat&0x01; //取出dat的第0位數(shù)據(jù)寫入1302
- delaynus(2); //稍微等待,使硬件做好準(zhǔn)備
- clk=1; //上升沿寫入數(shù)據(jù)
- delaynus(2); //稍微等待,使硬件做好準(zhǔn)備
- clk=0; //重新拉低SCLK,形成脈沖
- dat>>=1; //將dat的各數(shù)據(jù)位右移1位,準(zhǔn)備下入下一位數(shù)據(jù)位
- }
- }
- /*************根據(jù)命令,向1302寫一個數(shù)據(jù)到對應(yīng)的地址里***************/
- void write_ds1302(uchar add,uchar dat)
- {
- rst=0; //禁止數(shù)據(jù)傳遞
- clk=0; //確保寫數(shù)據(jù)前CLK被拉低
- rst=1; //啟動數(shù)據(jù)傳輸
- delaynus(2); //稍微等待,為硬件做好準(zhǔn)備
- Write1302(add); //寫入命令字
- Write1302(dat); //寫數(shù)據(jù)
- clk=1; //將始終電平置于已知狀態(tài)
- rst=0; //禁止數(shù)據(jù)傳遞
- }
- /*****************************************************
- 從1302讀一個字節(jié)數(shù)據(jù)
- ***************************************************/
- unsigned char Read1302(void)
- {
- unsigned char i,dat;
- delaynus(2); //稍微等待,為硬件做好準(zhǔn)備
- for(i=0;i<8;i++) //連續(xù)讀8個二進(jìn)制位數(shù)據(jù)
- {
- dat>>=1; //將dat的各數(shù)據(jù)位右移1位,因?yàn)橄茸x出來的是字節(jié)的最低位
- if(io==1) //如果讀出來的是1
- dat|=0x80; //將1取出,寫在dat的最高位
- clk=1; //將clk置于高電平,為下降沿讀出
- delaynus(2); //稍微等待
- clk=0; //拉低clk,形成脈沖下降沿
- delaynus(2); //稍微等待
- }
- return dat; //將讀出來的數(shù)據(jù)返回
- }
- /*************根據(jù)命令,從1302對應(yīng)的地址讀一個數(shù)據(jù)出來***************/
- uchar read_ds1302(uchar add)
- {
- unsigned char dat;
- rst=0; //拉低RST
- clk=0; //確保寫數(shù)據(jù)前CLK被拉低
- rst=1; //啟動數(shù)據(jù)傳輸
- Write1302(add); //寫入命令字
- dat=Read1302(); //讀出數(shù)據(jù)
- clk=1; //將時鐘電平置于已知狀態(tài)
- rst=0; //禁止數(shù)據(jù)傳遞
- return dat; //將讀出的數(shù)據(jù)返回
- }
- /*************把要的時間 年月日 都讀出來***************/
- void read_time()
- {
- miao = read_ds1302(read_add[0]); //讀秒
- fen = read_ds1302(read_add[1]); //讀分
- shi = read_ds1302(read_add[2]); //讀時
- ri = read_ds1302(read_add[3]); //讀日
- yue = read_ds1302(read_add[4]); //讀月
- nian = read_ds1302(read_add[5]); //讀年
- week = read_ds1302(read_add[6]); //讀星期
- }
- /*************把要寫的時間 年月日 都寫入ds1302里***************/
- void write_time()
- {
- write_ds1302(0x8e,0x00); //關(guān)閉寫保護(hù)
- write_ds1302(write_add[0],miao); //寫秒
- write_ds1302(write_add[1],fen); //寫分
- write_ds1302(write_add[2],shi); //寫時
- write_ds1302(write_add[3],ri); //寫日
- write_ds1302(write_add[4],yue); //寫月
- write_ds1302(write_add[5],nian); //寫年
- write_ds1302(write_add[6],week); //寫星期
- write_ds1302(0x8e,0x80); //打開寫保護(hù)
- }
- /*************把數(shù)據(jù)保存到ds1302 RAM中**0-31*************/
- void write_ds1302ram(uchar add,uchar dat)
- {
- add <<= 1; //地址是從第二位開始的
- add &= 0xfe; //把最低位清零 是寫的命令
- add |= 0xc0; //地址最高兩位為 1
- write_ds1302(0x8e,0x00);
- write_ds1302(add,dat);
- write_ds1302(0x8e,0x80);
- }
- /**********************設(shè)置ds1302時間函數(shù)**********************/
- void set_ds1302time(uchar num,uchar *shi,uchar dat) //調(diào)時
- {
- if(num == 1)
- {
- *shi+=0x01;
- if((*shi & 0x0f) >= 0x0a)
- *shi = (*shi & 0xf0) + 0x10;
- if(*shi >= dat)
- *shi = 0;
- }
- else
- {
- if(*shi == 0x00)
- *shi = dat;
- if((*shi & 0x0f) == 0x00)
- *shi = (*shi | 0x0a) - 0x10;
- *shi -=0x01 ;
- }
- }
- /*************把數(shù)據(jù)從ds1302 RAM讀出來**0-31*************/
- uchar read_ds1302ram(uchar add)
- {
- add <<= 1; //地址是從第二位開始的
- add |= 0x01; //把最高位置1 是讀命令
- add |= 0xc0; //地址最高兩位為 1
- return(read_ds1302(add));
- }
- /*************初始化ds1302時間***************/
- void init_ds1302()
- {
- uchar i;
- rst = 0; //第一次讀寫數(shù)據(jù)時要把I O口拉低
- clk = 0;
- io = 0;
- i = read_ds1302ram(30);
- if(i != 3)
- {
- i = 3;
- write_ds1302ram(30,i); //4050 4100 3080
- write_ds1302(0x8e,0x00); //關(guān)閉寫保護(hù)
- for(i=0;i<7;i++)
- write_ds1302(write_add[i],init_ds[i]); //把最高位值0 允許ds1302工作
- write_ds1302(0x8e,0x80); //打開保護(hù)
- }
- read_time(); //讀時間
- if(miao >= 0x60)
- {
- write_ds1302(0x8e,0x00); //關(guān)閉寫保護(hù)
- write_ds1302(write_add[0],0x01); //把最高位值0 允許ds1302工作
- write_ds1302(0x8e,0x80); //打開保護(hù)
-
- }
- }
- #endif
復(fù)制代碼 |
|