×
单片机 > 单片机程序设计 > 详情

51单片机的DS1302的驱动程序

发布时间:2020-06-15 发布时间:
|

 DS1302实时时钟模块


 对于时钟芯片,我们只要知道它的写入时序图和读出时序图,以及时钟芯片内部


 所对应的地址就可以了,


 所谓写是写入EEPROM里面,即设定好一个时钟的初值,然后每次刷新的时钟的


 新值都写入EEPROM里保存起来,再从EEPROM里读出来,这样就能保证当外部


 电源掉电后,自带的电池仍能按照掉电时的时间继续刷新,而不是回到初始值。


读一个数据的时序图


 写一个数据的时序图


 

 内部各功能地址


 

 驱动程序:


 

#include

#include "./delay/delay.h"

 

 

#define ds1302_sec_add    0x80    //设置秒的地址

#define ds1302_min_add    0x82    //设置分的地址

#define ds1302_hr_add      0x84  //设置时的地址

#define ds1302_date_add    0x86    //设置天的地址

#define ds1302_month_add    0x88    //设置月的地址

#define ds1302_year_add    0x8c    //设置年的地址

#define ds1302_control_add 0x8e

#define ds1302_charger_add 0x90  

#define ds1302_clkburst_add 0xbe

 

sbit RST = P1^2;

sbit SCK = P1^1;

sbit IO = P1^0;

 

unsigned char tempbuf[3];

unsigned char timebuf[3] = {20,59,30};           //时间

unsigned char readbuf[6];

unsigned char disbuf[7];

unsigned char writebuf[6];

 

unsigned char disyear[3] = {16,8,17};          //日期

 

 

 

/*LCD*/

#define LCDPORT P0

#define LCD_WRITE_DATA   1

#define LCD_WRITE_COM    0

sbit RS = P2^4;

sbit RW = P2^5;

sbit E = P2^6;

 

void ds1302_write_byte(unsigned char addr, unsigned char byte)

{

unsigned char i;

addr = addr & 0xfe;

SCK = 0;

RST = 0;

RST = 1;

for(i = 0; i < 8; i++)

{

IO = addr & 0x01;

SCK = 0;

SCK = 1;

addr >>= 1;

}

for(i = 0; i < 8; i++)

{

IO = byte & 0x01;

SCK = 0;

SCK = 1;

byte >>= 1;

}

SCK = 0;

RST = 0;

}

 

unsigned char ds1302_read_byte(unsigned char addr)

{

unsigned char i;

unsigned char temp;

addr = addr & 0xfe;

SCK = 0;

RST = 0;

RST = 1;

addr = addr + 1;

for(i = 0; i < 8; i++)

{

IO = addr & 0x01;

SCK = 0;

SCK = 1;

addr >>= 1;

}

for(i = 0; i < 8; i++)

{

SCK = 1;

SCK = 0;

temp >>= 1;

if(IO)

{

temp += 0x80;

}

}

//SCK = 0;

RST = 0;

return temp;

}

void ds1302_write_time()

{

unsigned char i;

unsigned char temp;

unsigned char temp1;

for(i = 0; i < 6; i++)

{  

temp  = timebuf[i] / 10;

        temp1 = timebuf[i] % 10;

        writebuf[i] = (temp << 4) | temp1;

//writebuf[i] = ((timebuf[i] / 10) << 4) + (timebuf[i] % 10);

}

ds1302_write_byte(ds1302_control_add,0x00);

ds1302_write_byte(ds1302_hr_add,writebuf[0]);

ds1302_write_byte(ds1302_min_add,writebuf[1]);

ds1302_write_byte(ds1302_sec_add,writebuf[2]);

ds1302_write_byte(ds1302_year_add,writebuf[3]);

ds1302_write_byte(ds1302_month_add,writebuf[4]);

ds1302_write_byte(ds1302_date_add,writebuf[5]);

ds1302_write_byte(ds1302_control_add,0x80);

}

 

void ds1302_read_time()

{

unsigned char i;

readbuf[0] = ds1302_read_byte(ds1302_hr_add);

readbuf[1] = ds1302_read_byte(ds1302_min_add);

readbuf[2] = ds1302_read_byte(ds1302_sec_add);

readbuf[3] = ds1302_read_byte(ds1302_year_add);

readbuf[4] = ds1302_read_byte(ds1302_month_add);

readbuf[5] = ds1302_read_byte(ds1302_date_add);

for(i = 0; i < 6; i++)

{

disbuf[i] =  ((readbuf[i] >> 4) * 10) + (readbuf[i] & 0x0f);               

}

}

 

void lcd1602_write(unsigned char byte, unsigned char flag)

{

if(flag)

{

RS = 1;                    //选择输入的数据为数据

}

else

{

RS = 0;                      //选择输入的数据为命令

}

RW = 0;                           //写

E = 1;                            //选中lcd

LCDPORT = byte;

delay_ms(5);

E = 0;                          //失能LCD      高电平有效

}

 

void lcd1602_init()

{

delay_ms(15);

  lcd1602_write(0x38,LCD_WRITE_COM);                  //设置8位数据接口,两行指令,5*8点阵字符

  delay_ms(5);

  lcd1602_write(0x38,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x38,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x38,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x08,LCD_WRITE_COM);             //关闭显示,关闭光标和闪烁

  delay_ms(5);

  lcd1602_write(0x01,LCD_WRITE_COM);            //清屏

  delay_ms(5);

  lcd1602_write(0x06,LCD_WRITE_COM);           //设置指针方式,画面不平移

  delay_ms(5);

  lcd1602_write(0x0c,LCD_WRITE_COM);          //设置指针方式,画面不平移

  delay_ms(5);  

}

 

 

void lcd1602_dis_str(unsigned char x, unsigned char y, unsigned char *s)               //打印字符串

{

if((x > 1) || (y > 15))

{

return ;

}

if(0 == x)

{

lcd1602_write(y + 0x80,LCD_WRITE_COM);

 

}

else if(1 == x)

{

lcd1602_write(y + 0xc0,LCD_WRITE_COM);

}

while(*s)

{

lcd1602_write(*s, LCD_WRITE_DATA);

s++;

}

}

 

 

 

void lcd1602_dis_time()

{

unsigned char lcddisbuf[9] = {0};

unsigned char lcdday[9] = {0};

 

lcddisbuf[0] = (disbuf[0] / 10) + 0x30;                //显示时间

lcddisbuf[1] = (disbuf[0] % 10) + 0x30;

lcddisbuf[2] = ':';

lcddisbuf[3] = (disbuf[1] / 10) + 0x30;

lcddisbuf[4] = (disbuf[1] % 10) + 0x30;

lcddisbuf[5] = ':';

lcddisbuf[6] = (disbuf[2] / 10) + 0x30;

lcddisbuf[7] = (disbuf[2] % 10) + 0x30;

 

lcdday[0] =  (disbuf[3] / 10) + 0x30;                 //显示日期

lcdday[1] =  (disbuf[3] % 10) + 0x30;

lcdday[2] =  '-';

lcdday[3] =  (disbuf[4] / 10) + 0x30;

lcdday[4] =  (disbuf[4] % 10) + 0x30;

lcdday[5] =  '-';

lcdday[6] =  (disbuf[5] / 10) + 0x30;

lcdday[7] =  (disbuf[5] % 10) + 0x30;

lcd1602_dis_str(0,0,"time:");

lcd1602_dis_str(0,6,lcddisbuf);

lcd1602_dis_str(1,0,lcdday);

}

void main()

{

lcd1602_init();

ds1302_write_time();                  //写入数据

while(1)

{

ds1302_read_time();              //读出数据

lcd1602_dis_time();              //打印读出的数据

}

}


关键字:51单片机  DS1302  驱动程序

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址