📄 ds1302.c
字号:
/********************************************************************
AUTHOR: GanGuoqiang
DISCRIPTION: DS1302 31*8 BYTE RAM ADDRESSED
NOTE: USING T_RST=P3^5; T_CLK =P3^6; T_IO=P3^7;
DATE : 2008.11.23
***********************************************************************/
#include "reg52.h"
#include "MYTYPE.H"
#include "KEYBOARD.H"
#define SEC 0X11
#define MIN 0X12
#define HOUR 0X13
#define DATE 0X14
#define MONTH 0X15
#define DAY 0X16
#define YEAR 0X17
sbit T_RST=P3^5;
sbit T_CLK =P3^6;
sbit T_IO=P3^7;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
extern displaystr(unsigned char x,unsigned char y,char z[]);
extern displaychr(unsigned char x,unsigned char y,char z);
extern w_com(unsigned char);
void W1302mod(which);
void W1302(uchar, uchar); //向DS1302写入一个字节
uchar R1302(uchar); //从DS1302读出一个字节
void Set1302(uchar * ); //设置时间
whichTIME(uchar ,uchar []);
uchar chic1(uchar getcode);
uchar chic2(uchar getcode);
setTIME(uchar); //extern
reTIME(); //extern
nowTIME(); //extern
setsec();
setmin();
sethour();
setdate();
setmonth();
setday();
setyear();
chickey(uchar which);
static uchar mod[7];
/*static char modsec[]="sec";
static char modmin[]="min";
static char modhour[]="hour";
static char moddate[]="date";
static char modmonth[]="month";
static char modday[]="day";
static char modyear[]="year";*/ //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
extern char SKEY[];//static char SKEY[17]={'0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f'}; ////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
static uchar initTIME[7]={0x00,0x10,0x20,0x11,0x23,0x07,0x08}; //初始化后设置为:08年11月23日星期ri 20点10分0秒 !!bcd!
//static uchar GETTIME[7]={0x00,0x10,0x20,0x11,0x23,0x07,0x08};
uchar TIME[20] ;//extern={0x70,0x70,'-',0x72,0x96,'-',0x77,0x78,'-',0x77,0x78,'-',0x77,0x79,'-',0x77,0x78,'-',0x70,0x70};
/********************************************************************
***********************************************************************/
displaymod1()
{ uchar i=1;
for(i=1;i<7;i++)
TIME[i*3-1]=':' ;
}
displaymod2()
{ uchar i=1;
for(i=1;i<7;i++)
TIME[i*3-1]='-' ;
}
displaymod3()
{
}
/////////////////////////////////////////////////////////////////////////////
void TIMEreset() //时间清零
{
Set1302(initTIME); //清时间
//W1302(0x90,0xa5); //打开充电二级管 一个二级管串联一个2K电阻
}
////////////////////////////////////////////////////////////////////////////
nowTIME() //少用
{
static char i=0,j=0;
for(i=1;i<8;i++)//1START
{
whichTIME(i,mod);
TIME[j++]=chic1(mod[i-1]);
mod[i-1]*=16;
TIME[j++]=chic1(mod[i-1]);
j++;
}
}
reTIME()
{
static char i=0,j=0x13;
for(i=1;i<8;i++)//1START
{
whichTIME(i,mod);
TIME[j--]=chic2(mod[i-1]);
mod[i-1]>>=4;
TIME[j--]=chic2(mod[i-1]);
j--;
}
}
sett()
{
reTIME();displaystr(0,0,TIME);
while(KEYNUM!=0X0F)
{
key();
switch(KEYNUM)
{
case 0x05 : setsec(); displaystr(0,0,"settime success!");break;
case 0x06 : setmin(); displaystr(0,0,"settime success!");break;
case 0x07 : sethour();displaystr(0,0,"settime success!");break;
case 0x08 : setdate();displaystr(0,0,"settime success!");break;
case 0x09 : setmonth();displaystr(0,0,"settime success!");break;
case 0x0a : setday(); displaystr(0,0,"settime success!");break;
case 0x0b : setyear();displaystr(0,0,"settime success!");break;
case 0x0f : w_com(0x01);displaystr(0,0,"exit!"); break;
default : w_com(0x01);displaystr(0,0,"wanta break?"); break;
}
}
}
setsec()
{
//w_com(0x01);displaystr(0,0,"sec");
chickey(0);
setTIME(SEC);
}
setmin()
{
//w_com(0x01);displaystr(0,0,modmin);
chickey(1);
setTIME(MIN);
}
sethour()
{
//w_com(0x01);displaystr(0,0,modhour);
chickey(2);
setTIME(HOUR);
}
setdate()
{
//w_com(0x01);displaystr(0,0,moddate);
chickey(3);
setTIME(DATE);
}
setmonth()
{
//w_com(0x01);displaystr(0,0,modmonth);
chickey(4);
setTIME(MONTH);
}
setday()
{
//w_com(0x01);displaystr(0,0,modday);
chickey(5);
setTIME(DAY);
}
setyear()
{
//w_com(0x01);displaystr(0,0,modyear);
chickey(6);
setTIME(YEAR);
}
setTIME(uchar setmod)
{
whichTIME(setmod,mod);
}
/////////////////////////////////////////////////////////////////////////
static whichTIME(uchar which,uchar mod[])
{
switch (which)
{
case 0x01 : mod[0]=R1302(0x81) ;break;
case 0x02 : mod[1]=R1302(0x83) ;break;
case 0x03 : mod[2]=R1302(0x85) ;break;
case 0x04 : mod[3]=R1302(0x87) ;break;
case 0x05 : mod[4]=R1302(0x89) ;break;
case 0x06 : mod[5]=R1302(0x8b) ;break;
case 0x07 : mod[6]=R1302(0x8d) ;break;
case 0x11 : W1302mod(0);break;
case 0x12 : W1302mod(1);break;
case 0x13 : W1302mod(2);break;
case 0x14 : W1302mod(3);break;
case 0x15 : W1302mod(4);break;
case 0x16 : W1302mod(5);break;
case 0x17 : W1302mod(6);break;
default : break;
}
}
uchar chic1(uchar getcode)
{
if(!(getcode/16)) return SKEY[0];
switch(getcode/16)
{
case 0x01 : return SKEY[1] ;break;
case 0x02 : return SKEY[2] ;break;
case 0x03 : return SKEY[3] ;break;
case 0x04 : return SKEY[4] ;break;
case 0x05 : return SKEY[5] ;break;
case 0x06 : return SKEY[6] ;break;
case 0x07 : return SKEY[7] ;break;
case 0x08 : return SKEY[8] ;break;
case 0x09 : return SKEY[9] ;break;
}
}
uchar chic2(uchar getcode)
{
if(!(getcode%16)) return SKEY[0] ;
switch(getcode%16)
{
case 0x01 : return SKEY[1] ;break;
case 0x02 : return SKEY[2] ;break;
case 0x03 : return SKEY[3] ;break;
case 0x04 : return SKEY[4] ;break;
case 0x05 : return SKEY[5] ;break;
case 0x06 : return SKEY[6] ;break;
case 0x07 : return SKEY[7] ;break;
case 0x08 : return SKEY[8] ;break;
case 0x09 : return SKEY[9] ;break;
}
}
chickey(uchar which)
{
uchar tmp=0,n;
w_com(0x01);
switch(which+1)
{
case 1 : displaystr(0,0,"sec"); break;
case 2 : displaystr(0,0,"min"); break;
case 3 : displaystr(0,0,"hour");break;
case 4 : displaystr(0,0,"date");break;
case 5 : displaystr(0,0,"month");break;
case 6 : displaystr(0,0,"day"); break;
case 7 : displaystr(0,0,"year");break;
}
while(KEYNUM!=0X10)
{
key();
if(KEYNUM!=0X10)
{
displaychr(0,0,SKEY[KEYNUM]);tmp=KEYNUM<<4;
}
}
KEYNUM=0X0; //
while(KEYNUM!=0X10)
{
key();
if(KEYNUM!=0X10)
{
displaychr(1,0,SKEY[KEYNUM]);tmp+=KEYNUM;
}
}
for(n=1;n<8;n++)
whichTIME(n,mod);
mod[which]=tmp;
}
//////////////////////////////////////////////////////////////////////////////
/*
void TIMEr_1(void) interrupt 1 //中断入口,闪烁
{
TH0=0x3c; //50ms定时
TL0=0xb0;
if(msec++==10) //500ms
{
msec=0;a=~a; //闪烁标志反转
if(a==0) //1秒后背光时间减一秒。
LedTime--;
}
}
*/
//********DS1302读写程序***************//
/********************************************************************
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
说 明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无
***********************************************************************/
void RTInputByte(uchar d)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
T_IO = ACC0; /*相当于汇编中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
说 明:从DS1302读取1Byte数据 (内部函数)
入口参数:无
返 回 值:ACC
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
RTInputByte(ucDa); /* 写1Byte数据*/
T_CLK = 1;
T_RST = 0;
}
void W1302mod(which)
{
/*uchar n;
//W1302(0x8e,0x00);W1302(0x80,mod[which]) ;W1302(0x8e,0x80);
for(n=1;n<8;n++)
whichTIME(n,mod);*/
Set1302(mod);
}
/********************************************************************
函 数 名:R1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
***********************************************************************/
uchar R1302(uchar ucAddr)
{
uchar ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 读1Byte数据 */
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/********************************************************************
函 数 名:Set1302()
功 能:设置初始时间
说 明:先写地址,后读命令/数据(寄存器多字节方式)
调 用:W1302()
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返 回 值:无
***********************************************************************/
void Set1302(uchar *pClock)
{
uchar i;
uchar ucAddr = 0x80;
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/
for(i =7; i>0; i--)
{
W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */
pClock++;
ucAddr +=2;
}
W1302(0x8e,0x80); /* 控制命令,WP=1,写保护*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -