📄 ds1302.c
字号:
//*************************************************************************************************
//* *
//* ***************************DS1302驱动程序************************* *
//* *
//*************************************************************************************************
//*************************************************************************************************
//* *
//* ******************************头文件及宏定义************************** *
//* *
//*************************************************************************************************
#include <at89x51.h>
#define DSIO P1_2 //实时时钟数据线引脚
#define DSCLK P1_1 //实时时钟时钟线引脚
#define DSRST P1_0 //实时时钟复位线引脚
#define DS_SECOND 0x80 //DS1302数据地址。
#define DS_MINUTE 0x82
#define DS_HOUR 0x84
#define DS_WEEK 0x8A
#define DS_DAY 0x86
#define DS_MONTH 0x88
#define DS_YEAR 0x8C
//*************************************************************************************************
//* *
//* ********************************全局变量****************************** *
//* *
//*************************************************************************************************
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
typedef struct TIME //定义的时间类型
{
unsigned char ucSecond;
unsigned char ucMinute;
unsigned char ucHour;
unsigned char ucWeek;
unsigned char ucDay;
unsigned char ucMonth;
unsigned char ucYear;
unsigned char ucaDateString[9];
unsigned char ucaTimeString[9];
}TIME;
//*************************************************************************************************
//* *
//* *********************实时时钟写入一字节(内部函数)************************* *
//* *
//*************************************************************************************************
void vWriteByte(unsigned char ucByte)
{
unsigned char ucCount;
ACC = ucByte;
for(ucCount=8;ucCount>0;ucCount--)
{
DSIO = ACC0; //把累加器第0位赋给DSIO口。
DSCLK = 1; //DSCLK下降沿,写入数据。
DSCLK = 0;
ACC = ACC >> 1; //把累加器里的数据右移一位。
}
}
//*************************************************************************************************
//* *
//* *********************实时时钟读入一字节(内部函数)************************ *
//* *
//*************************************************************************************************
unsigned char ucReadByte(void)
{
unsigned char ucCount;
for(ucCount=8;ucCount>0;ucCount--)
{
ACC = ACC >>1; //把累加器右移一位。
ACC7 = DSIO; //把DSIO的数据传给累加器最高位。
DSCLK = 1; //DSCLK下降沿读出数据。
DSCLK = 0;
}
return ACC;
}
//*************************************************************************************************
//* *
//* *************************向实时时钟写入一字节*************************** *
//* *
//*************************************************************************************************
void vDSWriteDirect(unsigned char ucAddr, unsigned char ucData) //ucAddr: DS1302地址, ucData: 要写的数据
{
DSRST = 0;
DSCLK = 0;
DSRST = 1;
vWriteByte(ucAddr); // 地址,命令
vWriteByte(ucData); // 写1Byte数据
DSCLK = 1;
DSRST = 0;
}
//*************************************************************************************************
//* *
//* *************************读取DS1302某地址的数据************************* *
//* *
//*************************************************************************************************
unsigned char vDSReadDirect(unsigned char ucAddr)
{
unsigned char ucData;
DSRST = 0;
DSCLK = 0;
DSRST = 1;
vWriteByte(ucAddr|0x01); // 地址,命令
ucData = ucReadByte(); // 读1Byte数据
DSCLK = 1;
DSRST = 0;
return ucData;
}
//*************************************************************************************************
//* *
//* ******************************是否写保护******************************* *
//* *
//*************************************************************************************************
void vDSSetProtect(bit bFlag)
{
if(bFlag)
vDSWriteDirect(0x8E,0x10);
else
vDSWriteDirect(0x8E,0x00);
}
//*************************************************************************************************
//* *
//* ******************************设置实时时钟时间************************** *
//* *
//*************************************************************************************************
void vDSSetTime(unsigned char ucAddress, unsigned char ucValue)
{
vDSSetProtect(0); //取消保护。
vDSWriteDirect(ucAddress, ((ucValue/10)<<4 | (ucValue%10))); //吧ucValue转换成BCD码,然后写入。
}
//*************************************************************************************************
//* *
//* ******************************读取实时时钟时间************************** *
//* *
//*************************************************************************************************
void vDSGetTime(TIME *stTime) //把读取的BCD码转换成2进制数然后存入时间数组。
{
unsigned char ucReadValue;
ucReadValue = vDSReadDirect(DS_SECOND); //秒
stTime->ucSecond=((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucReadValue = vDSReadDirect(DS_MINUTE); //分
stTime->ucMinute=((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucReadValue = vDSReadDirect(DS_HOUR); //小时
stTime->ucHour =((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucReadValue = vDSReadDirect(DS_DAY); //天
stTime->ucDay =((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucReadValue = vDSReadDirect(DS_WEEK); //星期
stTime->ucWeek=((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucReadValue =vDSReadDirect(DS_MONTH); //月
stTime->ucMonth=((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
ucReadValue =vDSReadDirect(DS_YEAR); //年
stTime->ucYear=((ucReadValue&0x70)>>4)*10+(ucReadValue&0x0F);
}
//*************************************************************************************************
//* *
//* ******************************实时时钟日期字符串************************** *
//* *
//*************************************************************************************************
void vDateString(TIME *stTime) //把日期数据转换成日期字符串,便于显示。
{
stTime->ucaDateString[0] = stTime->ucYear/10 + '0';
stTime->ucaDateString[1] = stTime->ucYear%10 + '0';
stTime->ucaDateString[2] = '-';
stTime->ucaDateString[3] = stTime->ucMonth/10 + '0';
stTime->ucaDateString[4] = stTime->ucMonth%10 + '0';
stTime->ucaDateString[5] = '-';
stTime->ucaDateString[6] = stTime->ucDay/10 + '0';
stTime->ucaDateString[7] = stTime->ucDay%10 + '0';
stTime->ucaDateString[8] = '\0';
}
//*************************************************************************************************
//* *
//* ******************************实时时钟时间字符串************************** *
//* *
//*************************************************************************************************
void vTimeString(TIME *stTime) //把时间数据转换成时间字符串,便于显示。
{
stTime->ucaTimeString[0] = stTime->ucHour/10 + '0';
stTime->ucaTimeString[1] = stTime->ucHour%10 + '0';
stTime->ucaTimeString[2] = ':';
stTime->ucaTimeString[3] = stTime->ucMinute/10 + '0';
stTime->ucaTimeString[4] = stTime->ucMinute%10 + '0';
stTime->ucaTimeString[5] = ':';
stTime->ucaTimeString[6] = stTime->ucSecond/10 + '0';
stTime->ucaTimeString[7] = stTime->ucSecond%10 + '0';
stTime->ucaDateString[8] = '\0';
}
//*************************************************************************************************
//* *
//* ******************************初始化时钟************************** *
//* *
//*************************************************************************************************
void vDSInitialize()
{
unsigned char ucSecond=vDSReadDirect(DS_SECOND);
if(ucSecond&0x80)
vDSSetTime(DS_SECOND,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -