#include<reg52.h>
#include<intrins.h>
#define GPIO_LCD P0
//DS1302写入和读取时分秒的地址命令
unsigned charREAD_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //秒分时日月周年 最低位读写位};
unsigned charWRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//DS1302时钟初始化2013年1月1日星期二12点00分00秒。存储顺序是秒分时日月周年,存储格式是用BCD码
unsigned charTIME[7]={0x01,0x01,0x12,0x02,0x01,0x01,0x13}; //BCD码
sbit RS=P2^6;
sbit RW=P2^5;
sbit E=P2^7;
sbit SCLK=P3^6;
sbit RST=P3^5;
sbit DSIO=P3^4;
void Delay1us(unsigned int); //延时函数声明
void LCDInit(); //LCD初始化
void LcdWriteCom(unsigned char com); //LCD写入命令
void LcdWriteData(unsigned char dat); //LCD写入数据
void Ds1302Write(unsigned charaddr,unsigned char dat); //1302写入数据
unsigned char Ds1302Read(unsigned charaddr); //1302读操作
void Ds1302Init(void); //
void Ds1302ReadTime(void); //
void LcdDisplay(void);
///////////////////////////////////////////////////////////////
void main()
{
LCDInit();
Ds1302Init();
while(1)
{
Ds1302ReadTime();
LcdDisplay();
}
}
///////////////////////////////////////////////////////////显示函数
void LcdDisplay()
{
LcdWriteCom(0x80+0x40);
LcdWriteData('0'+TIME[2]/16); //时
LcdWriteData('0'+(TIME[2]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[1]/16); //分
LcdWriteData('0'+(TIME[1]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[0]/16); //秒
LcdWriteData('0'+(TIME[0]&0x0f));
LcdWriteCom(0x80);
LcdWriteData('2');
LcdWriteData('0');
LcdWriteData('0'+TIME[6]/16); //年
LcdWriteData('0'+(TIME[6]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[4]/16); //月
LcdWriteData('0'+(TIME[4]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[3]/16); //日
LcdWriteData('0'+(TIME[3]&0x0f));
LcdWriteCom(0x8D);
LcdWriteData('0'+(TIME[5]&0x07)); //星期
}
////////////////////////////////////////////////////////////下面是DS1302
void Ds1302Write(unsigned charaddr,unsigned char dat) //向DS1302写数据
{
unsigned char n;
SCLK=0; //将信号时钟SCLK置低电平
_nop_();
RST=1; //将RST(CE)置高电平
_nop_();
for(n=0;n<8;n++) //开始传送8位地址命令
{
DSIO=addr&0x01; //数据从低位开始传送
addr>>=1; //“>>=”是符合运算符,等于addr右移一位再赋值给addr
SCLK=1; //数据在上升沿时,DS1302读取数据
_nop_();
SCLK=0; //数据在下降沿时,放置数据
_nop_();
}
_nop_();
for(n=0;n<8;n++) //写8位数据
{
DSIO=dat&0x01; //数据从低位开始传送
dat>>=1; //“>>=”是符合运算符,等于addr右移一位再赋值给addr
SCLK=1; //数据在上升沿时,DS1302读取数据
_nop_();
SCLK=0; //数据在下降沿时,放置数据
_nop_();
}
RST=0;
_nop_();
}
////////////////////////////////////////////////////////////////////从DS1302读数据
unsigned char Ds1302Read(unsigned charaddr)
{
unsigned char n,dat,dat1;
SCLK=0; //将信号时钟SCLK置低电平
_nop_();
RST=1; //将RST(CE)置高电平
_nop_();
for(n=0;n<8;n++) //开始传送8位地址命令
{
DSIO=addr&0x01; //数据从低位开始传送
addr>>=1; //“>>=”是符合运算符,等于addr右移一位再赋值给addr
SCLK=1; //数据在上升沿时,DS1302读取数据
_nop_();
SCLK=0; //数据在下降沿时,放置数据
_nop_();
}
_nop_();
for(n=0;n<8;n++) //读取8位数据
{
//dat1=DSIO; //数据从低位开始传送
//dat=dat>>1; //“>>=”是符合运算符
// dat|=dat1<<7;
dat>>=1;
if(DSIO)
dat|=0x80;
SCLK=1; //数据在上升沿时,DS1302读取数据
_nop_();
SCLK=0; //数据在下降沿时,放置数据
_nop_();
}
RST=0;
_nop_(); //下面6行是为了让DS1302复位
SCLK=1;
_nop_();
DSIO=0;
_nop_();
DSIO=1;
_nop_();
return dat;
}
//////////////////////////////////////////////////DS1302初始化
void Ds1302Init()
{
unsignedchar n;
Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能
for(n=0;n<7;n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80); //打开写保护功能
}
///////////////////////////////////////////////////////DS1302读出时间
void Ds1302ReadTime()
{
unsignedchar n;
for(n=0;n<7;n++)//读取7个字节的时钟信号:分秒时日月周年
{
TIME[n]=Ds1302Read(READ_RTC_ADDR[n]);
}
}
///////////////////////////////////////////////下面是LCD的3个子函数和延时函数
void LcdWriteCom(unsigned char com) //写入命令
{
RS=0; //选择命令
RW=0; //写
GPIO_LCD=com;
Delay1us(1);
E=1; //使能信号
Delay1us(1);
E=0;
}
void LcdWriteData(unsigned char dat) //写入数据
{
RS=1;
RW=0;
GPIO_LCD=dat;
Delay1us(1);
E=1;
Delay1us(1);
E=0;
}
void LCDInit() //初始化
{
LcdWriteCom(0x38); //设置16*2显示,5*7点阵,8位数据接口
LcdWriteCom(0x0c); //开显示,不显示光标,不闪烁
LcdWriteCom(0x06); //光标加1,整屏不移动
LcdWriteCom(0x01); //所有显示清零
}
void Delay1us(unsigned int a) //延时函数
{
unsignedint b,c;
for(c=a;c>0;c--)
for(b=110;b>0;b--);
}
#include<intrins.h>
#define GPIO_LCD P0
//DS1302写入和读取时分秒的地址命令
unsigned charREAD_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //秒分时日月周年 最低位读写位};
unsigned charWRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//DS1302时钟初始化2013年1月1日星期二12点00分00秒。存储顺序是秒分时日月周年,存储格式是用BCD码
unsigned charTIME[7]={0x01,0x01,0x12,0x02,0x01,0x01,0x13}; //BCD码
sbit RS=P2^6;
sbit RW=P2^5;
sbit E=P2^7;
sbit SCLK=P3^6;
sbit RST=P3^5;
sbit DSIO=P3^4;
void Delay1us(unsigned int); //延时函数声明
void LCDInit(); //LCD初始化
void LcdWriteCom(unsigned char com); //LCD写入命令
void LcdWriteData(unsigned char dat); //LCD写入数据
void Ds1302Write(unsigned charaddr,unsigned char dat); //1302写入数据
unsigned char Ds1302Read(unsigned charaddr); //1302读操作
void Ds1302Init(void); //
void Ds1302ReadTime(void); //
void LcdDisplay(void);
///////////////////////////////////////////////////////////////
void main()
{
LCDInit();
Ds1302Init();
while(1)
{
Ds1302ReadTime();
LcdDisplay();
}
}
///////////////////////////////////////////////////////////显示函数
void LcdDisplay()
{
LcdWriteCom(0x80+0x40);
LcdWriteData('0'+TIME[2]/16); //时
LcdWriteData('0'+(TIME[2]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[1]/16); //分
LcdWriteData('0'+(TIME[1]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[0]/16); //秒
LcdWriteData('0'+(TIME[0]&0x0f));
LcdWriteCom(0x80);
LcdWriteData('2');
LcdWriteData('0');
LcdWriteData('0'+TIME[6]/16); //年
LcdWriteData('0'+(TIME[6]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[4]/16); //月
LcdWriteData('0'+(TIME[4]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[3]/16); //日
LcdWriteData('0'+(TIME[3]&0x0f));
LcdWriteCom(0x8D);
LcdWriteData('0'+(TIME[5]&0x07)); //星期
}
////////////////////////////////////////////////////////////下面是DS1302
void Ds1302Write(unsigned charaddr,unsigned char dat) //向DS1302写数据
{
unsigned char n;
SCLK=0; //将信号时钟SCLK置低电平
_nop_();
RST=1; //将RST(CE)置高电平
_nop_();
for(n=0;n<8;n++) //开始传送8位地址命令
{
DSIO=addr&0x01; //数据从低位开始传送
addr>>=1; //“>>=”是符合运算符,等于addr右移一位再赋值给addr
SCLK=1; //数据在上升沿时,DS1302读取数据
_nop_();
SCLK=0; //数据在下降沿时,放置数据
_nop_();
}
_nop_();
for(n=0;n<8;n++) //写8位数据
{
DSIO=dat&0x01; //数据从低位开始传送
dat>>=1; //“>>=”是符合运算符,等于addr右移一位再赋值给addr
SCLK=1; //数据在上升沿时,DS1302读取数据
_nop_();
SCLK=0; //数据在下降沿时,放置数据
_nop_();
}
RST=0;
_nop_();
}
////////////////////////////////////////////////////////////////////从DS1302读数据
unsigned char Ds1302Read(unsigned charaddr)
{
unsigned char n,dat,dat1;
SCLK=0; //将信号时钟SCLK置低电平
_nop_();
RST=1; //将RST(CE)置高电平
_nop_();
for(n=0;n<8;n++) //开始传送8位地址命令
{
DSIO=addr&0x01; //数据从低位开始传送
addr>>=1; //“>>=”是符合运算符,等于addr右移一位再赋值给addr
SCLK=1; //数据在上升沿时,DS1302读取数据
_nop_();
SCLK=0; //数据在下降沿时,放置数据
_nop_();
}
_nop_();
for(n=0;n<8;n++) //读取8位数据
{
//dat1=DSIO; //数据从低位开始传送
//dat=dat>>1; //“>>=”是符合运算符
// dat|=dat1<<7;
dat>>=1;
if(DSIO)
dat|=0x80;
SCLK=1; //数据在上升沿时,DS1302读取数据
_nop_();
SCLK=0; //数据在下降沿时,放置数据
_nop_();
}
RST=0;
_nop_(); //下面6行是为了让DS1302复位
SCLK=1;
_nop_();
DSIO=0;
_nop_();
DSIO=1;
_nop_();
return dat;
}
//////////////////////////////////////////////////DS1302初始化
void Ds1302Init()
{
unsignedchar n;
Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能
for(n=0;n<7;n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80); //打开写保护功能
}
///////////////////////////////////////////////////////DS1302读出时间
void Ds1302ReadTime()
{
unsignedchar n;
for(n=0;n<7;n++)//读取7个字节的时钟信号:分秒时日月周年
{
TIME[n]=Ds1302Read(READ_RTC_ADDR[n]);
}
}
///////////////////////////////////////////////下面是LCD的3个子函数和延时函数
void LcdWriteCom(unsigned char com) //写入命令
{
RS=0; //选择命令
RW=0; //写
GPIO_LCD=com;
Delay1us(1);
E=1; //使能信号
Delay1us(1);
E=0;
}
void LcdWriteData(unsigned char dat) //写入数据
{
RS=1;
RW=0;
GPIO_LCD=dat;
Delay1us(1);
E=1;
Delay1us(1);
E=0;
}
void LCDInit() //初始化
{
LcdWriteCom(0x38); //设置16*2显示,5*7点阵,8位数据接口
LcdWriteCom(0x0c); //开显示,不显示光标,不闪烁
LcdWriteCom(0x06); //光标加1,整屏不移动
LcdWriteCom(0x01); //所有显示清零
}
void Delay1us(unsigned int a) //延时函数
{
unsignedint b,c;
for(c=a;c>0;c--)
for(b=110;b>0;b--);
}