两天的成果, /*************************************/ #include<reg52.h> #define uint unsigned int #define uchar unsigned char uchar year,month,day,week,hours,minutes,seconds; uchar flag1302,cnt; /************************************* 控制按键 *************************************/ sbit K1=P1^0; sbit K2=P1^2; sbit K3=P1^4; /************************************* 控制LCD液晶显示 *************************************/ sbit lcdwrite=P2^5; sbit lcddatecommand=P2^6; sbit lcde=P2^7; /************************************* 控制DS1302时钟 *************************************/ sbit SCK=P3^6; sbit RST=P3^5; sbit SDA=P3^4; /************************************* 延时子函数 *************************************/ void delay(uint z) { uint x,y; for(x=z;x>0;x--) { for(y=0;y<=112;y++) { } } } /************************************* LCD写命令函数 *************************************/ void write_command(uchar command) { lcddatecommand=0; //开启写命令 lcdwrite=0; //只写不读 P0=command; delay(1); lcde=1; //形成使能E高脉冲 delay(1); lcde=0; //使能E拉低 } /************************************* LCD写数据函数 *************************************/ void write_date(uchar date) { lcddatecommand=1; //开启写数据 lcdwrite=0; //只写不读 P0=date; delay(1); lcde=1; //形成使能E高脉冲 delay(1); lcde=0; //使能E拉低 } /************************************* LCD屏幕初始化 *************************************/ void lcdInit() { lcde=0; write_command(0x38);//设置16*2显示,5*7点阵,8位数据接口 write_command(0x0c);//设置开显示,不显示光标 write_command(0x06);// 写一个字符后地址指针加1 write_command(0x01);//显示清0,数据指针清0 } /************************************* DS1302写字节函数 *************************************/ void write_1302byte(uchar date) { uchar i; for(i=0;i<8;i++) { SCK=0; SDA=date&0x01; date=date>>1; SCK=1;//将电平置为已知状态 } } /************************************* DS1302读字节函数 *************************************/ uchar read_1302byte(uchar address) { uchar i,temp; temp=0x00; RST=0; delay(1); SCK=0; delay(1); RST=1; delay(1); write_1302byte(address); for(i=0;i<8;i++) { if(SDA==1) { temp=temp|0x80; //每次传输低字节 } temp=temp>>1; SCK=1; delay(1); SCK=0; delay(1); } return temp; } /************************************* 往DS1302中写数据 *************************************/ void write_1302(uchar address,uchar date) { RST=0; delay(1); SCK=0; delay(1); RST=1; delay(1); write_1302byte(address); write_1302byte(date); RST=0; } /************************************* 往DS1302中读取数据 *************************************/ uchar read_1302(uchar address) { uchar date; RST=0; SCK=0; RST=1; write_1302byte(address); date=read_1302byte(address); SCK=1; RST=0; return date; } /************************************* 初始化时间 *************************************/ void Init_1302() { write_1302(0x8e,0x00); //写入不保护指令 write_1302(0x80,(14/10)<<4|(14%10));//14秒钟 write_1302(0x82,(7/10)<<4|(7%10)); //7分钟 write_1302(0x84,(3/10)<<4|(3%10)); //3小时 write_1302(0x86,(6/10)<<4|(6%10)); //6日 write_1302(0x88,(6/10)<<4|(6%10)); //6月 write_1302(0x8A,(4/10)<<4|(4%10)); //周四 write_1302(0x8C,(13/10)<<4|(13%10));//13年 write_1302(0x90,0xa5); //打开充电功能,选择2K电阻充电方式 write_1302(0x8e,0x80); //写保护 } /************************************* 时钟显示 *************************************/ void DisplayHours(uchar hours) { uchar shi,ge; shi=hours/10; ge=hours%10; write_command(0x06); write_command(0x80+0x40); write_date(shi+48); write_date(ge+48); write_date(':'); } /************************************* 分钟显示 *************************************/ void DisplayMinutes(uchar minutes) { uchar shi,ge; shi=minutes/10; ge=minutes%10; write_command(0x06); write_command(0x80+0x43); write_date(shi+48); write_date(ge+48); write_date(':'); } /************************************* 秒钟显示 *************************************/ void DisplaySeconds(uchar seconds) { uchar shi,ge; shi=seconds/10; ge=seconds%10; write_command(0x06); write_command(0x80+0x46); write_date(shi+48); write_date(ge+48); } /************************************* 年份显示 *************************************/ void DisplayYear(uchar years) { uchar shi,ge; shi=years/10; ge=years%10; write_command(0x06); write_command(0x80+0x00); write_date(shi+48); write_date(ge+48); write_date('-'); } /************************************* 月份显示 *************************************/ void DisplayMonth(uchar month) { uchar shi,ge; shi=month/10; ge=month%10; write_command(0x06); write_command(0x80+0x03); write_date(shi+48); write_date(ge+48); write_date('-'); } /************************************* 日显示 *************************************/ void DisplayDay(uchar day) { uchar shi,ge; shi=day/10; ge=day%10; write_command(0x06); write_command(0x80+0x06); write_date(shi+48); write_date(ge+48); } /************************************* 礼拜显示 *************************************/ void DisplayWeek(uchar week) { uchar i; i=week; write_command(0x06); write_command(0x80+0x09); switch(i) { case 1:write_date('M');write_date('O');write_date('N'); break; case 2:write_date('T');write_date('H');write_date('E'); break; case 3:write_date('W');write_date('E');write_date('D'); break; case 4:write_date('T');write_date('H');write_date('U'); break; case 5:write_date('F');write_date('R');write_date('I'); break; case 6:write_date('S');write_date('A');write_date('T'); break; case 7:write_date('S');write_date('U');write_date('N'); break; } } /************************************* 读取日期 *************************************/ void read_date() { uchar ReadValue; ReadValue = read_1302(0x81); seconds=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = read_1302(0x83); minutes=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = read_1302(0x85); hours=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = read_1302(0x87); day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = read_1302(0x89); month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = read_1302(0x8d); year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue=read_1302(0x8b); week=ReadValue&0x07; DisplaySeconds(seconds); DisplayMinutes(minutes); DisplayHours(hours); DisplayDay(day); DisplayMonth(month); DisplayYear(year); DisplayWeek(week); } /************************************* 修改日期 *************************************/ void change() { uchar temp,nian,yue,ri,zhou,shi,fen,miao; if(K1==0) { delay(5); if(K1==0)//证明功能键确实按下 { cnt++;//计数器,计算按下的次数 write_1302(0x8e,0x00);//关闭写保护 } } /******************************************* 修改年份 *******************************************/ if(cnt==1) { temp=read_1302(0x8d); nian=((temp&0x70)>>4)*10+(temp&0x0F); if(K2==0) { delay(5); if(K2==0)//K2键实现加 { while(!K2); delay(5); while(!K2);//确保K2键松开 nian++; if(nian>=100) { nian=0; } write_1302(0x8e,0x00); write_1302(0x8c,(nian/10)<<4|(nian%10)); DisplayYear(nian); write_1302(0x8e,0x80); } } if(K3==0) { delay(5); if(K3==0)//K3键实现减 { while(!K3); delay(5); while(!K3);//确保K3键松开 nian--; if(nian==-1) { nian=99; } write_1302(0x8e,0x00); write_1302(0x8c,(nian/10)<<4|(nian%10)); DisplayYear(nian); write_1302(0x8e,0x80); } } } /******************************************* 修改月份 *******************************************/ if(cnt==2) { temp=read_1302(0x89); yue=((temp&0x70)>>4)*10+(temp&0x0F); if(K2==0) { delay(5); if(K2==0)//K2键实现加 { while(!K2); delay(5); while(!K2);//确保K2键松开 yue++; if(yue>=12) { yue=1; } write_1302(0x8e,0x00); write_1302(0x88,(yue/10)<<4|(yue%10)); DisplayMonth(yue); write_1302(0x8e,0x80); } } if(K3==0) { delay(5); if(K3==0)//K3键实现减 { while(!K3); delay(5); while(!K3);//确保K3键松开 yue--; if(yue==0) { yue=12; } write_1302(0x8e,0x00); write_1302(0x88,(yue/10)<<4|(yue%10)); DisplayMonth(yue); write_1302(0x8e,0x80); } } } /******************************************* 修改天数 *******************************************/ if(cnt==3) { temp=read_1302(0x87); ri=((temp&0x70)>>4)*10+(temp&0x0F); if(K2==0) { delay(5); if(K2==0)//K2键实现加 { while(!K2); delay(5); while(!K2);//确保K2键松开 ri++; if(ri>=32) { ri=1; } write_1302(0x8e,0x00); write_1302(0x86,(ri/10)<<4|(ri%10)); DisplayDay(ri); write_1302(0x8e,0x80); } } if(K3==0) { delay(5); if(K3==0)//K3键实现减 { while(!K3); delay(5); while(!K3);//确保K3键松开 ri--; if(ri==0) { ri=31; } write_1302(0x8e,0x00); write_1302(0x86,(ri/10)<<4|(ri%10)); DisplayDay(ri); write_1302(0x8e,0x80); } } } /******************************************* 修改周 *******************************************/ if(cnt==4) { temp=read_1302(0x8B); zhou=((temp&0x70)>>4)*10+(temp&0x0F); if(K2==0) { delay(5); if(K2==0)//K2键实现加 { while(!K2); delay(5); while(!K2);//确保K2键松开 zhou++; if(zhou>=8) { zhou=1; } write_1302(0x8e,0x00); write_1302(0x8a,(zhou/10)<<4|(zhou%10)); DisplayWeek(zhou); write_1302(0x8e,0x80); } } if(K3==0) { delay(5); if(K3==0)//K3键实现减 { while(!K3); delay(5); while(!K3);//确保K3键松开 zhou--; if(zhou==-1) { zhou=7; } write_1302(0x8e,0x00); write_1302(0x8a,(zhou/10)<<4|(zhou%10)); DisplayWeek(zhou); write_1302(0x8e,0x80); } } } /******************************************* 修改小时 *******************************************/ if(cnt==5) { temp=read_1302(0x85); shi=((temp&0x70)>>4)*10+(temp&0x0F); if(K2==0) { delay(5); if(K2==0)//K2键实现加 { while(!K2); delay(5); while(!K2);//确保K2键松开 shi++; if(shi>=24) { shi=0; } write_1302(0x8e,0x00); write_1302(0x84,(shi/10)<<4|(shi%10)); DisplayHours(shi); write_1302(0x8e,0x80); } } if(K3==0) { delay(5); if(K3==0)//K3键实现减 { while(!K3); delay(5); while(!K3);//确保K3键松开 shi--; if(shi==-1) { shi=23; } write_1302(0x8e,0x00); write_1302(0x84,(shi/10)<<4|(shi%10)); DisplayHours(shi); write_1302(0x8e,0x80); } } } /******************************************* 修改分钟 *******************************************/ if(cnt==6) { temp=read_1302(0x83); fen=((temp&0x70)>>4)*10+(temp&0x0F); if(K2==0) { delay(5); if(K2==0)//K2键实现加 { while(!K2); delay(5); while(!K2);//确保K2键松开 fen++; if(fen>=60) { fen=0; } write_1302(0x8e,0x00); write_1302(0x82,(fen/10)<<4|(fen%10)); DisplayMinutes(fen); write_1302(0x8e,0x80); } } if(K3==0) { delay(5); if(K3==0)//K3键实现减 { while(!K3); delay(5); while(!K3);//确保K3键松开 fen--; if(fen==-1) { fen=59; } write_1302(0x8e,0x00); write_1302(0x82,(fen/10)<<4|(fen%10)); DisplayMinutes(fen); write_1302(0x8e,0x80); } } } /******************************************* 修改秒钟 *******************************************/ if(cnt==7) { temp=read_1302(0x81); miao=((temp&0x70)>>4)*10+(temp&0x0F); if(K2==0) { delay(5); if(K2==0)//K2键实现加 { while(!K2); delay(5); while(!K2);//确保K2键松开 miao++; if(miao>=60) { miao=0; } write_1302(0x8e,0x00); write_1302(0x80,(miao/10)<<4|(miao%10)); DisplaySeconds(miao); write_1302(0x8e,0x80); } } if(K3==0) { delay(5); if(K3==0)//K3键实现减 { while(!K3); delay(5); while(!K3);//确保K3键松开 miao--; if(miao==-1) { miao=59; } write_1302(0x8e,0x00); write_1302(0x80,(miao/10)<<4|(miao%10)); DisplaySeconds(miao); write_1302(0x8e,0x80); } } } if(cnt==8) { cnt=0; } } /************************************* 主函数 *************************************/ void main() { lcdInit(); flag1302=read_1302(0x81); if(flag1302&0x80)//秒钟的最高位为1才需要初始化 { Init_1302(); } while(1) { change(); read_date(); } }