ds1302实时时钟C程序
/*51hei.com会员经典作品已经测试成功/
/**************http://www.51hei.com/ziliao/file/ds1302c.rar 点此链接下载本例的代码*****/
#include < reg52.h> #include
#define uchar unsigned char
sbit T_CLK = P3^4; /*实时时钟时钟线引脚 */ sbit T_IO = P3^3; /*实时时钟数据线引脚 */ sbit T_RST = P3^2; /*实时时钟复位线引脚 */ //sbit OE=P3^6; sbit ACC0=ACC^0; sbit ACC7=ACC^7;
uchar time[8]=\" : : \"; uchar min,hou,day,mon,yea;
void Init1302(void);
void v_W1302(uchar ucAddr, uchar ucDa); uchar uc_R1302(uchar ucAddr); void v_BurstW1302T(uchar *pSecDa); void v_BurstR1302T(uchar *pSecDa); void v_BurstW1302R(uchar *pReDa); void v_BurstR1302R(uchar *pReDa); void v_Set1302(uchar *pSecDa); void v_Get1302(uchar ucCurtime[]); void donetime(void); void bcd_int(uchar i); void bcdtoInt(void);
void SetTime(void);
/******************************************************************** *
* 名称: v_RTInputByte * 说明:
* 功能: 往DS1302写入1Byte数据 * 调用:
* 输入: ucDa 写入的数据 * 返回值: 无
***********************************************************************/ void v_WTInputByte(uchar ucDa) { uchar i; //OE=0; ACC= ucDa; for(i=8; i>0; i--) {
T_IO = ACC0; //*相当于汇编中的 RRC T_CLK = 1; T_CLK = 0; ACC =ACC>> 1; } // OE=1; }
/******************************************************************** *
* 名称: uchar uc_RTOutputByte * 说明:
* 功能: 从DS1302读取1Byte数据 * 调用:
* 输入: * 返回值: ACC
***********************************************************************/ uchar uc_RTOutputByte(void) { uchar i; //OE=0; for(i=8; i>0; i--) {
ACC = ACC>>1; //*相当于汇编中的 RRC ACC7 = T_IO; T_CLK = 1; T_CLK = 0; } //OE=1; return(ACC); }
/******************************************************************** *
* 名称: v_W1302
* 说明: 先写地址,后写命令/数据 * 功能: 往DS1302写入数据 * 调用: v_RTInputByte()
* 输入: ucAddr: DS1302地址, ucDa: 要写的数据 * 返回值: 无
***********************************************************************/ void v_W1302(uchar ucAddr, uchar ucDa) { //OE=0; T_RST = 0;
T_CLK = 0; T_RST = 1;
v_WTInputByte(ucAddr); /* 地址,命令 */ v_WTInputByte(ucDa); /* 写1Byte数据*/ T_CLK = 1; T_RST =0; //OE=1; }
/******************************************************************** *
* 名称: uc_R1302
* 说明: 先写地址,后读命令/数据 * 功能: 读取DS1302某地址的数据
* 调用: v_RTInputByte() , uc_RTOutputByte() * 输入: ucAddr: DS1302地址 * 返回值: ucDa :读取的数据
***********************************************************************/ uchar uc_R1302(uchar ucAddr) {
uchar ucDa; //OE=0; T_RST = 0; T_CLK = 0; T_RST = 1;
v_WTInputByte(ucAddr); /* 地址,命令 */ ucDa = uc_RTOutputByte(); /* 读1Byte数据 */ T_CLK = 1; T_RST =0; // OE=1; return(ucDa);
}
/******************************************************************** *
* 名称: v_BurstW1302T
* 说明: 先写地址,后写数据(时钟多字节方式) * 功能: 往DS1302写入时钟数据(多字节方式) * 调用: v_RTInputByte()
* 输入: pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制 * 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B * 返回值: 无
***********************************************************************/ /*void v_BurstW1302T(uchar *pSecDa) { uchar i;
v_W1302(0x8e,0x00); //* 控制命令,WP=0,写操作? T_RST = 0; T_CLK = 0; T_RST = 1;
v_WTInputByte(0xbe); //* 0xbe:时钟多字节写命令 for (i=8;i>0;i--) //*8Byte = 7Byte 时钟数据 + 1Byte 控制 {
v_WTInputByte(*pSecDa);//* 写1Byte数据 pSecDa++; }
T_CLK = 1; T_RST =0; } */
/******************************************************************** *
* 名称: v_BurstR1302T
* 说明: 先写地址,后读命令/数据(时钟多字节方式) * 功能: 读取DS1302时钟数据
* 调用: v_RTInputByte() , uc_RTOutputByte()
* 输入: pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 * 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B * 返回值: ucDa :读取的数据
***********************************************************************/ /*void v_BurstR1302T(uchar *pSecDa) { uchar i; T_RST = 0; T_CLK = 0; T_RST = 1;
v_WTInputByte(0xbf); //* 0xbf:时钟多字节读命令 for (i=8; i>0; i--) {
*pSecDa = uc_RTOutputByte(); //* 读1Byte数据 pSecDa++; }
T_CLK = 1; T_RST =0; } */
/******************************************************************** *
* 名称: v_BurstW1302R
* 说明: 先写地址,后写数据(寄存器多字节方式) * 功能: 往DS1302寄存器数写入数据(多字节方式) * 调用: v_RTInputByte() * 输入: pReDa: 寄存器数据地址 * 返回值: 无
***********************************************************************/ /*void v_BurstW1302R(uchar *pReDa) { uchar i;
v_W1302(0x8e,0x00); //* 控制命令,WP=0,写操作? T_RST = 0; T_CLK = 0; T_RST = 1;
v_WTInputByte(0xfe); //* 0xbe:时钟多字节写命令 for (i=31;i>0;i--) //*31Byte 寄存器数据 {
v_WTInputByte(*pReDa); //* 写1Byte数据 pReDa++; }
T_CLK = 1; T_RST =0; } */
/******************************************************************** *
* 名称: uc_BurstR1302R
* 说明: 先写地址,后读命令/数据(寄存器多字节方式) * 功能: 读取DS1302寄存器数据
* 调用: v_RTInputByte() , uc_RTOutputByte() * 输入: pReDa: 寄存器数据地址 * 返回值: 无
***********************************************************************/ /*void v_BurstR1302R(uchar *pReDa) { uchar i; T_RST = 0;
T_CLK = 0; T_RST = 1;
v_WTInputByte(0xff); //* 0xbf:时钟多字节读命令 for (i=31; i>0; i--) //*31Byte 寄存器数据 {
*pReDa = uc_RTOutputByte(); //* 读1Byte数据 pReDa++; }
T_CLK = 1; T_RST =0; } */
/******************************************************************** *
* 名称: v_Set1302 * 说明:
* 功能: 设置初始时间 * 调用: v_W1302()
* 输入: pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年 * 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B * 返回值: 无
***********************************************************************/ /*void v_Set1302(uchar *pSecDa) { uchar i;
uchar ucAddr = 0x80;
v_W1302(0x8e,0x00); // 控制命令,WP=0,写操作? for(i =7;i>0;i--) {
v_W1302(ucAddr,*pSecDa); //秒 分 时 日 月 星期 年 pSecDa++;
ucAddr +=2; }
v_W1302(0x8e,0x80); // 控制命令,WP=1,写保护? } */
/******************************************************************** *
* 名称: v_Get1302 * 说明:
* 功能: 读取DS1302当前时间 * 调用: uc_R1302()
* 输入: ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年 * 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B * 返回值: 无
***********************************************************************/ /*void v_Get1302(uchar ucCurtime[]) { uchar i;
uchar ucAddr = 0x81; for (i=0;i<7;i++) {
ucCurtime[i] = uc_R1302(ucAddr);//*格式为: 秒 分 时 日 月 星期 年 ucAddr += 2; } } */
/*********************************************************************** * 名称: Init1302 * 说明:
* 功能: 初始化DS1302 * 调用: * 输入:
* 返回值: 无
*****************************************************************************/ void Init1302(void) {
v_W1302(0x8e,0x00); //控制写入WP=0 v_W1302(0x90,0xa5); v_W1302(0x80,0x00); //秒 v_W1302(0x82,0x59); //分 v_W1302(0x84,0x10); //时 v_W1302(0x86,0x01); //日 v_W1302(0x88,0x08); //月 v_W1302(0x8a,0x03); //星期 v_W1302(0x8c,0x07); //年 */ v_W1302(0x8e,0x80); }
/************************************************************************** * 名称: donetime * 说明:
* 功能: 时间处理 * 调用: * 输入: * 返回值: 无
*****************************************************************************/ void donetime(void) { uchar d;
d=uc_R1302(0x81); time[6]=d/16+48; time[7]=d%16+48; d=uc_R1302(0x83);
time[3]=d/16+48; time[4]=d%16+48; d=uc_R1302(0x85); time[0]=d/16+48; time[1]=d%16+48; //bcd_int(d); }
//
/*void bcd_int(uchar i) { uchar j;
time[0]=(i&0x0f)+48; j=i>>4;
time[1]=(j&0x0f)+48; } */ //
/*void bcdtoInt(void) { uchar i; for(i=0;i<7;i++) bcd_int(ucCurtm[i]); } */ //
void SetTime(void) {
v_W1302(0x8e,0x00); v_W1302(0x80,0x80); v_W1302(0x82,min); v_W1302(0x84,hou);
v_W1302(0x86,day); v_W1302(0x88,mon); v_W1302(0x8c,yea); v_W1302(0x80,0x00); v_W1302(0x8e,0x80); }
对DS1302操作程序如下
#pragma small #include /************************************引脚连接图*****************************************/ sbit ds1302_clk=P1^0; sbit ds1302_dat=P1^1; sbit ds1302_rst=P1^2; sbit ACC_0 = ACC^0; sbit ACC_1 = ACC^1; sbit ACC_2 = ACC^2; sbit ACC_3 = ACC^3; sbit ACC_4 = ACC^4; sbit ACC_5 = ACC^5; sbit ACC_6 = ACC^6; sbit ACC_7 = ACC^7; /*************************************函数说明******************************************/ void Read(void); //写DS1302操作 void Write(void); //读DS1302操作 uchar ReadRam_Byte(uchar address); //从Ram中读出一个字节 uchar ReadRTC_Byte(uchar address); //从DS1302中读出一个字节 uchar WriteRam_Byte(uchar address,uchar number); //向Ram中写入一个字节 uchar WriteRTC_Byte(uchar address,uchar number); //向DS1302中写入一个字节 void ReadRam(uchar data * buffer,uchar size); //从Ram中读出多个字节 void ReadRTC(uchar data * buffer,uchar size); //从DS1302中读出多个字节 void WriteRam(uchar data * buffer,uchar size); //向Ram中写入多个字节 void WriteRTC(uchar data * buffer,uchar size); //向DS1302中写入多个字节 uchar ReadSec(void); //从DS1302中读出秒字节 uchar ReadMin(void); //从DS1302中读出分字节 uchar ReadHr(void); //从DS1302中读出时字节 uchar ReadDay(void); //从DS1302中读出日字节 uchar ReadMonth(void); //从DS1302中读出月字节 uchar ReadWeek(void); //从DS1302中读出星期字节 uchar ReadYear(void); //从DS1302中读出年字节 void WriteSec(uchar number); //向DS1302中写入秒字节 void WriteMin(uchar number); //向DS1302中写入分字节 void WriteHr(uchar number); //向DS1302中写入时字节 void WriteDay(uchar number); //向DS1302中写入日字节 void WriteMonth(uchar number); //向DS1302中写入月字节 void WriteWeek(uchar number); //向DS1302中写入星期字节 void WriteYear(uchar number); //向DS1302中写入年字节 void WriteControl(uchar number); //向慢速充电控制寄存器写入控制字节 void EnableWP(void); //禁止写保护 void DisableWP(void); //允许写保护 void Write(void) //写DS1302操作 { ds1302_dat = ACC_0; //写DS1302 ds1302_clk = 1; //时钟上升沿,发送数据有效 ds1302_clk = 0; //清零时钟总线 ds1302_dat = ACC_1; ds1302_clk = 1; ds1302_clk = 0; ds1302_dat = ACC_2; ds1302_clk = 1; ds1302_clk = 0; ds1302_dat = ACC_3; ds1302_clk = 1; ds1302_clk = 0; ds1302_dat = ACC_4; ds1302_clk = 1; ds1302_clk = 0; ds1302_dat = ACC_5; ds1302_clk = 1; ds1302_clk = 0; ds1302_dat = ACC_6; ds1302_clk = 1; ds1302_clk = 0; ds1302_dat = ACC_7; ds1302_clk = 1; ds1302_clk = 0; } void Read(void) //读DS1302操作 { ACC_0 = ds1302_dat; //读取DS1302数据 ds1302_clk = 1; //时钟上升沿,发送数据有效 ds1302_clk = 0; //清零时钟总线 ACC_1 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_2 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_3 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_4 = ds1302_dat; ds1302_clk = 1;ds1302_clk = 0; ACC_5 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_6 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_7 = ds1302_dat; ds1302_rst = 0; ds1302_clk = 1; } uchar ReadRam_Byte(uchar address) //从RAM中读出一个字节 { ds1302_rst = 0; //复位引脚为低电平,所有数据传送中止 ds1302_clk = 0; //清零时钟总线 ds1302_rst = 1; //复位引脚为高电平,逻辑控制有效 ACC = address; Write(); //写DS1302操作 ds1302_dat = 1; Read(); //读DS1302操作 return ACC; } uchar ReadRTC_Byte(uchar address) //从DS1302中读出一个字节 { ds1302_rst = 0; //复位引脚为低电平,所有数据传送中止 ds1302_clk = 0; //清零时钟总线 ds1302_rst = 1; //复位引脚为高电平,逻辑控制有效 ACC = address; Write(); //对DS1302写命令字和地址 ds1302_dat = 1; Read(); //读DS1302操作 return ACC; //返回读取的数据 } uchar WriteRam_Byte(uchar address,uchar number) //向RAM中写入一个字节 { ds1302_clk = 0; ds1302_rst = 0;ds1302_rst = 1; ACC = address; Write(); //对DS1302写命令字和地址 ACC = number; Write(); //对DS1302写命令字和数据 ds1302_rst = 0; ds1302_clk = 1; return ACC; } uchar WriteRTC_Byte(uchar address,uchar number) //向DS1302中写入一个字节 { ds1302_clk = 0; ds1302_rst = 0;ds1302_rst = 1; ACC = address; ACC |= 0x80; Write(); //对DS1302写命令字和地址 ACC = number; Write(); //对DS1302写命令字和数据 ds1302_rst = 0; ds1302_clk = 1; return ACC; } void ReadRam(uchar data * buffer,uchar size) //从RAM中读出多个字节 { register uchar a,b; ds1302_clk = 0; ds1302_rst = 0; ds1302_rst = 1; ACC = 0xff; //命令字为FFH Write(); //对DS1302写命令字和地址 ds1302_dat = 1; for(a=0;a ds1302_clk = 1; ds1302_clk = 0; ACC_1 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_2 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_3 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_4 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_5 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_6 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_7 = ds1302_dat; b = ACC; *(buffer+a)=b; ds1302_clk = 1; ds1302_clk = 0; } ds1302_rst = 0; ds1302_clk = 1; } void ReadRTC(uchar data * buffer,uchar size) //从DS1302中读出多个字节 { register uchar a,b; ds1302_clk = 0; ds1302_rst = 0; ds1302_rst = 1; ACC = 0xbf; //命令字为BFH Write(); //对DS1302写命令字和地址 ds1302_dat = 1; for(a=0;a ds1302_clk = 1; ds1302_clk = 0; ACC_1 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_2 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_3 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_4 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_5 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_6 = ds1302_dat; ds1302_clk = 1; ds1302_clk = 0; ACC_7 = ds1302_dat; b = ACC; *(buffer+a)=b; ds1302_clk = 1; ds1302_clk = 0; } ds1302_rst = 0; ds1302_clk = 1; } void WriteRam(uchar data * buffer,uchar size) //向RAM中写入多个字节 { register uchar a; ds1302_clk = 0; ds1302_rst = 0; ds1302_rst = 1; ACC = 0xfe; //命令字为FE Write(); //对DS1302写命令字和地址 for(a=0;a ds1302_rst = 0; ds1302_clk = 1; } void WriteRTC(uchar data * buffer,uchar size) //向DS1302中写入多个字节 {//注意:连续写DS1302只能是8个字节一起写 register uchar a; ds1302_clk = 0; ds1302_rst = 0; ds1302_rst = 1; ACC = 0xbe; //命令字为BEH Write(); //对DS1302写命令字和地址 for(a=0;a ACC = *(buffer+a); Write(); //对DS1302写数据 } ds1302_rst = 0; ds1302_clk = 1; } uchar ReadSec(void) //从DS1302中读出秒字节 { return ReadRTC_Byte(0x81); } uchar ReadMin(void) //从DS1302中读出分字节 { return ReadRTC_Byte(0x83); } uchar ReadHr(void) //从DS1302中读出时字节 { return ReadRTC_Byte(0x85); } uchar ReadDay(void) //从DS1302中读出日字节 { return ReadRTC_Byte(0x87); } uchar ReadMonth(void) //从DS1302中读出月字节 { return ReadRTC_Byte(0x89); } uchar ReadWeek(void) //从DS1302中读出星期字节 { return ReadRTC_Byte(0x8B); } uchar ReadYear(void) //从DS1302中读出年字节 { return ReadRTC_Byte(0x8D); } void WriteSec(uchar number) //向DS1302中写入秒字节 { WriteRTC_Byte(0x80,number); } void WriteMin(uchar number) //向DS1302中写入分字节 { WriteRTC_Byte(0x82,number); } void WriteHr(uchar number) //向DS1302中写入时字节 { WriteRTC_Byte(0x84,number); } void WriteDay(uchar number) //向DS1302中写入日字节 { WriteRTC_Byte(0x86,number); } void WriteMonth(uchar number) //向DS1302中写入月字节 { WriteRTC_Byte(0x88,number); } void WriteWeek(uchar number) //向DS1302中写入星期字节 { WriteRTC_Byte(0x8A,number); } void WriteYear(uchar number) //向DS1302中写入年字节 { WriteRTC_Byte(0x8C,number); } void WriteControl(uchar number) //向慢速充电控制寄存器写入控制字节 { WriteRTC_Byte(0x90,number); } void DisableWP(void) //禁止写保护 { WriteRTC_Byte(0x8E,0); } void EnableWP(void) //允许写保护 { WriteRTC_Byte(0x8E,0x80); } void main(void) //主程序 { uchar sec,min,hr,day,month,week,year; uchar data buffer1[32] = {32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; uchar data buffer2[8] = {45,45,15,13,3,2,01,0}; ReadRTC(buffer2,8); DisableWP(); //禁止写保护 WriteControl(0xaa); //向慢速充电控制寄存器写入控制字节 WriteRam(buffer1,31); //写DS1302RAM WriteRTC(buffer2,8); //写DS1302时钟 EnableWP(); //允许写保护 ReadRam(buffer1,31); //读DS1302RAM ReadRTC(buffer2,8); //读DS1302时钟 sec = ReadSec(); //读秒 min = ReadMin(); //读分 hr = ReadHr(); //读小时 day = ReadDay(); //读日 month = ReadMonth(); //读月 week = ReadWeek(); //读星期 year = ReadYear(); //读年 ACC = 0; } 因篇幅问题不能全部显示,请点此查看更多更全内容