我们有驱动的情况下,DS1302芯片操作。我们只要看这张表就可以操作了。
如图所示,时钟日历包含在 7 个读/写寄存器内,读/写寄存器中的数据是二——十进制的 BCD 码。秒寄存器的 BIT7 定义为时间暂停位,当 BIT1 为 1 时,时钟振荡器停止工作,DS1302 进入低功耗模式,电源消耗小于 100 微安,当 BIT1 为 0 时,时钟振荡器启动,DS1302 正常工作。小时寄存器的 BIT7 定义为 12 或 24 小时工作模式选择位,当 BIT7 为高时,为 12 小时工作模式,此时 BIT5 为 AM/PM 位,低电平标示 AM,高电平标示PM,在 24 小时模式下,BIT5
为第二个 10 小时位标示(20~23 时)。写保护寄存器的 BIT7:WP 是写保护位,工作时,出 WP 外的其他位都置为0,对时钟/日历寄存器或 RAM 进行写操作之前,WP 必须为 0,当 WP 为高电平的时候,不能对任何时钟/日历寄存器或 RAM 进行写操作。
#include "reg52.h"
#include "ds1302.h"
#define uchar unsigned char;
#define uint unsigned int;
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
uchar dsbuff[]={10,10,10,10,10,10,10,10};
uchar dscom=0;
uchar s_time[7]={0x28,0x23,0x20,0x05,0x03,0x04,0x17};//设置时间数组
uchar g_time[7]={0}; //保存时间数组
void dstime_nyr();
void dstime_sfm();
void get_time();
void delay(int n)
{
char z=110;
while(n--)
for(z=0;z<110;z++);
}
void init_smg()
{
TMOD|=0x01;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
EA=1;
ET0=1;
TR0=1;
}
void dsplay()
{
P2=(P2&0x1f)|0xe0;
P0=0xff;
P2&=0x1f;
P2=(P2&0x1f)|0xc0;
P0=1<<dscom;
P2&=0x1f;
P2=(P2&0x1f)|0xe0;
P0=tab[dsbuff[dscom]];
P2&=0x1f;
if(++dscom==8)dscom=0;
}
void smg_time()interrupt 1
{
static unsigned int n1=0;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
if(n1<4000) //显示8秒时间
dstime_sfm();
else dstime_nyr();
if(++n1==5000)n1=0; //显示2秒日期
dsplay();
}
void set_time() //设置时间
{
char i=0;
char adr=0x80; //写地址
Ds1302_Single_Byte_Write(0x8e,0x00); //写保护可写
for(i=0;i<7;i++)
Ds1302_Single_Byte_Write(adr+i*2,s_time[i]);
Ds1302_Single_Byte_Write(0x8e,0x80); //写保护不可写
}
void get_time() //获取时间
{
char i=0;
for(i=0;i<7;i++)
{
g_time[i]=Ds1302_Single_Byte_Read(0x81+i*2);
delay(30);
}
}
void dstime_sfm() //显示时间
{
//BCD转码
dsbuff[6]=(g_time[0]&0x70)>>4;//秒十位
dsbuff[7]=g_time[0]&0x0f; //秒各位
dsbuff[5]=11; //-
dsbuff[3]=(g_time[1]&0x70)>>4;//分十位
dsbuff[4]=g_time[1]&0x0f; //分各位
dsbuff[2]=11; //-
dsbuff[0]=(g_time[2]&0x30)>>4;//时十位
dsbuff[1]=g_time[2]&0x0f; //时各位
}
void dstime_nyr() //显示年月日
{
//BCD转码
dsbuff[6]=(g_time[3]&0x30)>>4;//日十位
dsbuff[7]=g_time[3]&0x0f; //日各位
dsbuff[5]=11; //-
dsbuff[3]=(g_time[4]&0x10)>>4;//月十位
dsbuff[4]=g_time[4]&0x0f; //月各位
dsbuff[2]=11; //-
dsbuff[0]=(g_time[6]&0xf0)>>4;//年十位
dsbuff[1]=g_time[6]&0x0f; //年各位
}
void clo_buzz() //关闭蜂鸣器
{
P2=(P2&0x1f)|0xa0;
P0&=0xB0;
P2&=0x1f;
}
void main()
{
clo_buzz(); //关蜂鸣器
init_smg(); //初始化数码管
set_time(); //设置时间
while(1)
{
get_time(); //get时间
}
}