//寫的時候,是低電平改變數據,上升沿送入數據
//讀的時候,是低電平讀入數據,下降沿使得從設備把數據放到總線上
//讀的時候,是低電平讀,但沒有讀出,提供下降沿使得從設備把數據放到總線上
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs="P2"^4;
sbit rw="P2"^5;
sbit en="P3"^6;
sbit reset="P3"^3;
sbit sclk="P3"^0;
sbit io="P3"^1;
uchar str1[]="date of today is:";
uchar init[]={0x00,0x00,0x21,0x21,0x10,0x01,0x04};//秒,分,時,日,月,星期,年
//
void delay()
{uchar j;
for(j=250;j>0;j--);
}
//-------------------液晶模塊-----------------//
void en_toggle()
{
en=0;
//_nop_();
delay();
en=1;
delay();
// _nop_();
en=0;
} //注意必須加延時,否則會出問題的
void is_ready()
{
P2=0x00;//設置為輸入口 //注意:現實中應該送0xff
rs=0;
rw=1;
en=1;
while(bflag);
en=0;
}
void write_cmd(uchar cmd)
{
is_ready();
rs=0;
rw=0;
P2=cmd;
en_toggle();
_nop_();
}
void write_data(uchar indata)
{
is_ready();
rs=1;
rw=0;
P2=indata;
en_toggle();
_nop_();
}
void write_str(uchar addr,uchar *p)
{
uchar i;
write_cmd(addr);
while(p[i]!='\0')
{write_data(p[i]);
i++;
}
}
void write_position(uchar row,uchar col)
{uchar p;
if(row==1)
{p=0x80+col-1;
write_cmd(p);}
else
{p=0xc0+col-1;
write_cmd(p);
}
}
void init_lcd()
{
write_cmd(0x38);
write_cmd(0x0c);
write_cmd(0x06);
write_cmd(0x01);//清屏幕
}
//------------液晶模塊結束---------------------
//-----------ds1302模塊開始-------------------
//注意點:sclk的上升沿輸入數據,sclk的下跳沿輸出數據
//讀寫時都是從第0位開始
void write_byte(uchar inbyte)
{
uchar i;
for(i=8;i>0;i--)
{
sclk=0; //寫的時候低電平改變數據
if(inbyte&0x01)
io=1;
else
io=0;
sclk=1; //寫的時候高電平,把數據寫入ds1302
_nop_();
inbyte=inbyte>>1;
}
}
uchar read_byte() //sclk的下跳沿讀數據
{
uchar i,temp=0;
io=1; //設置為輸入口
for(i=7;i>0;i--)
{
sclk=0;
if(io==1)
temp=temp|0x80;
else
temp=temp&0x7f;
sclk=1; //產生下跳沿
temp=temp>>1;
}
return (temp);
}
//----------往ds1302的某個地址寫入數據-------------
void write_ds1302(uchar cmd,uchar indata)
{
reset=1;
write_byte(cmd);
write_byte(indata);
reset=0;
sclk=0;
}
//----------讀ds1302某地址的的數據-----------------
uchar read_ds1302(uchar addr)
{
uchar backdata;
reset=1;
write_byte(addr);
backdata=read_byte();//先寫地址,然后讀數據
reset=0;
sclk=0;
return (backdata);
}
//------------設置初始時間-------------------
void set_ds1302(uchar addr,uchar *p,uchar n)//寫入n個數據
{
write_ds1302(0x8e,0x00);//寫控制字,允許寫操作
for(;n>0;n--)
{write_ds1302(addr,*p);
p++;
addr=addr+2;
}
write_ds1302(0x8e,0x80);//寫保護,不允許寫
}
//----------- 讀取當前時間-------------------
void read_nowtime(uchar addr,uchar *p,uchar n)
{
for(;n>0;n--)
{
*p=read_ds1302(addr);
p++;
addr=addr+2;
}
}
void init_ds1302()
{
reset=0;
sclk=0;
write_ds1302(0x80,0x00);//寫控制字,允許寫
write_ds1302(0x90,0x00);//禁止渦流充電
}
//-----------ds1302模塊結束-------------------
void main()
{
init_lcd(); //初始化LCD
write_str(0x80,str1); //液晶顯示提示信息
init_ds1302(); //初始化ds1302
set_ds1302(0x80,init,7);//設置初始時間,日期,年月
//如果不設置初始化時間的話,則默認為系統時間
while(1)
{
read_nowtime(0x81,init,7); //讀出當前時間,讀出7個字節
write_position(2,1);
write_data('0'+((init[2]&0xf0)>>4));
write_position(2,2);
write_data('0'+(init[2]&0x0f)); //讀小時
write_position(2,3);
write_data(':');
write_position(2,4);
write_data('0'+((init[1]&0xf0)>>4));
write_position(2,5);
write_data('0'+(init[1]&0x0f)); //讀分鐘
write_position(2,6);
write_data(':');
write_position(2,7);
write_data('0'+((init[0]&0xf0)>>4));
write_position(2,8);
write_data('0'+(init[0]&0x0f)); //讀秒
write_position(2,13);
write_data('0'+((init[6]&0xf0)>>4));
write_position(2,14);
write_data('0'+(init[6]&0x0f)); //讀年
write_position(2,15);
write_data('/');
write_position(2,16);
write_data('0'+((init[4]&0xf0)>>4));
write_position(2,17);
write_data('0'+(init[4]&0x0f)); //讀月
write_position(2,18);
write_data('/');
write_position(2,19);
write_data('0'+((init[3]&0xf0)>>4));
write_position(2,20);
write_data('0'+(init[3]&0x0f)); //讀日
|