1、原理圖

2、DS1302手冊
3、源代碼
*************************************************************************
ds1302控制程式
#include
unsigned char time[] = __TIME__;
unsigned char date[] = __DATE__;
#define uchar unsigned char
#define uint unsigned int
#define WRITE_SECOND 0x80
#define WRITE_MINUTE 0x82
#define WRITE_HOUR 0x84
#define WRITE_DAY 0x86
#define WRITE_MONTH 0x88
#define WRITE_YEAR 0x8C
#define READ_SECOND 0x81
#define READ_MINUTE 0x83
#define READ_HOUR 0x85
#define READ_DAY 0x87
#define READ_MONTH 0x89
#define READ_YEAR 0x8D
sbit SCLK = P1^7;
sbit DATA = P1^2;
uint second, minute, hour, day, month, year;
uchar str[3];
uchar rdata;
void write_cmd(uchar addr);
void write_data(uchar dat);
void read_data();
void write_ds1302(uchar addr, uchar dat);
uint read_ds1302(uchar addr);
void init_ds1302();
void lcd_1602_init();
void lcd_1602_write_string(uchar x, uchar y, uchar *string);
void lcd_1602_write_char(uchar x, uchar y, uchar dat);
void delay_10us();
uchar *itoa(uchar dat);
void main()
{
init_ds1302();
lcd_1602_init();
second = read_ds1302(READ_SECOND);
minute = read_ds1302(READ_MINUTE);
hour = read_ds1302(READ_HOUR);
day = read_ds1302(READ_DAY);
month = read_ds1302(READ_MONTH);
year = read_ds1302(READ_YEAR);
str[0] = month/10 + '0';
str[1] = month%10 + '0';
str[2] = '\0';
// lcd_1602_write_string(1, 12, str);
lcd_1602_write_char(1, 14, str[1]);
lcd_1602_write_string(0, 0, "time:");
lcd_1602_write_string(0, 6, itoa(hour));
lcd_1602_write_string(0, 8, ":");
lcd_1602_write_string(0, 9, itoa(minute));
lcd_1602_write_string(0, 11, ":");
lcd_1602_write_string(0, 12, itoa(second));
lcd_1602_write_string(1, 0, "date:");
lcd_1602_write_string(1, 6, itoa(year));
lcd_1602_write_string(1, 8, "-");
lcd_1602_write_string(1, 9, itoa(month));
lcd_1602_write_string(1, 11, "-");
lcd_1602_write_string(1, 12, itoa(day));
}
void get_time()
hour = (time[0]-'0')*10 + time[1] - '0';
minute = (time[2]-'0')*10 + time[3] - '0';
second = (time[4]-'0')*10 + time[5] - '0';
void get_date()
year = (date[0]-'0')*1000 + (date[1]-'0')*100 + (date[2]-'0')*10 + (date[3]-'0');
month = (date[4]-'0')*10 + (date[5]-'0');
day = (date[6]-'0')*10 + (date[7]-'0');
void write_cmd(uchar addr)
int i;
uchar temp;
SCLK = 0;
for(i = 0; i
temp = addr;
DATA = (bit)(temp&0x01);
SCLK = 1; //上升沿寫入位址
addr >>= 1; //串行輸入,先輸入低位
delay_10us();
void write_data(uchar dat)
temp = dat;
SCLK = 1; //上升沿寫入資料
dat >>= 1; //串行輸入,先輸入低位
void read_data()
SCLK = 1;
rdata = 0;
temp = DATA;
rdata |= (temp
SCLK = 0; //下降沿讀出資料,先讀低位
rdata = dat; //将讀出的資料傳回
void write_ds1302(uchar addr, uchar dat)
write_cmd(addr);
write_data(dat);
uint read_ds1302(uchar addr)
read_data();
return rdata;
void init_ds1302()
uchar flag;
flag = read_ds1302(0x81);
if(flag & 0x80)
write_ds1302(0x8e, 0x00); //去除寫保護
//初始化 秒、分、時
write_ds1302(WRITE_SECOND, ((44/10)
write_ds1302(WRITE_MINUTE, ((33/10)
write_ds1302(WRITE_HOUR, ((22/10)
//初始化 日、月、年
write_ds1302(WRITE_DAY, ((26/10)
write_ds1302(WRITE_MONTH, ((4/10)
write_ds1302(WRITE_YEAR, ((14/10)
//打開充電模式 , 增加寫保護
write_ds1302(0x90, 0xa5);
write_ds1302(0x8e, 0x80);
uchar *itoa(uchar dat) //數字轉字元串函數
str[0] = (dat>>4)&0x07 + '0';
str[1] = dat&0x0f + '0';
return str;
****************************************************************************
lcd1602液晶顯示程式
**************************************************************************
#define uchar unsigned char
uchar code cmd[] = {
0x01, //清屏
0x02, //光标傳回00h
0x06, //開顯示,無光标,不閃爍
0x38 //8位總線,雙行顯示,5*7陣列
};
void delay_1ms();
void delay_10us();
int lcd_1602_busy()
uchar tmp;
P0 = 0xff;
LCD_1602_RW = 1;
LCD_1602_RS = 0;
LCD_1602_EN = 1;
tmp = P0;
LCD_1602_EN = 0;
return (bit)(0x80 & tmp);
void lcd_1602_write_cmd(uchar cmd)
while(lcd_1602_busy());
LCD_1602_RW = 0;
P0 = cmd;
// P0 = cmd;
void lcd_1602_write_data(uchar dat)
while(lcd_1602_busy());
LCD_1602_RS = 1;
P0 = dat;
// P0 = dat;
void lcd_1602_init()
lcd_1602_write_cmd(0x01);
lcd_1602_write_cmd(0x0c);
lcd_1602_write_cmd(0x38);
// lcd_1602_write_cmd(0x05);
delay_1ms();
void lcd_1602_write_char(uchar x, uchar y, uchar dat)
if(x == 0)
lcd_1602_write_cmd(0x80 + y%16);
lcd_1602_write_data(dat);
else
lcd_1602_write_cmd(0xc0 + y%16);
void lcd_1602_write_string(uchar x, uchar y, uchar *string)
while(*string != '\0')
lcd_1602_write_char(x, y++, *(string++));