#ifndef _DS1302_H_
#define _DS1302_H_
#include<AT89X52.H>
#include<intrins.h>
typedef struct __SYSTEMTIME__
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char datestr[11];
unsigned char timestr[9];
}systime; //定义的时间类型
#define uchar unsigned char
#define uint unsigned int
#define am(x) x
#define pm(x) (x+12) // 转成24小时制
#define dssecond 0x80 //时钟芯片的寄存器位置,存放时间
#define dsminute 0x82
#define dshour 0x84
#define dsweek 0x8A
#define dsday 0x86
#define dsmonth 0x88
#define dsyear 0x8C
#define dsbaohu 0x8E
#define on 0x80
#define off 0x00
extern uchar change(uchar x);
extern uchar bcdtohex(uchar val);
extern void wr1302b(uchar temp);
extern void wr1302(uchar add,uchar dat);
extern uchar re1302b();
extern uchar re1302(uchar address);
extern void dsinit(void);
extern void dsgettime(systime *ds1302);
extern void timetostr(systime *ds1302);
extern void datetostr(systime *ds1302);
#endif
////////////////////////////////////////////////////////////c程序////////////////////////////////////////////////////
#include <AT89X52.H>
#include "ds1302.h"
#include <intrins.h>
//管角定义
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit dssck=P1^0;
sbit dssda=P1^1;
sbit dsrst=P1^2;// DS1302复位
systime currenttime; //定义结构体变量不可以在点h文件中定义
uchar flaghour,flagmin,flagsec,flagyear,flagmonth,flagday,flagweek,week_value[2];
/*************************************
函数名:change
函数功能:十进制转换成十六进制
参数:x(十六进制数)
返回:y(十进制数)
备注:无
*************************************/
uchar bcdtohex(uchar val)
{
uchar i;
i = val&0x0f; //按位与,i得到低四位数。
val >>= 4; //右移四位,将高四位移到低四位的位置,得到高四位码值。
val &= 0x0f; //防止移位时高位补进1,只保留高四位码值
val *= 10; //高位码值乘以10
i += val; //然后与第四位码值相加。
return i; //将得到的十进制数返回
}
/*************************************
函数名:wr1302b
函数功能:实时时钟写入一个字节
参数:d
返回:无
备注:配合wr1302使用
*************************************/
void wr1302b(uchar d)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
dssda = ACC0; //相当于汇编中的 RRC
dssck = 1;
dssck = 0;
ACC = ACC >> 1;
}
}
/*************************************
函数名:wr1302
函数功能:向1302中写数据
参数:ucAddr(DS1302地址), ucData(要写的数据)
返回:无
备注:无
*************************************/
void wr1302(uchar ucAddr, uchar ucDa)
{
dsrst = 0;
dssck = 0;
dsrst = 1;
wr1302b(ucAddr); // 地址,命令
wr1302b(ucDa); // 写1Byte数据
dssck = 1;
dsrst = 0;
}
/*************************************
函数名:re1302b
函数功能:实时时钟读取一字节
参数:无
返回:ACC
备注:配合re1302使用
*************************************/
uchar re1302b(void)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = dssda;
dssck = 1;
dssck = 0;
}
return(ACC);
}
/*************************************
函数名:re1302
函数功能:读数据
参数:ucAddr(地址)
返回:ucData(数据)
备注:无
*************************************/
uchar re1302(uchar ucAddr) //读取DS1302某地址的数据
{
unsigned char ucData;
dsrst = 0;
dssck = 0;
dsrst = 1;
wr1302b(ucAddr|0x01); // 地址,命令
ucData = re1302b(); // 读1Byte数据
dssck = 1;
dsrst = 0;
return(ucData);
}
/*************************************
函数名:dsinit
函数功能:时钟初始化
参数:无
返回:无
备注:无
*************************************/
void dsinit(void) //时钟初始化可以不填
{
wr1302(dsbaohu,off);
wr1302(dsyear,0x09);
wr1302(dsmonth,0x11);
wr1302(dsday,0x02);
wr1302(dsweek,0x01);
wr1302(dshour,0x23);
wr1302(dsminute,0x57);
wr1302(dssecond,0x55);
wr1302(dsbaohu,on);
}
/*************************************
函数名:dsgettime
函数功能:获取时间到时间型指针
参数:systime *ds1302(时间型数据指针)
返回:无
备注:无
*************************************/
void dsgettime(systime *ds1302) //获取时钟芯片的时钟数据到自定义的结构型数组
{
unsigned char ReadValue;
ReadValue = re1302(dssecond);
ds1302->Second = bcdtohex(ReadValue);
ReadValue = re1302(dsminute);
ds1302->Minute = bcdtohex(ReadValue);
ReadValue = re1302(dshour);
ds1302->Hour = bcdtohex(ReadValue);
ReadValue = re1302(dsday);
ds1302->Day = bcdtohex(ReadValue);
ReadValue = re1302(dsweek);
ds1302->Week = bcdtohex(ReadValue);
ReadValue = re1302(dsmonth);
ds1302->Month =bcdtohex(ReadValue);
ReadValue = re1302(dsyear);
ds1302->Year = bcdtohex(ReadValue);
}
/*************************************
函数名:timetostr
函数功能:将时间转换液晶显示字符放入数组timestr[]
参数:systime *ds1302(时间型数据指针)
返回:无
备注:无
*************************************/
void timetostr(systime *ds1302)
{ if(flaghour<2)
{
ds1302->timestr[0] = ds1302->Hour/10 + '0';
ds1302->timestr[1] = ds1302->Hour%10 + '0';
}
else
{
ds1302->timestr[0] = ' ';
ds1302->timestr[1] = ' ';
}
ds1302->timestr[2] = ':';
if(flagmin<2)
{
ds1302->timestr[3] = ds1302->Minute/10 + '0';
ds1302->timestr[4] = ds1302->Minute%10 + '0';
}
else
{
ds1302->timestr[3] = ' ';
ds1302->timestr[4] = ' ';
}
ds1302->timestr[5] = ':';
if(flagsec<2)
{
ds1302->timestr[6] = ds1302->Second/10 + '0';
ds1302->timestr[7] = ds1302->Second%10 + '0';
}
else
{
ds1302->timestr[6] = ' ';
ds1302->timestr[7] = ' ';
}
ds1302->timestr[8] = '\0';
}
/*************************************
函数名:datetostr
函数功能:将日期转换液晶显示字符放入数组datestr[]
参数:systime *ds1302(时间型数据指针)
返回:无
备注:无
*************************************/
void datetostr(systime *ds1302) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
{ if(flagyear<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22
{
ds1302->datestr[0] = '2';
ds1302->datestr[1] = '0';
ds1302->datestr[2] = ds1302->Year/10 + '0';
ds1302->datestr[3] = ds1302->Year%10 + '0';
}
else
{
ds1302->datestr[0] = ' ';
ds1302->datestr[1] = ' ';
ds1302->datestr[2] = ' ';
ds1302->datestr[3] = ' ';
}
ds1302->datestr[4] = '/';
if(flagmonth<2)
{
ds1302->datestr[5] = ds1302->Month/10 + '0';
ds1302->datestr[6] = ds1302->Month%10 + '0';
}
else
{
ds1302->datestr[5] = ' ';
ds1302->datestr[6] = ' ';
}
ds1302->datestr[7] = '/';
if(flagday<2)
{
ds1302->datestr[8] = ds1302->Day/10 + '0';
ds1302->datestr[9] = ds1302->Day%10 + '0';
}
else
{
ds1302->datestr[8] = ' ';
ds1302->datestr[9] = ' ';
}
if(flagweek<2)
{
week_value[0] = ds1302->Week%10 + '0';
//星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示
}
else
{
week_value[0] = ' ';
}
week_value[1] = '\0';
ds1302->datestr[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符
}