一. 描述
DS1302时钟芯片是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。 它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。
DS1302芯片包含一个用于存储实时时钟/日历的 31 字节的静态 RAM,可通过简单的串行接口与微处理器通讯,将当前的时钟存于RAM。 DS1302芯片对于少于 31 天的月份月末会自动调整,并会自动对闰年进行校正。 由于有一个 AM/PM 指示器,时钟可以工作在 12 小时制或者 24小时制。
二. 芯片参数
1.芯片特点
2.引脚说明
DS1302采用的是三线接口的双向数据通信接口,RST是片引脚,低电平有效; SCLK是时钟芯片,为通信提供时钟源; I/O为数据输入输出引脚,用于传输及接收数据;
DS1302还采用了双电源供电模式,VCC1 连接到备用电源,在VCC2主电源失效时保持时间和日期数据.
三. 参考电路
DS1302芯片基本电路如上图,其中Y2为32.768k外部晶振,为芯片提供时钟源;P2为备用电池,以保证在主电源掉电后,芯片仍可继续运行;D1为二极管,保证电压的单向导通,防止主电源电压过高烧坏备用电池;R6为上拉电阻,增强信号传输的稳定性。
四. 控制程序
1.时钟数据的读写地址
如上图,为DS1302芯片的时钟数据的读和写的地址,也就是说要实现对芯片控制,就是往这些地址上写入或读出数据。 其中:
读地址为: 0x81(秒), 0x83(分), 0x85(时), 0x87(日), 0x89(月), 0x8b(星期), 0x8d(年);
写地址为: 0x80(秒), 0x82(分), 0x84(时), 0x86(日), 0x88(月), 0x8a(星期), 0x8c(年);
2.控制时序
DS1302控制软件最基本的操作为写函数和读函数,其次就是实现初始化函数。
(1)读时序
/*******************************************************************************
* 函数功能 : 读取一个地址的数据
*******************************************************************************/
uchar Ds1302Read(uchar addr)
{
uchar n,dat,dat1;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置低电平。
_nop_();
RST = 1;//然后将RST(CE)置高电平。
_nop_();
for(n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;//DS1302下降沿时,放置数据
_nop_();
}
_nop_();
for(n=0; n<8; n++)//读取8位数据
{
dat1 = DSIO;//从最低位开始接收
dat = (dat>>1) | (dat1<<7);
SCLK = 1;
_nop_();
SCLK = 0;//DS1302下降沿时,放置数据
_nop_();
}
RST = 0;
_nop_(); //以下为DS1302复位的稳定时间,必须的。
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return dat;
}
(2)写时序
/*******************************************************************************
* 函数功能 : 向DS1302命令(地址+数据)
*******************************************************************************/
void Ds1302Write(uchar addr, uchar dat)
{
uchar n;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置低电平。
_nop_();
RST = 1; //然后将RST(CE)置高电平。
_nop_();
for (n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++)//写入8位数据
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;//传送数据结束
_nop_();
}
(3)初始化
/*******************************************************************************
* 函数功能 : 初始化DS1302.
*******************************************************************************/
void Ds1302Init()
{
uchar n;
Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能
for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80); //打开写保护功能
}
3. 参考示例
实现了DS1302的驱动程序,接下来就可以实现DS1302的报时功能了。
//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;-------//
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};
/*******************************************************************************
* 函数功能 : 读取时钟信息
*******************************************************************************/
void Ds1302ReadTime()
{
uchar n;
for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
{
TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
}
}
void main()
{
LcdInit();
Ds1302Init();
while(1)
{
Ds1302ReadTime(); //读取此时的时间
LcdDisplay(); //显示时间
}
}
全部0条评论
快来发表一下你的评论吧 !