高精度实时时钟-SD2001驱动程序 /*------------------------------------------------------------------------------------------ [文件名] Sd.c [功能] 对sd2001时钟进行时实读写,并对其内部的ram进行操作 [版本] 1.4b [作者] 鞠春阳 [最后修改时间] 2003年5月12日 [版权所有] www.mcuzb.com [sd2001资料] 请到www.mcuzb.com下载 ===========================================================================================*/ //用户调用函数 //void initSD2001Time(unsigned char year,unsigned char month,unsigned char day,unsigned char date,unsigned char hour,unsigned char minute,unsigned char second) //时钟初始化函数 年,月,日,星期,小时,分钟,秒 //ReadSD2001_Time() //读时间函数 结果分别存放在全局变量 SD2001_year SD2001_month ;SD2001_day ;SD2001_date ;SD2001_hour ;SD2001_minute;SD2001_second;中
#include "reg51.h" #include "intrins.h" sbit SD2001_SDA= P2^1; sbit SD2001_SCL= P2^3; sbit SCLE = P1^5; sbit SDAE = P1^4;#define SomeNOP(); { _nop_(); _nop_(); _nop_();_nop_(); } unsigned char SD2001_year ; unsigned char SD2001_month ; unsigned char SD2001_day ; unsigned char SD2001_date ; unsigned char SD2001_hour ; unsigned char SD2001_minute; unsigned char SD2001_second; unsigned char LishiSRAM[7]; /*-------------------------------------------------------------------------------- 调用方式:void SD2001_I2CStart(void) ﹫2001/07/0 4 函数说明:私有函数,I2C专用 ---------------------------------------------------------------------------------*/ void SD2001_I2CStart(void) { EA=0; SD2001_SCL=0; SD2001_SDA=1; SomeNOP(); SD2001_SCL=1; SomeNOP();//INI SD2001_SDA=0; SomeNOP(); //START SD2001_SCL=0; }
void I2CStartRAM(void) { EA=0; SCLE=0; SDAE=1; SomeNOP(); SCLE=1; SomeNOP();//INI SDAE=0; SomeNOP(); //START SCLE=0; } /*-------------------------------------------------------------------------------- 调用方式:void SD2001_I2CStop(void) ﹫2001/07/0 4 函数说明:私有函数,I2C专用 ---------------------------------------------------------------------------------*/ void SD2001_I2CStop(void) { SD2001_SDA=0; SD2001_SCL=0; SomeNOP(); //INI SD2001_SCL=1; SomeNOP(); SD2001_SDA=1; SomeNOP();//STOP SD2001_SCL=0; EA=1; }
void I2CStopRAM(void) { SDAE=0; SCLE=0; SomeNOP(); //INI SCLE=1; SomeNOP(); SDAE=1; SomeNOP();//STOP SCLE=0; EA=1; } /*-------------------------------------------------------------------------------- 调用方式:void I2CSend(unsigned char ch) ﹫2001/07/0 5 函数说明:私有函数,I2C专用 MSB ---------------------------------------------------------------------------------*/ void SD2001_I2CSendByte(unsigned char ch) { unsigned char i=8; while(i--) { SD2001_SCL=0;_nop_(); SD2001_SDA=(bit)(ch&0x80); ch<<=1; SomeNOP(); SD2001_SCL=1; SomeNOP(); } SD2001_SCL=0; // WaitAck(); } /*-------------------------------------------------------------------------------- 调用方式:void I2CSend(unsigned char ch) ﹫2001/07/0 5 函数说明:私有函数,I2C专用 LSB ---------------------------------------------------------------------------------*/ void SD2001_I2CSendByte1(unsigned char ch) { unsigned char i=8; while(i--) { SD2001_SCL=0;_nop_(); SD2001_SDA=(bit)(ch & 0x01); ch>>=1; SomeNOP(); SD2001_SCL=1; SomeNOP(); } SD2001_SCL=0; //WaitAck(); } //ACK bitout() { SD2001_SDA=0; SD2001_SCL=0; SD2001_SDA=0; SomeNOP(); SD2001_SCL=1; SomeNOP(); SD2001_SCL=0; } //接受时钟的1位 bit bitin() { bit temp; SD2001_SDA=1; SD2001_SCL=0; SomeNOP(); temp=SD2001_SDA; SomeNOP(); SD2001_SCL=1; SomeNOP(); SD2001_SCL=0; return(temp); } //接受时钟的1个字节 unsigned char rx() { unsigned char i=8; unsigned char dat=0; while(i--) { dat>>=1; if(bitin()) dat=dat|0x80; } return(dat); } /*-------------SRAM-------------*/ SRAMACK() { SCLE=0; SomeNOP(); //ACK SDAE=0; SomeNOP(); SCLE=1; SomeNOP(); SCLE=0; SomeNOP(); } void SRAMSent(unsigned char ch) //发送一个字节给RAM { unsigned char i=8; while(i--) { SCLE=0;_nop_(); SDAE=(bit)(ch&0x80); ch<<=1; SomeNOP(); SCLE=1; SomeNOP(); SCLE=0; } SDAE=1; SCLE=0; SomeNOP(); //ACK SCLE=1; SomeNOP(); //ACK while(SDAE==1){} //ACK SCLE=0; } SRAMRX() //接收一个字节从RAM { unsigned char i=8,dat=0; SCLE=0;SomeNOP(); SDAE=1;SomeNOP(); while(i--) { SCLE=1;SomeNOP(); dat<<=1; dat|=SDAE; SCLE=0; } return(dat); } /*==============================*/ //改时钟 void initSD2001Time(unsigned char year,unsigned char month,unsigned char day,unsigned char date,unsigned char hour,unsigned char minute,unsigned char second) { SD2001_I2CStart(); SD2001_I2CSendByte(0x64); //从年开始写 bitout();
SD2001_I2CSendByte1(year); //写入年 bitout(); SD2001_I2CSendByte1(month); bitout(); SD2001_I2CSendByte1(day); bitout(); SD2001_I2CSendByte1(date); bitout(); SD2001_I2CSendByte1(hour); bitout(); SD2001_I2CSendByte1(minute); bitout(); SD2001_I2CSendByte1(second); bitout(); SD2001_I2CStop(); }
//读时间 ReadSD2001_Time() { unsigned char time[8]=0,i; SD2001_I2CStart(); SD2001_I2CSendByte(0x65); //从年开始读 bitout(); i=8; while(i--) { time[i]=rx(); bitout(); } SD2001_I2CStop(); SD2001_year =time[7]; SD2001_month =time[6]; SD2001_day =time[5]; SD2001_date =time[4]; SD2001_hour =time[3]&0x7F; SD2001_minute=time[2]; SD2001_second=time[1]; } //时钟初始化 InitSD2001() { SD2001_I2CStart(); SD2001_I2CSendByte(0x62);//写状态寄存器 bitout(); SD2001_I2CSendByte1(0xC2);//Power 12/24 INT1AE INT2AE INT1ME INT2ME INT1FE INT2FE // 1 1 0 0 0 0 1 0 SD2001_I2CStop(); }
//向ram写入数据 SaveToSRAM(unsigned int Address,unsigned char SRAM_Dat) { unsigned char AddrH,AddrL; AddrL=Address; AddrH=Address>>8; I2CStartRAM(); SRAMSent(0xA0); //送关键字 SRAMSent(AddrH); //送高地址 已经含ACK SRAMSent(AddrL); //送低地址 SRAMSent(SRAM_Dat); I2CStopRAM(); }//从ram中读取数据 LoadFromSRAM(unsigned int Address) { unsigned char AddrH,AddrL,Dat; AddrL=Address; AddrH=Address>>8; I2CStartRAM(); SRAMSent(0xA0); //送关键字 SRAMSent(AddrH); //送高地址 已经含ACK SRAMSent(AddrL); //送低地址 I2CStartRAM(); SRAMSent(0xA1); Dat=SRAMRX(); I2CStopRAM(); return(Dat); } //////////////////////////////////////// main() { unsigned char a; InitSD2001(); //initSD2001Time(0x03,0x01,0x20,0x01,0x15,0x50,0x00);//对表 ReadSD2001_Time(); SaveToSRAM(5,20); a=LoadFromSRAM(5);
while(1) { ReadSD2001_Time(); _nop_(); } }