DS1302时钟芯片的电路和程序

本文介绍ds1302时钟芯片的电路和程序。
ds1302是由美国dallas公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,并且具有闰年补偿等多种功能。
1、参考电路
如下参考电路已经过实践验证,可正常工作。
其中,pu151到pu153对应ds1302的sclk,io,rst引脚,需接到微处理器(如单片机)的相关引脚。
第8脚加上3v的后备纽扣电池,时钟在主电路掉电时也可以持续运行。
2、参考程序
实践验证,以下两个程序任意一个都是可以运行的。
2.1参考程序1
//ds1302设置子程序
#include ds1302.h
sbit sclk=p3^3;//ds1302设置
sbit rst=p3^5;
sbit io=p3^4; //ds1302三个管脚定义
unsigned char xdata time[7]={23,1,3,20,5,6,7};//0年 1周 2月 3日 4时 5分 6秒 有符号
unsigned char write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//ds1302写时间寄存器地址
unsigned char read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//读
void write_ds1302_byte(unsigned char dat) //ds1302写字节函数
{
unsigned char i;
for(i=0;i>1;
sclk=1;
}
}
void write_ds1302(unsigned char add,unsigned char dat)
{
rst=0;
nop ();
sclk=0;
nop ();
rst=1;
nop ();
write_ds1302_byte(add);
write_ds1302_byte(dat);//发送地址后立即发送数据,没有停顿
rst=0;
nop ();
sclk=1;
io=1;
}
unsigned char read_ds1302(unsigned char add)
{
unsigned char i,dat=0;
rst=0;
nop ();
sclk=0;
nop ();
rst=1;
nop ();
write_ds1302_byte(add);//发送地址后ds1302立即送出数据
for(i=0;i>1;
sclk=0;
if(io)
dat=dat|0x80;
sclk=1;
}
rst=0;
nop ();
sclk=0;
nop ();
sclk=1;
io=0; //223-3-20,1改为0后可保存数据
return dat;
}
void ds1302_init()
{
unsigned char i,j;
for(i=0;i<7;i++)
{
j=time[i]/10;
time[i]=time[i]%10;
time[i]=time[i]+j*16; //转换为bcd码
}
write_ds1302(0x8e,0x00);//去除写保护
for(i=0;i59) time[5]=59;
if (time[6]>59) time[6]=59;
}
说明:
●如果要读取时间,就调用read_time()子程序,读取的时钟数据存入time[]数组;
●如果要设置时间,就调用ds1302_init()子程序,要设置的时钟数据预先存入time[]数组;
●ds1302_init()子程序不能每次开机运行,只需在修改时间时运行即可。
2.2参考程序2
#include ds1302.h
#define uchar unsigned char
#define uint unsigned int
//ds1302宏定义部分
#define write_second 0x80 //写秒地址
#define write_minute 0x82 //写分地址
#define write_hour 0x84 //写时地址
#define write_date 0x86 //写日地址
#define write_month 0x88 //写月地址
#define write_week 0x8a //写周地址
#define write_year 0x8c //写年地址
#define write_protect 0x8e //写保护
#define read_second 0x81 //读秒地址
#define read_minute 0x83 //读分地址
#define read_hour 0x85 //读时地址
#define read_date 0x87 //读日地址
#define read_month 0x89 //读月地址
#define read_week 0x8b //读周地址
#define read_year 0x8d //读年地址
sbit acc_7 = acc^7; //位寻址寄存器定义
sbit sclk = p3^3; // ds1302时钟信号6脚
sbit dio= p3^4; // ds1302数据信号5脚
sbit ce = p3^5; // ds1302片选7脚
uchar xdata time[7]={23,1,3,2,5,6,7}; //依次存放年月日周时分秒,十进制表示,2023年1月3日周2 5:6:7
//地址、数据发送子程序
void write1302 ( unsigned char addr,dat )
{
unsigned char i,temp; ce=0; //ce 引脚为低,数据传送中止 sclk=0; //清零时钟总线 ce = 1; //ce 引脚为高,逻辑控制有效 //发送地址 for ( i=8; i >0; i-- ) //循环8次移位 { sclk = 0; temp = addr; dio = (bit)(temp&0x01); //每次传输低字节 addr > >= 1; //右移一位 sclk = 1; } //发送数据 for ( i=8; i >0; i-- ) { sclk = 0; temp = dat; dio = (bit)(temp&0x01); //每次传输低字节 dat > >= 1; //右移一位 sclk = 1; } ce = 0;}
//数据读取子程序
unsigned char read1302 ( unsigned char addr )
{
unsigned char i,temp,dat1,dat2; ce=0; sclk=0; ce = 1; //发送地址 for ( i=8; i >0; i-- ) //循环8次移位 { sclk = 0; temp = addr; dio = (bit)(temp&0x01); //每次传输低字节 addr > >= 1; //右移一位 sclk = 1; } //读取数据 for ( i=8; i >0; i-- ) { acc_7=dio; sclk = 1; acc >>=1; sclk = 0; } ce=0; dat1=acc; dat2=dat1/16; //数据进制转换 dat1=dat1%16; //十六进制转十进制 dat1=dat1+dat2*10; return (dat1);}
//初始化 ds1302
void initialds1302(void)
{
//初始化为13年04月24日周3 23时27分56秒 注意,write1302函数第二个参数是16进制,需进行十进制到十六进制转码,如参数里:秒0x56表示56秒,0x12表示12月,0x23表示23时等,以下已转码。 write1302 (write_protect,0x00); //禁止写保护 write1302 (write_second,time[6]/10*16+time[6]%10); //秒位初始化 write1302 (write_minute,time[5]/10*16+time[5]%10); //分钟初始化 write1302 (write_hour,time[4]/10*16+time[4]%10); //时位初始化 write1302 (write_year,time[0]/10*16+time[0]%10); //年位初始化write1302 (write_month,time[1]/10*16+time[1]%10); //月位初始化
write1302 (write_date,time[2]/10*16+time[2]%10); //日位初始化
write1302 (write_week,time[3]/10*16+time[3]%10); //星期位初始化
write1302 (write_protect,0x80); //允许写保护}
//读取年月日周时分秒
void read_time(void)
{
time[0]=read1302(read_year); //取年
time[1]=read1302(read_month); //取月
time[2]=read1302(read_date); //取日
time[3]=read1302(read_week); //取周
time[4]=read1302(read_hour); //取时
time[5]=read1302(read_minute); //取分
time[6]=read1302(read_second); //取
}
//// 运行 read_nyrsfm()子函数读取数组time[]显示即可
说明:
●如果要读取时间,就调用read_time()子程序,读取的时钟数据存入time[]数组;
●如果要设置时间,就调用initialds1302()子程序,要设置的时钟数据预先存入time[]数组。
●initialds1302()子程序不能每次开机运行,只需在修改时间时运行即可。
以上电路和程序已经过实践验证,可正常运行。

实战经验 | 一个 Flash 编程错误标志的探析
显卡上电容的作用及爆浆的原因
新的预训练方法——MASS!MASS预训练几大优势!
磷酸铁锂电池在新能源纯电动车中的应用分析
电池管理电子设备怎样增强电池的安全性
DS1302时钟芯片的电路和程序
怎样用电池为便携式DVD播放器供电
基于机器视觉技术实现在LED光学检测系统的应用解决方案
crt显示器和lcd显示器的区别
二级市场并不认为Xilinx能为AMD带来持续高增长
ARM9芯片适用于超高频读写器的PIE编码以及MILLER2解码的实现方式
原OPPO智能硬件事业部总裁李开新入职得瑞领新
手机中的哪些零部件加工用到了激光加工技术
有哪些好用的在线视频压 缩软件
欢迎参加2023意法半导体NFC研讨会北京、深圳站
我只挑专业的:韶音运动耳机双十一种草指南
小米Note3配置让人略显失望,对标产品应为OPPO R11
虹科方案 | 使用HK-TrueNAS保护关键任务数据-1
万能转换开关的应用场合
AMD不比英特尔差,为什么在笔记本领域仍不受厂商待见