你的問題加了注釋如下:
#include <reg52.h>
#include <intrins.h>
#define lcd1602data P0
typedef unsigned char u8;
typedef unsigned int u16;
sbit E=P2^7;
sbit RW=P2^5;
sbit RS=P2^6;
sbit key1=P3^1;
sbit key2=P3^0;
sbit key3=P3^2;
sbit SCLK=P3^6;
sbit IO=P3^4;
sbit RST=P3^5;
u16 read[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //這是讀DS1302時鐘數據的地址"秒 分 小時 日 月 星期 年"
u16 write[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //這是寫DS1302時鐘數據的地址"秒 分 小時 日 月 星期 年"
u8 time[]={0x15,0x27,0x09,0x15,0x02,0x06,0x20}; //這是設置DS1302時鐘數據"秒 分 小時 日 月 星期 年"
//以上數據不需要轉換,可以認為是十六制數,可以認為BCD碼,16進制數只是BCD碼的一種表現形式,即BCD數據中不可能出現A-F數碼
u16 setmark,setplace;
void delay_ms(u16 n);
void initConfiguration();
void lcdDisplay();
void lcdwrite_com(u8 datas);
void lcdwrite_datas(u8 datas);
void lcdinit();
void writebyte(u8 address,u8 datas);
u8 readbyte(u8 address);
void ds1302init();
void read_time();
void main()
{
u16 i;
initConfiguration();
lcdinit();
ds1302init();
while(1)
{
if(setmark==0)
{
read_time();
}
else
{
if(key1==0) //按鍵1操作
{
delay_ms(1);
if(key1==0)
{
setplace++;
setplace%=7;
}
while(i<50&&key1==0)
{
i++;
delay_ms(10);
}
i=0;
}
if(key2==0) //按鍵2操作
{
delay_ms(1);
if(key2==0)
{
time[setplace]++; //按鍵設置的時鐘數據處理
if((time[setplace]&0x0f)>9) //每次加1后出現A-F數據不符合BCD,所以要保證數據只有0-9
{
time[setplace]=time[setplace]+6;
}
if((time[setplace]>=0x60)&&(setplace<2)) //保證分鐘在十進制00-59間變化
{
time[setplace]=0;
}
if((time[setplace]>=0x24)&&(setplace==2)) //保證小時在十進制00-23之間變化
{
time[setplace]=0;
}
if((time[setplace]>=0x32)&&(setplace==3)) //保證日期在十進制1-31之間變化
{
time[setplace]=0;
}
if((time[setplace]>=0x13)&&(setplace==4)) //保證月份在十進制1-12之間變化
time[setplace]=0;
}
if((time[setplace]>=0x7)&&(setplace==5)) //保證星期在十進制0-6之間變化 0表示星期天 1-6表示星期一至六
{
time[setplace]=1;
}
}
while((i<50)&&(0==key2))
{
i++;
delay_ms(10);
}
i=0;
}
}
lcdDisplay();
}
}
void delay_ms(u16 n)
{
u16 a,b;
for(;n>0;n--)
{
for(a=199;a>0;a--)
{
for(b=1;b>0;b--)
{
;
}
}
}
}
void initConfiguration()
{
EA=1;
IT0=1;
EX0=1;
}
void init0() interrupt 0
{
delay_ms(10);
if(key3==0) //按鍵3在中斷里判斷是不行的 這個中斷程序是有問題的
{
setmark=~setmark;
setplace=0;
ds1302init();
}
}
void lcdDisplay() //LCD顯示程序
{
lcdwrite_com(0x80+0x01);
lcdwrite_datas('d');
lcdwrite_datas('a');
lcdwrite_datas('t');
lcdwrite_datas('e');
lcdwrite_datas(':');
lcdwrite_datas('2');
lcdwrite_datas('0');
lcdwrite_datas('0'+time[6]/16); //顯示年份十位
lcdwrite_datas('0'+(time[6]&0x0f)); //顯示年份個位
lcdwrite_datas('-');
lcdwrite_datas('0'+time[4]/16); //顯示月份十位
lcdwrite_datas('0'+(time[4]&0x0f)); //顯示月份個位
lcdwrite_datas('-');
lcdwrite_datas('0'+time[3]/16); //顯示日期十位
lcdwrite_datas('0'+(time[3]&0x0f)); //顯示日期個位
lcdwrite_com(0x80+0x0f);
lcdwrite_datas('0'+(time[5]&0x07)); //顯示星期 讀出的星期數據只有最低3位是表示星期,其它位可能表示12時制或24時制
//&07的目的去掉不需的內容
lcdwrite_com(0x80+0x40);
lcdwrite_datas('t');
lcdwrite_datas('i');
lcdwrite_datas('m');
lcdwrite_datas('e');
lcdwrite_datas(':');
lcdwrite_datas('0'+time[2]/16);
lcdwrite_datas('0'+(time[2]&0x0f));
lcdwrite_datas('-');
lcdwrite_datas('0'+time[1]/16);
lcdwrite_datas('0'+(time[1]&0x0f));
lcdwrite_datas('-');
lcdwrite_datas('0'+time[0]/16);
lcdwrite_datas('0'+(time[0]&0x0f));
}
void lcdwrite_com(u8 datas)
{
E=0;
RW=0;
RS=0;
lcd1602data=datas;
delay_ms(1);
E=1;
delay_ms(1);
E=0;
}
void lcdwrite_datas(u8 datas)
{
E=0;
RW=0;
RS=1;
lcd1602data=datas;
delay_ms(1);
E=1;
delay_ms(1);
E=0;
}
void lcdinit()
{
lcdwrite_com(0x38);
lcdwrite_com(0x0c);
lcdwrite_com(0x06);
lcdwrite_com(0x01);
lcdwrite_com(0x80);
}
void writebyte(u8 address,u8 datas)
{
u8 i;
RST=0;
_nop_();
SCLK=0;
_nop_();
RST=1;
_nop_();
for(i=0;i<8;i++)
{
IO=address&0x01;
address>>=1;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
for(i=0;i<8;i++)
{
IO=datas&0x01;
datas>>=1;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
RST=0;
}
u8 readbyte(u8 address)
{
u8 i,datas,dat;
RST=0;
_nop_();
SCLK=0;
_nop_();
RST=1;
_nop_();
for(i=0;i<8;i++)
{
IO=address&0x01;
address>>=1;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
_nop_();
for(i=0;i<8;i++)
{
dat=IO;
datas=(datas>>1)|(dat<<7);
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
RST=0;
_nop_();
SCLK=1;
_nop_();
IO=0;
_nop_();
IO=1;
_nop_();
return datas;
}
void ds1302init()
{
u8 i;
writebyte(0x8e,0x00);
for(i=0;i<7;i++)
{
writebyte(write[i],time[i]);
}
writebyte(0x8e,0x80);
}
void read_time()
{
u8 i;
for(i=0;i<7;i++)
{
time[i]=readbyte(read[i]);
}
} |