文章目录
- [1. 引言](#1. 引言)
- [2. DS302简介](#2. DS302简介)
- [3. DS302引脚](#3. DS302引脚)
- [4. DS302的寄存器](#4. DS302的寄存器)
-
- [4.1. 时钟芯片DS1302模块介绍](#4.1. 时钟芯片DS1302模块介绍)
- [4.2. 日历、时钟寄存器](#4.2. 日历、时钟寄存器)
- [4.3. 片内RAM](#4.3. 片内RAM)
- [4.4. DS302的输入/输出过程](#4.4. DS302的输入/输出过程)
- [5. DS302+单片机=显示万年历](#5. DS302+单片机=显示万年历)
-
- [5.1 参考代码](#5.1 参考代码)
- [5.2 运行效果](#5.2 运行效果)
- [6. 总结](#6. 总结)
1. 引言
自己制作一个带有年月日时分秒的时钟
2. DS302简介
DS1302是高性能低功耗涓流充电时钟芯片,内含有一个实时时钟/日历寄存器和31个字节静态RAM,实时时钟/日历寄存器能提供2100年之前的秒、分、时、日、日期、月、年等信息,每月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM指示决定采用24小时或12小时格式。内部31个字节静态RAM可提供用户访问。对时钟/日历寄存器、RAM的读/写,可以采用单字节方式或多达31个字节的字符组方式;工作电压范围宽,为2.0~5.5V;与TTL兼容,VCC=5V;温度范围宽,可在-40℃~+85℃正常工作;采用主电源和备份电源双电源供电,备份电源可由电池或大容量电容实现;功耗很低,保持数据和时钟信息时功率小于1mW。
3. DS302引脚

- X1、X2:32.768kHz晶振接入引脚。
- GND:地。
- -RST:复位引脚,低电平有效。
- I/O:数据输入/输出引脚,具有三态功能。
- SCLK:串行时钟输入引脚。
- VCC1:电源1引脚。
- VCC2:电源2引脚。
4. DS302的寄存器
DS1302有一个控制寄存器、12个时钟/日历寄存器和31个RAM。

4.1. 时钟芯片DS1302模块介绍

4.2. 日历、时钟寄存器

4.3. 片内RAM
片内有31个RAM单元。
4.4. DS302的输入/输出过程
- DS1302通过-RST引脚驱动输入/输出过程,当置-RST高电平启动输入/输出过程。在SCLK时钟的控制下,首先把控制命令字写入DS1302的控制寄存器,其次根据写入的控制命令字,依次读写内部寄存器或片内RAM单元的数据。
- 对于日历、时钟寄存器,根据控制命令字,一次可以读写一个日历、时钟寄存器,也可以一次读写8个字节。对所有的日历、时钟寄存器,写的控制命令字为0BEH,读的控制命令字为0BFH。
- 对于片内RAM单元,根据控制命令字,一次可读写一个字节,一次也可读写31个字节。当数据读写完后,-RST变为低电平结束输入/输出过程。
- 无论是命令字还是数据,一个字节传送时都是低位在前,高位在后,每一位的读写发生在时钟的上升沿。
5. DS302+单片机=显示万年历
5.1 参考代码
c
#include <reg52.h>
#include <absacc.h> //定义绝对地址访问
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit T_CLK = P1^3; //DS1302 时钟线引脚
sbit T_IO = P1^4; //DS1302 数据线引脚
sbit T_RST = P1^2; //DS1302 复位线引脚
sbit ACC7 = ACC^7;
sbit ACC0 = ACC^0;
void WriteB(uchar ucDa);
uchar ReadB(void);
void v_W1302(uchar ucAddr,uchar ucDa);
uchar uc_R1302(uchar ucAddr);
uchar data ttime[3]={0x00,0x00,0x00}; // 时分秒
uchar data tdata[4]={0x00,0x00,0x00,0x00}; // 年月日,星期
// LCD2864 常量定义
# define lcdrow 0xc0 //常量初始行
# define lcdpage 0xb8 //常量初始页
# define lcdcolumn 0x40 //常量初始列
# define c_page_max 0x08 //常量最大页
# define c_column_max 0x40 //常量最大列
//LCD12864 端口定义
# define bus P0
sbit rst = P2^0;
sbit e = P2^1;
sbit rw = P2^2;
sbit rs = P2^3;
sbit cs1 = P2^4;
sbit cs2 = P2^5;
void select(uchar);
void send_cmd(uchar);
void send_data(uchar);
void clear_screen(void);
void initial(void);
void display_zf(uchar,uchar,uchar,uchar);
void dispaly_hz(uchar,uchar,uchar,uchar);
uchar code table_zf[]={
// 0(0) 1(1) 2(2) 3(3) 4(4) 5(5) 6(6) 7(7) 8(8) 9(9)
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,/*"0",0*/
0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,/*"1",1*/
0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,/*"2",2*/
0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00,/*"3",3*/
0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00,0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24,/*"4",4*/
0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00,/*"5",5*/
0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00,/*"6",6*/
0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00,/*"7",7*/
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,/*"8",8*/
0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00,/*"9",9*/
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00/*":",10*/
};
uchar code table_hz[]={
// 年(0) 月(1) 日(2) :(3)
0x00,0x20,0x18,0xC7,0x44,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0x04,0x00,0x00,
0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00,/*"年",0*/
0x00,0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xFE,0x00,0x00,0x00,
0x80,0x40,0x30,0x0F,0x02,0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x00,0x00,0x00,/*"月",1*/
0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x00,0x00,0x00,0x00,/*"日",2*/
};
uchar code table_tu[]={
/*-- 调入了一幅图像:C:\Users\86150\Desktop\csdn.bmp --*/
/*-- 宽度x高度=128x32 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x80,0xC0,0xE0,0x60,0x60,0x70,0x70,0xFC,0xFC,0xFE,0xFC,0xFE,0xFC,0xFC,0x70,
0x70,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x04,
0x04,0xC3,0x79,0xFD,0xE4,0xE4,0xE4,0x18,0x39,0x39,0xC1,0x03,0xC1,0x39,0x39,0x58,
0xE4,0xE4,0xE4,0xFD,0x19,0xE3,0x04,0x04,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x80,0xC0,0xE0,0x70,0x78,0x38,0x1C,0x0E,0x06,0x06,0x02,0x02,0x02,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x78,0xFC,0xFC,0xC6,0x86,0x82,0x82,0x82,0x06,0x1E,0x1C,
0x1C,0x00,0x00,0x00,0x00,0x00,0xE0,0xFE,0x1E,0x1E,0x06,0x02,0x02,0x02,0x02,0x06,
0x06,0x3C,0x3C,0xF8,0xE0,0x00,0x00,0x00,0x00,0xFC,0xFE,0xFE,0x7C,0x1C,0x06,0x06,
0x06,0x02,0x02,0x06,0x06,0x06,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x7F,0xFC,
0xFC,0xFB,0xF7,0x0C,0x0B,0x0B,0x08,0x08,0x04,0x04,0x30,0x00,0x30,0x07,0x07,0x08,
0x08,0x0B,0x0B,0x08,0xF4,0xFB,0xFC,0xFC,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
0x3E,0xFF,0x87,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xC0,0x80,0x00,0x00,0x00,0x03,0x03,0x03,0x07,0x07,0x0F,0xFC,
0xFC,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00,0x80,0xFF,0x7F,0x7F,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x01,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x03,0x07,0x07,0x0E,0x0E,0x0C,0x0C,0x08,0x08,0x08,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x07,0x07,0x07,0x07,0x07,0x06,0x06,0x07,0x07,0x07,0x07,
0x07,0x01,0x00,0x00,0x00,0x00,0x07,0x07,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,
0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
//定义延迟函数
void delayus10(void) // 延迟10us
{
uchar i =5;
while(--i);
}
void delayms(uint j) // 延迟ms
{
uchar i = 250;
for(;j>0;j--)
{
while(--i);
i = 249;
while(--i);
i = 250;
}
}
// 往DS1302 写1B数据
void WriteB(uchar ucDa)
{
uchar i;
ACC = ucDa;
for(i =8;i>0;i--)
{
T_IO =ACC0;
T_CLK = 1;
T_CLK = 0;
ACC = ACC >>1;
}
}
// 从DS302读1B数据
uchar ReadB(void)
{
uchar i;
for(i=8;i>0;i--)
{
ACC =ACC>>1;
ACC7 =T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
// DS302 单字节读,从指定地址单元读出数据
uchar uc_R1302(uchar ucAddr)
{
uchar ucDa=0;
T_RST =0;T_CLK =0;
T_RST =1;
WriteB(ucAddr);
ucDa =ReadB();
T_CLK =1;
T_RST =0;
return(ucDa);
}
void select(uchar cs)
{
if(cs==0){cs1=0;cs2=0;}
else if(cs==1){cs1=0;cs2=1;}
else{cs1=1;cs2=0;}
}
void send_cmd(uchar cmd)
{
rs=0;rw=0;bus=cmd;delayus10();e=0;e=1;e=0;
}
void send_data(uchar dat)
{
rs=1;rw=0;bus=dat;delayus10();e=0;e=1;e=0;
}
void clear_screen(void)
{
uchar c_page,c_column;
select(0);
for(c_page=0;c_page<c_page_max;c_page++)
{
send_cmd(c_page+lcdpage);
send_cmd(lcdcolumn);
for(c_column=0;c_column<c_column_max;c_column++)
{
send_data(0x00);
}
}
}
void initial(void)
{
rst=0;delayms(10);rst=1;
select(0);
clear_screen();
send_cmd(lcdrow);
send_cmd(lcdcolumn);
send_cmd(lcdpage);
send_cmd(0x3f);
}
void display_zf(uchar c_page,uchar c_column,uchar num,uchar offset)
{
uchar c1,c2,c3;
for(c1=0;c1<num;c1++)
{
for(c2=0;c2<2;c2++)
{
for(c3=0;c3<8;c3++)
{
send_cmd(lcdpage+c_page+c2);
send_cmd(lcdcolumn+c_column+c1*8+c3);
send_data(table_zf[(c1+offset)*16+c2*8+c3]);
//delayms(100);
}
}
}
}
void display_hz(uchar c_page,uchar c_column,uchar num,uchar offset)
{
uchar c1,c2,c3;
for(c1=0;c1<num;c1++)
{
for(c2=0;c2<2;c2++)
{
for(c3=0;c3<16;c3++)
{
send_cmd(lcdpage+c_page+c2);
send_cmd(lcdcolumn+c_column+c1*16+c3);
send_data(table_hz[(c1+offset)*32+c2*16+c3]);
//delayms(100);
}
}
}
}
void display_tu()
{
uint i,j;
send_cmd(lcdpage);
send_cmd(lcdcolumn);
for(i=0;i<4;i++)
{
for(j=0;j<128;j++)
{
if(j<64)
{
select(1);
send_cmd(lcdpage+i);
send_cmd(lcdcolumn+j);
send_data(table_tu[i*128+j]);delayms(10);
}else
{
select(2);
send_cmd(lcdpage+i);
send_cmd(lcdcolumn+j-64);
send_data(table_tu[i*128+j]);delayms(10);
}
}
}
}
void main()
{
uchar temp;
SP =0x50;
initial();
display_tu();
//省略固定文字
select(1);
display_zf(4,8,1,2);//2
display_zf(4,16,1,0);//2
display_hz(4,40,1,0);//年
display_zf(6,36,1,10);//:
select(2);
display_hz(4,8,1,1);// 月
display_hz(4,40,1,2);// 日
display_zf(6,4,1,10);//:
while(1)
{
P3=0xFF;
temp=uc_R1302(0x8d);
tdata[0]=(temp/16)*10+temp%16;
select(1);
display_zf(4,24,1,tdata[0]/10);
display_zf(4,32,1,tdata[0]%10);
temp=uc_R1302(0x89);
tdata[1]=(temp/16)*10+temp%16;
select(1);
display_zf(4,56,1,tdata[1]/10);
select(2);
display_zf(4,0,1,tdata[1]%10);
temp=uc_R1302(0x87);
tdata[2]=(temp/16)*10+temp%16;
select(2);
display_zf(4,24,1,tdata[2]/10);
display_zf(4,32,1,tdata[2]%10);
temp=uc_R1302(0x85);
temp=temp&0x7f;
ttime[0]=(temp/16)*10+temp%16;
select(1);
display_zf(6,16,1,ttime[0]/10);
display_zf(6,24,1,ttime[0]%10);
temp=uc_R1302(0x83);
ttime[1]=(temp/16)*10+temp%16;
select(1);
display_zf(6,48,1,ttime[1]/10);
display_zf(6,56,1,ttime[1]%10);
temp=uc_R1302(0x81);
temp=temp&0x7f;
ttime[2]=(temp/16)*10+temp%16;
select(2);
display_zf(6,16,1,ttime[2]/10);
display_zf(6,24,1,ttime[2]%10);
temp=uc_R1302(0x8b);
tdata[3]=temp/16;
select(2);
display_zf(6,48,1,temp%10);
delayms(100);
}
}
5.2 运行效果

6. 总结
本文详细介绍了基于 DS1302 时钟芯片与 51 单片机实现万年历显示的全过程,读者可以掌握 DS1302 的时序控制方法、单片机与 LCD 的接口编程技巧,并具备在此基础上扩展闹钟、定时等功能的开发能力。