标题 单片机外设之一(时钟芯片DS1302)
何为DS1302?
DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。工作电压为2.0V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。采用普通32.768kHz晶振。
有何用途?
可以为显示设备,数码管、液晶屏LCD1602和12864等各种显示屏提供系统时间。
底层头文件是什么?
1、文件名ds1302.h
#ifndef _DS1302_H
#define _DS1302_H
#define uint unsigned int
#define uchar unsigned char
/****************************************************************/
//定义I/O接口的参数
sbit DS1302_CLK = P1^7; //定义DS1302的串行时钟引脚
sbit DS1302_IO = P2^6; //定义DS1302的数据引脚
sbit DS1302_RST = P1^6; //定义DS1302的复位引脚
sbit ACC7 = ACC^7; //累加器第7位
sbit ACC0 = ACC^0; //累加器第0位
#define AM(X) X
#define PM(X) (X+12) //转成24小时制
#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8a
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8c
/DS1302时钟部分子程序*******/
typedef struct SYSTEMTIME
{
uchar Second;
uchar Minute;
uchar Hour;
uchar Day;
uchar Month;
uchar Year;
uchar Week;
uchar DatToStr[11];
uchar TimeToStr[9];
}SYSTEMTIME; //定义的时间类型
/************************************************************************/
unsigned char DS1302Write10_16(uchar Date_10);
/************************************************************************/
void DS1302InputByte(uchar d);
/*************************************************************************/
unsigned char DS1302OutputByte(void);
/*************************************************************************/
void Write1302(uchar ucAddr, uchar ucDa);
//
unsigned char Read1302(uchar ucAddr);
//
void DS1302_GetTime(SYSTEMTIME Time);
/************************************************************************/
void DateToStr(SYSTEMTIME Time);
/************************************************************************/
//时钟芯片初始化
void Initial_DS1302(void);
#endif
2、头文件名函数的实现文件DS1302.C
#include <reg51.h>
#include <ds1302.h>
//全局变量
extern SYSTEMTIME CurrentTime;
extern SYSTEMTIME CurrentTime1;
uint txbut,hxbut,hbut;
uchar data_byte;
uchar ck;
/*************************************************************************/
unsigned char DS1302Write10_16(uchar Date_10) //10位转16位
{
uchar Write_date,date1;
Write_date=Date_10/10;
date1=Date_10%10;
Write_date=Write_date16+date1;
return(Write_date);
}
/************************************************************************/
void DS1302InputByte(uchar d) //实时时钟写入一字节(内部函数)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相当于汇编中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
/*************************************************************************/
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
//
void Write1302(uchar ucAddr, uchar ucDa)//ucAddr: DS1302地址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 写1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
//
unsigned char Read1302(uchar ucAddr) //读取DS1302某地址的数据
{
uchar date1,date2;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
date1 = DS1302OutputByte(); // 读1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
date2=date1/16;
date1=date1%16;
date1=date1+date2*10;
return(date1);
}
/************************************************************************/
void DS1302_GetTime(SYSTEMTIME *Time)
//获取时钟芯片的时钟数据到自定义的结构型数组
{
uchar ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ReadValue;
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ReadValue;
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ReadValue;
ReadValue = Read1302(DS1302_DAY);
if(Time->Day>ReadValue)CurrentTime.Week++;
if(CurrentTime.Week>7)CurrentTime.Week=1;
Time->Day = ReadValue;
ReadValue = Read1302(DS1302_MONTH);
if(Time->Month>ReadValue)CurrentTime.Week++;
if(CurrentTime.Week>7)CurrentTime.Week=1;
Time->Month = ReadValue;
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ReadValue;;
}
/*************************************************************************/
void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,放到数组里DateString[]
{
Time->DatToStr[0] = ‘2’;
Time->DatToStr[1] = ‘0’;
Time->DatToStr[2] = Time->Year/10 + ‘0’;
Time->DatToStr[3] = Time->Year%10 + ‘0’;
Time->DatToStr[4] = ‘/’;
Time->DatToStr[5] = Time->Month/10 + ‘0’;
Time->DatToStr[6] = Time->Month%10 + ‘0’;
Time->DatToStr[7] = ‘/’;
Time->DatToStr[8] = Time->Day/10 + ‘0’;
Time->DatToStr[9] = Time->Day%10 + ‘0’;
Time->DatToStr[10] = ‘\0’;
Time->TimeToStr[0] = Time->Hour/10 + '0';
Time->TimeToStr[1] = Time->Hour%10 + '0';
Time->TimeToStr[2] = ':';
Time->TimeToStr[3] = Time->Minute/10 + '0';
Time->TimeToStr[4] = Time->Minute%10 + '0';
Time->TimeToStr[5] = ':';
Time->TimeToStr[6] = Time->Second/10 + '0';
Time->TimeToStr[7] = Time->Second%10 + '0';
Time->TimeToStr[8] = '\0';
}
/*************************************************************************/
//时钟芯片初始化
void Initial_DS1302(void)
{
Write1302(0x8e,0x00); //写入允许
Write1302(0x8c,0x11); //以下写入初始化时间 日期
Write1302(0x88,0x08); //
Write1302(0x86,0x23); //
Write1302(0x8a,0x04); //写入星期
Write1302(0x84,0x01); //
Write1302(0x82,0x31); //
Write1302(0x80,0x20); //
Write1302(0x8e,0x80); //禁止写入
}
应用
以1602为例,处理器为STC89C52RC单片机,对DS1302的系统时间进行调用。如下所示:
while(1)
{
DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据
DateToStr(&CurrentTime); //日期数据转换液晶字符
for(i=0;i<100;i++)
{
DisplayYear(CurrentTime.Year);
}
for(i=0;i<100;i++)
{
DisplayMD(CurrentTime.Month,CurrentTime.Day);
}
for(i=0;i<250;i++)
{
DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据
DateToStr(&CurrentTime); //日期数据转换液晶字符
DisplayTime(CurrentTime.Hour ,CurrentTime.Minute ,CurrentTime.Second);
}
}