天天看點

基于DS1302的實時時鐘系統

1、原理圖

基于DS1302的實時時鐘系統
基于DS1302的實時時鐘系統

2、DS1302手冊

基于DS1302的實時時鐘系統
基于DS1302的實時時鐘系統
基于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++));

繼續閱讀