#include
#define uint unsigned int
#define uchar unsigned char
sbit RS=P3^5;//数据/命令选择线
sbit EL=P3^6;//使能信号线
sbit ls164_clk=P1^1;//控制时钟
sbit ls164_dat=P1^2;//数据输入
sbit ds1302_clk=P1^5;//脉冲线
sbit ds1302_io=P1^6;//数据线
sbit ds1302_rst=P1^7;//复位控制线
uchar kk[]={'0','1','2','3','4','5','6','7','8','9'};
uchar y1,y2;
//--------------------------------------
void delay1(uint z)//延时函数
{
uint x,y;
for (x=z;x>0;x--)
for(y=0;y<100;y++);
}
void ls164_in(uchar dat )//74ls164控制输入
{
uchar i,a;
a=dat;
for(i=0;i<8;i++)
{
if(a&0x80)
{
ls164_dat=1;
ls164_clk=1;
ls164_clk=0;
}
else
{
ls164_dat=0;
ls164_clk=1;
ls164_clk=0;
}
a=a<<1;
}
}
void comand_1602(uchar com)//1602命令输入
{
ls164_in(com);//命令输入
RS=0;
EL=0;
delay1(1);
EL=1;
delay1(1);
EL=0;
//delay(2);
//EL=0;
}
void indat_1602(uchar dat)//1602数据输入
{
ls164_in(dat);//命令输入
RS=1;
EL=0;
delay1(1);
EL=1;
delay1(1);
EL=0;
}
void innit_1602()//1602初始化
{
comand_1602(0x38);//功能设定
delay1(20);
comand_1602(0x38);//功能设定
delay1(20);
comand_1602(0x38);//功能设定
delay1(20);
//----------------------
comand_1602(0x38);//分两行显示,5*7显示方式
delay1(20);
comand_1602(0x0f);//开显示,有光标,光标闪烁
delay1(20);
comand_1602(0x01);//清屏
delay1(20);
comand_1602(0x06);//输入时光标自动向右移动一格,并且加一
delay1(20);
}
//----------------------------------------------
void delay(uint z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=4;y>0;y--);
}
uchar ds1302_read()//读出数据
{
uchar i,b=0;
//delay(1);
ds1302_clk=0;
for(i=0;i<8;i++)
{
if(ds1302_io==1)
{
b=b|0x80;//先读低位
}
else
{
b=b|0x00;
}
ds1302_clk=1;
ds1302_clk=0;
if (i<7) b=b>>1;
}
//ds1302_rst=0;
return(b);
}
void ds1302_write(uchar com)
{
uchar i,a;
a=com;
ds1302_clk=0;
for(i=0;i<8;i++)
{
if(a&0x01)
{
ds1302_io=1;//先写低位
}
else
{
ds1302_io=0;
}
ds1302_clk=1;
ds1302_clk=0;
a=a>>1;
}
//ds1302_rst=0;
}
uchar ds1302_read_baye(uchar adrr)
{
uchar aa;
ds1302_rst=0;
ds1302_clk=0;
ds1302_rst=1;
ds1302_write(adrr);//写入地址
ds1302_io=0;
aa=ds1302_read();
ds1302_clk=1;
ds1302_rst=0;
return (aa);
}
uchar ds1302_write_baye(uchar adrr,dat)
{
ds1302_rst=0;
ds1302_clk=0;
ds1302_rst=1;
ds1302_write(adrr);//写入地址
//ds1302_io=1;
ds1302_write(dat);
ds1302_clk=1;
ds1302_rst=0;
}
uchar go10to16(uchar u)//10进制转换为16进制
{
uchar a,b,c;
if (u<16)//小于16不用转换
{
return(u);
}
else
{
a=u/16;//取商
b=u%16;//取模
c=a*10+b;
return(c);
}
}
void cuanhuan(uchar i)
{
uchar a,b;
a=i;
b=go10to16(a);
if(b>0&b<10)
{
y1=kk[0];
y2=kk[b];
}
else
{
y1=kk[b/10];
y2=kk[b%10];
}
}
/*-----------------------------------------------------------
此函数在第一次用到DS1302时才用,初此化后,以后就不用初始化了,
除非你想再一次设定DS1302才用,注意填写10位与个位所放的位置,
如我要设27号,应为:0010 0111
10位放在这 个位放在这
而不是0x1B 0001 1011
-------------------------------------------------------------*/
void ds1302int(uchar year,moon,date,hour,mini,sen)//当DS1302第一次使用时要进行设置
{
ds1302_rst=0;
ds1302_clk=0;
ds1302_rst=1;
ds1302_write(0x8e);
ds1302_write(0x00);
ds1302_rst=0;
ds1302_clk=1;
ds1302_write_baye(0x8c,year);//设置年为08年
ds1302_write_baye(0x88,moon);//设置月为3月
ds1302_write_baye(0x86,date);//设置日为27号
ds1302_write_baye(0x84,hour);//设置时9时
ds1302_write_baye(0x82,mini);//设置分为5分
ds1302_write_baye(0x80,sen);//设置秒为00秒
ds1302_rst=0;
ds1302_clk=0;
ds1302_rst=1;
ds1302_write(0x8e);
ds1302_write(0x80);
}
void main()
{
delay1(20);
innit_1602();//1602初始化
ds1302int(8,3,0x27,9,0x27,0);//DS1302初始化
while(1)
{
comand_1602(0x80);//在址00开始显示,第一行显示年-月-日
cuanhuan(ds1302_read_baye(0x8d));
indat_1602(y1);//显示年
indat_1602(y2);
indat_1602('-');
cuanhuan(ds1302_read_baye(0x89));//读出月份
indat_1602(y1);//显示月
indat_1602(y2);
indat_1602('-');
cuanhuan(ds1302_read_baye(0x87));//读出日
indat_1602(y1);//显示日
indat_1602(y2);
comand_1602(0x80+0x40);//在第二行显示时:分:秒
cuanhuan(ds1302_read_baye(0x85));//读出时
indat_1602(y1);//显示时
indat_1602(y2);
indat_1602(':');
cuanhuan(ds1302_read_baye(0x83));//读出分
indat_1602(y1);//显示分
indat_1602(y2);
indat_1602(':');
cuanhuan(ds1302_read_baye(0x81));//读出秒
indat_1602(y1);//显示秒
indat_1602(y2);
}
}