|
- #include <iom16v.h>
- #include <macros.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define SCK_CLR PORTC&=~BIT(0)
- //拉低時(shí)鐘線
- #define SCK_SET PORTC|=BIT(0)
- //拉高時(shí)鐘線
- #define SCK_OUT DDRC|=BIT(0)
- #define RST_CLR PORTC&=~BIT(2)
- //拉低RST線 復(fù)位線
- #define RST_SET PORTC|=BIT(2)
- //拉高RST線
- #define RST_OUT DDRC|=BIT(2)
- //把RST設(shè)為輸出
- #define IO_CLR PORTC&=~BIT(1)
- //拉低IO線 數(shù)據(jù)線
- #define IO_SET PORTC|=BIT(1)
- //拉高IO線
- #define IO_IN DDRC&=~BIT(1)
- //把IO設(shè)為輸入
- #define IO_RD PINC&BIT(1)
- //從IO中讀數(shù)據(jù)
- #define IO_OUT DDRC|=BIT(1)
- //把IO設(shè)為輸出
- uchar const write_add[]={0x80,0x82,0x84}; //寫地址,0x86,0x88,0x8c,0x8a
- //uchar code read_add[] ={0x81,0x83,0x85}; //讀地址,0x87,0x89,0x8d,0x8b
- uchar const init_ds[] ={0x55,0x17,0x15,0x01,0x01,0x13,0x13};
- uchar miao,fen,shi;//,ri,yue,week,nian=0x20;
- uchar nfen=0;
- uchar nshi=0;
- /*************寫一個(gè)數(shù)據(jù)到對(duì)應(yīng)的地址里***************/
- void write_ds1302(uchar add,uchar dat)
- {
- uchar i;
- RST_SET;
- IO_OUT; //把復(fù)位線拉高
- for(i=0;i<8;i++)
- { //低位在前
- SCK_CLR; //時(shí)鐘線拿低開始寫數(shù)據(jù)
- if(add&0x01)
- {
- IO_SET;
- }
- else
- {
- IO_CLR;
- } //把地址右移一位
- SCK_SET; //時(shí)鐘線拿高
- add=add>>1;
- }
- for(i=0;i<8;i++)
- {
- SCK_CLR; //時(shí)鐘線拿低開始讀數(shù)據(jù)
- if(dat&0x01)
- {
- IO_SET;
- }
- else
- {
- IO_CLR;
- } //把數(shù)據(jù)右移一位
- SCK_SET; //時(shí)鐘線拿高
- dat=dat>>1;
- }
- RST_CLR; //復(fù)位線合低
- SCK_CLR;
- IO_CLR;
- }
- /*************從對(duì)應(yīng)的地址讀一個(gè)數(shù)據(jù)出來***************/
- uchar read_ds1302(uchar add)
- {
- uchar value,i;
- RST_SET;
- IO_IN; //把復(fù)位線拿高
- for(i=0;i<8;i++)
- { //低位在前
- SCK_CLR; //時(shí)鐘線拿低開始寫數(shù)據(jù)
- if(add&0x01)
- {
- IO_SET;
- }
- else
- {
- IO_CLR;
- }
- SCK_SET; //時(shí)鐘線拿高
- add=add>>1; //把地址右移一位
- }
- for(i=0;i<8;i++)
- {
- SCK_CLR; //時(shí)鐘線拿低開始讀數(shù)據(jù)
- value >>= 1;
- if(IO_RD)
- value |= 0x80;
- SCK_SET; //時(shí)鐘線拿高
- }
- RST_CLR; //復(fù)位線合低
- SCK_CLR;
- IO_CLR;
- return value; //返回讀出來的數(shù)據(jù)
- }
- /*************把要的時(shí)間年月日都讀出來***************/
- void read_time()
- {
- miao = read_ds1302(0x81); //讀秒
- fen = read_ds1302(0x83); //讀分
- shi = read_ds1302(0x85); //讀時(shí)
- // ri = read_ds1302(read_add[3]); //讀日
- // yue = read_ds1302(read_add[4]); //讀月
- // nian = read_ds1302(read_add[5]); //讀年
- // week = read_ds1302(read_add[6]); //讀星期
- }
- /*************把要寫的時(shí)間年月日都寫入ds1302里***************/
- void write_time()
- {
- write_ds1302(0x8e,0x00); //打開寫保護(hù)
- // write_ds1302(write_add[0],miao); //寫秒
- write_ds1302(0x82,fen); //寫分
- write_ds1302(0x84,shi); //寫時(shí)
- // 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(0xc2,nshi); //寫鬧時(shí)
- write_ds1302(0xc4,nfen); //寫鬧分
- write_ds1302(0x8e,0x80); //關(guān)閉寫保護(hù)
- }
- void read_nao()
- {
- nshi = read_ds1302(0xc3); //讀鬧鐘時(shí)
- nfen = read_ds1302(0xc5); //讀鬧鐘分
- }
- /*************把數(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ù)據(jù)從ds1302 RAM讀出來**0-31***********/
- uchar read_ds1302ram(uchar add)
- {
- add <<= 1; //地址是從第二位開始的
- add |= 0x01; //把最低位清零 是讀的命令
- add |= 0xc0; //地址最高兩位為1
- return(read_ds1302(add));
- }
- /*************初始化ds1302時(shí)間***************/
- void init_ds1302()
- {
- uchar i;
- RST_CLR; //復(fù)位線合低
- SCK_CLR;
- IO_CLR;
- i = read_ds1302ram(30);
- if(i != 3)
- {
- i = 3;
- write_ds1302ram(30,i);
- write_ds1302(0x8e,0x00); //打開保護(hù)
- for(i=0;i<3;i++)
- write_ds1302(write_add[i],init_ds[i]); //把最高位值0 允許ds1302工作
- write_ds1302(0x8e,0x80); //關(guān)寫保護(hù)
- }
- }
- void init_ds1302_io()
- {
- RST_CLR; //第一次讀寫數(shù)據(jù)是要把io位拿低
- SCK_CLR;
- IO_CLR;
- }
復(fù)制代碼 |
|