|
#i nclude <reg52.h> #i nclude <intrins.h> #define uchar unsigned char sbit SDA=P3^4; sbit SCL=P3^5; sbit P10=P1^0; uchar g8563_Store[4]; /*時間交換區(qū),全局變量聲明*/ uchar code c8563_Store[4]={0x00,0x59,0x07,0x01}; /*寫入時間初值:星期一 07:59:00*/
/******************************************** 內(nèi)部函數(shù),延時1 ********************************************/ void Delay() { // {P10=1;_nop_();P10=0;} _nop_(); _nop_(); /*根據(jù)晶振頻率制定延時時間*/ } /******************************************** 內(nèi)部函數(shù),I2C開始 ********************************************/ void Start() { EA=0; SDA=1; SCL=1; Delay(); SDA=0; Delay(); SCL=0; } /******************************************** 內(nèi)部函數(shù),I2C結(jié)束 ********************************************/ void Stop() { SDA=0; SCL=0; Delay(); SCL=1; Delay(); SDA=1; Delay(); EA=1; } /******************************************** 內(nèi)部函數(shù),輸出ACK ,每個字節(jié)傳輸完成,輸出ack=0,結(jié)束讀書據(jù),ack=1; ********************************************/ void WriteACK(uchar ack) { SDA=ack; Delay(); SCL=1; Delay(); SCL=0; } /******************************************** 內(nèi)部函數(shù),等待ACK ********************************************/ void WaitACK() { uchar errtime=20; SDA=1; Delay(); /*讀ACK*/ SCL=1; Delay(); while(SDA) { errtime--; if(!errtime) Stop(); } SCL=0; Delay(); } /******************************************** 內(nèi)部函數(shù).輸出數(shù)據(jù)字節(jié) 入口:B=數(shù)據(jù) ********************************************/ void writebyte(uchar wdata) { uchar i; for(i=0;i<8;i++) { if(wdata&0x80) SDA=1; else SDA=0; wdata<<=1; SCL=1; Delay(); SCL=0; } WaitACK(); //I2C器件或通訊出錯,將會退出I2C通訊 } /******************************************** 內(nèi)部函數(shù).輸入數(shù)據(jù) 出口:B ********************************************/ uchar Readbyte() { uchar i,bytedata; SDA=1; for(i=0;i<8;i++) { SCL=1; bytedata<<=1; bytedata|=SDA; SCL=0; Delay(); } return(bytedata); } /******************************************** 輸出數(shù)據(jù)->pcf8563 ********************************************/ void writeData(uchar address,uchar mdata) { Start(); writebyte(0xa2); /*寫命令*/ writebyte(address); /*寫地址*/ writebyte(mdata); /*寫數(shù)據(jù)*/ Stop(); } /******************************************** 輸入數(shù)據(jù)<-pcf8563 ********************************************/ uchar ReadData(uchar address) /*單字節(jié)*/ { uchar rdata; Start(); writebyte(0xa2); /*寫命令*/ writebyte(address); /*寫地址*/ Start(); writebyte(0xa3); /*讀命令*/ rdata=Readbyte(); WriteACK(1); Stop(); return(rdata); } void ReadData1(uchar address,uchar count,uchar * buff) /*多字節(jié)*/ { uchar i; Start(); writebyte(0xa2); /*寫命令*/ writebyte(address); /*寫地址*/ Start(); writebyte(0xa3); /*讀命令*/ for(i=0;i<count;i++) { buff[i]=Readbyte(); if(i<count-1) WriteACK(0); } WriteACK(1); Stop(); } /******************************************** 內(nèi)部函數(shù),讀入時間到內(nèi)部緩沖區(qū) ********************************************/ void P8563_Read() { uchar time[7]; ReadData1(0x02,0x07,time); g8563_Store[0]=time[0]&0x7f; /*秒*/ g8563_Store[1]=time[1]&0x7f; /*分*/ g8563_Store[2]=time[2]&0x3f; /*小時*/ g8563_Store[3]=time[4]&0x07; /*星期*/ } /******************************************** 讀入時間到內(nèi)部緩沖區(qū)----外部調(diào)用 ********************************************/ void P8563_gettime() { P8563_Read(); if(g8563_Store[0]==0) P8563_Read(); /*如果為秒=0,為防止時間變化,再讀一次*/ } /******************************************** 寫時間修改值 ********************************************/ void P8563_settime() { uchar i; for(i=2;i<=4;i++) { writeData(i,g8563_Store[i-2]); } writeData(6,g8563_Store[3]); } /******************************************** P8563的初始化-----外部調(diào)用 ********************************************/ void P8563_init() { uchar i; if((ReadData(0xa)&0x3f)!=0x8) /*檢查是否第一次啟動,是則初始化時間*/ { for(i=0;i<=3;i++) g8563_Store[i]=c8563_Store[i]; /*初始化時間*/ P8563_settime(); writeData(0x0,0x00); writeData(0xa,0x8); /*8:00報警*/ writeData(0x1,0x12); /*報警有效*/ writeData(0xd,0xf0); } }
|