#include<reg52.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int //定義的的4個鍵盤 sbit s1=P3^0; //時鐘功能鍵 sbit s2=P3^1; //加鍵 sbit s3=P3^2; //減鍵 sbit s4=P3^6; //確認鍵 sbit s5=P3^3; //鬧鐘功能鍵 sbit dula=P2^6; //數碼管操作 sbit wela=P2^7; sbit lcden=P2^5; //液晶操作 sbit lcdrs=P1^0; sbit lcdrw=P1^1; sbit rd=P3^7; //為了分離出3個獨立鍵盤 sbit FM=P2^3; //蜂鳴器口 sbit ACC0=ACC^0; //累加器喂ACC 這是位定義 sbit ACC7=ACC^7; sbit sclk=P2^1; //DS1302操作 sbit data1=P2^0; sbit rst=P2^4; uchar s1num,flag1,flag2,s5num; int miao,shi,fen,nian,yue,ri,week,afen,ashi; int x1,x2; uchar code table1[]="SUN";//星期字表 uchar code table2[]="MON"; uchar code table3[]="TUE"; uchar code table4[]="WED"; uchar code table5[]="THU"; uchar code table6[]="FRI"; uchar code table7[]="SAT"; void delayms(uint xms) //延時函數 { uint x,y; for(x=xms;x>0;x--) for(y=110;y>0;y--); } void di() //蜂鳴器函數 { FM=0; delayms(100); FM=1; } void cmg88() //關數碼管函數 { dula=1; P0=0x00; dula=0; } void write_com(uchar com) //液晶寫命令函數 { lcdrs=0; lcden=0; P0=com; delayms(5); lcden=1; delayms(5); lcden=0; } void write_date(uchar date) //液晶寫數據函數 { lcdrs=1; lcden=0; P0=date; delayms(5); lcden=1; delayms(5); lcden=0; } void Write1302(uchar dat) //向1302寫一個字節數據 { uchar i; ACC=dat; for(i=8;i>0;i--) { data1=ACC0; sclk=1; sclk=0; ACC=ACC>>1; } } void WriteSet1302(uchar Cmd,uchar dat) //根據命令,向1302寫一個字節數據 { rst=0; _nop_(); sclk=0; _nop_(); rst=1; delayms(2); Write1302(Cmd); Write1302(dat); sclk=1; rst=0; } uchar Read1302() //向1302讀一個字節數據 { uchar i; for(i=8;i>0;i--) { ACC=ACC>>1; ACC7=data1; sclk=1; sclk=0; } return(ACC); } uchar ReadSet1302(uchar Cmd) //根據命令,向1302讀一個字節數據 { uchar dat; rst=0; sclk=0; rst=1; Write1302(Cmd); dat=Read1302(); sclk=1; rst=0; return(dat); } void inital_1302() // 初始化DS1302函數 { WriteSet1302(0x8e,0x00); //禁止寫保護 WriteSet1302(0x90,0xaa); //定義充電 WriteSet1302(0x80,0x45); //秒 WriteSet1302(0x84,0x18); // 時 WriteSet1302(0x82,0x47); // 分 WriteSet1302(0x8c,0x16); //年 WriteSet1302(0x88,0x05); //月 WriteSet1302(0x86,0x23); //日 WriteSet1302(0x8a,0x01); //星期 WriteSet1302(0xc0,0x07); //鬧鐘小時初始化 WriteSet1302(0xfc,0x30); //鬧鐘分鐘初始化 WriteSet1302(0x8e,0x80); //開寫保護 } void write_sfm(uchar add,uchar dat) //時分秒函數 { uchar gw,sw; gw=dat%16; sw=dat/16; write_com(0x80+0x40+add); write_date(sw+0x30); write_date(gw+0x30); } void write_nyr(uchar add,uchar dat) //年月日函數 { uchar gw,sw; gw=dat%16; sw=dat/16; write_com(0x80+add); write_date(sw+0x30); write_date(gw+0x30); } void write_week(uchar xq) //寫星期函數 { uchar x; write_com(0x80+12); switch(xq) { case 1: for(x=0;x<3;x++) { write_date(table1[x]); } break; case 2: for(x=0;x<3;x++) { write_date(table2[x]); } break; case 3: for(x=0;x<3;x++) { write_date(table3[x]); } break; case 4: for(x=0;x<3;x++) { write_date(table4[x]); } break; case 5: for(x=0;x<3;x++) { write_date(table5[x]); } break; case 6: for(x=0;x<3;x++) { write_date(table6[x]); } break; case 7: for(x=0;x<3;x++) { write_date(table7[x]); } break; } write_com(0x80+12); } void init() //初始化操作 { flag1=0; flag2=0; rd=0; dula=0; wela=0; lcdrw=0; lcden=0; fen=0; miao=0; shi=0; week=0; nian=0; yue=0; ri=0; s1num=0; s5num=0; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80+1); //在液晶上寫一些固定的數 write_date('2'); write_date('0'); delayms(5); write_com(0x80+5); //在液晶上寫一些固定的數 write_date('-'); delayms(5); write_com(0x80+8); write_date('-'); delayms(5); write_com(0x80+0x40+3); //時間部分的兩個冒號 write_date(':'); delayms(5); write_com(0x80+0x40+6); write_date(':'); delayms(5); write_com(0x80+0x40+12); write_date(':'); delayms(5); } void keyscan() //鍵盤掃描操作 { if(s1==0&&s5num==0) //時鐘功能鍵 并且鬧鐘不處于調整狀態 { delayms(5); if(s1==0&&s5num==0) { s1num++; flag1=1; while(!s1); di(); switch(s1num) { case 1: write_com(0x80+0x40+8); write_com(0x0f); //光標閃爍 break; case 2: write_com(0x80+0x40+5); break; case 3: write_com(0x80+0x40+2); break; case 4: write_com(0x80+14); break; case 5: write_com(0x80+10); break; case 6: write_com(0x80+7); break; case 7: write_com(0x80+4); break; case 8: flag1=0; s1num=0; write_com(0x0c); WriteSet1302(0x8e,0x00); //第八次按時鐘功能鍵后,把調整了的所有數據當前狀態存入到DS1302中 WriteSet1302(0x80,miao); WriteSet1302(0x84,shi); WriteSet1302(0x82,fen); WriteSet1302(0x8a,week); WriteSet1302(0x8c,nian); WriteSet1302(0x88,yue); WriteSet1302(0x86,ri); WriteSet1302(0x8e,0x80); break; } } } if(s1num!=0&&s5num==0) //時鐘加鍵 { if(s2==0) { delayms(5); if(s2==0) { while(!s2); di(); switch(s1num) { case 1: x1=miao%16; x2=miao/16; x1++; if(x1==10) { x1=0; x2++; if(x2>=6) x2=0; } miao=x1+x2*16; write_sfm(7,miao); write_com(0x80+0x40+8); break; case 2: x1=fen%16; x2=fen/16; x1++; if(x1==10) { x1=0; x2++; if(x2>=6) x2=0; } fen=x1+x2*16; write_sfm(4,fen); write_com(0x80+0x40+5); break; case 3: x1=shi%16; x2=shi/16; x1++; if(x1==10) { x1=0; x2++; } if(x2>=2&&x1>=4) { x1=0; x2=0; } shi=x1+x2*16; write_sfm(1,shi); write_com(0x80+0x40+2); break; case 4: x1=(week)%10; x2=(week)/10; x1++; if(x1==8) x1=1; week=x2*16+x1; write_week(week); write_com(0x80+14); break; case 5: x1=ri%16; x2=ri/16; x1++; if(x1==10) { x1=0; x2++; } if(x2==3&&x1==2) { x1=0; x2=0; } ri=x1+x2*16; write_nyr(9,ri); write_com(0x80+10); break; case 6: x1=yue%16; x2=yue/16; x1++; if(x2==1&&x1==3) { x1=1; x2=0; } if(x1==10) { x1=0; x2++; } yue=x1+x2*16; write_nyr(6,yue); write_com(0x80+7); break; case 7: x1=nian%16; x2=nian/16; x1++; if((x2==9)&&(x1==10)) { x1=0; x2=0; } if(x1==10) { x2++; x1=0; } nian=x1+x2*16; write_nyr(3,nian); write_com(0x80+4); break; } } } if(s3==0) //時鐘減鍵 { delayms(5); if(s3==0) { while(!s3); di(); switch(s1num) { case 1: x1=miao%16; x2=miao/16; x1--; if(x1==-1) { x1=9; x2--; if(x2==-1) x2=5; } miao=x1+x2*16; write_sfm(7,miao); write_com(0x80+0x40+8); break; case 2: x1=fen%16; x2=fen/16; x1--; if(x1==-1) { x1=9; x2--; if(x2==-1) x2=5; } fen=x1+x2*16; write_sfm(4,fen); write_com(0x80+0x40+5); break; case 3: x1=shi%16; x2=shi/16; x1--; if(x1==-1) { x1=9; x2--; if(x2==-1) { x1=3; x2=2; } } shi=x1+x2*16; write_sfm(1,shi); write_com(0x80+0x40+2); break; case 4: x1=(week)%10; x2=(week)/10; x1--; if(x1==0) x1=7; week=x2*16+x1; write_week(week); write_com(0x80+14); break; case 5: x1=ri%16; x2=ri/16; x1--; if(x1==-1) { x1=9; x2--; if(x2==-1) { x1=1; x2=3; } } ri=x1+x2*16; write_nyr(9,ri); write_com(0x80+10); break; case 6: x1=yue%16; x2=yue/16; x1--; if((x2==1)&&(x1==-1)) { x1=9; x2--; } if((x2==0)&&(x1==0)) { x1=2; x2=1; } yue=x1+x2*16; write_nyr(6,yue); write_com(0x80+7); break; case 7: x1=nian%16; x2=nian/16; x1--; if(x1==-1) { x1=9; x2--; if(x2==-1) { x1=9; x2=9; } } nian=x1+x2*16; write_nyr(3,nian); write_com(0x80+4); break; } } } } if(s1num!=0||s5num!=0) //表示時鐘或者鬧鐘處于調整狀態 { if(s4==0) //確定狀態的按鍵 { delayms(5); if(s4==0) { if(s1num!=0) //表示時鐘處于調整狀態 { while(!s4); //確定鍵被按下 di(); WriteSet1302(0x8e,0x00); //按了確認鍵后,把調整了的所有數據當前狀態存入到DS1302中 WriteSet1302(0x80,miao); WriteSet1302(0x84,shi); WriteSet1302(0x82,fen); WriteSet1302(0x8a,week); WriteSet1302(0x8c,nian); WriteSet1302(0x88,yue); WriteSet1302(0x86,ri); WriteSet1302(0x8e,0x80); flag1=0; write_com(0x0c); s1num=0; } if(s5num!=0) //表示鬧鐘處于調整狀態 { while(!s4); di(); WriteSet1302(0x8e,0x00); //調整鬧鐘,不能讓時鐘暫停,故沒把時鐘數據寫入DS1302中 WriteSet1302(0xc0,ashi); //把鬧鐘數據寫入DS1302中 WriteSet1302(0xfc,afen); WriteSet1302(0x8e,0x80); flag2=0; s5num=0; write_com(0x0c); } } } } if(s5==0&&s1num==0) //鬧鐘功能鍵 并且時鐘不處于調整狀態 { delayms(5); if(s5==0&&s1num==0) { s5num++; flag2=1; while(!s5); di(); if(s5num==1) { write_com(0x80+0x40+14); write_com(0x0f); } if(s5num==2) { write_com(0x80+0x40+11); } if(s5num==3) { s5num=0; flag2=0; WriteSet1302(0x8e,0x00); WriteSet1302(0xfc,afen); WriteSet1302(0xc0,ashi); WriteSet1302(0x8e,0x80); write_com(0x0c); } } } if(s5num!=0&&s1num==0) //只有鬧鐘處于調整狀態 { if(s2==0) //鬧鐘加鍵 { delayms(5); if(s2==0) { while(!s2); di(); if(s5num==1) { x1=afen%16; x2=afen/16; x1++; if(x1==10) { x1=0; x2++; if(x2>=6) x2=0; } afen=x1+x2*16; write_sfm(13,afen); write_com(0x80+0x40+14); } if(s5num==2) { x1=ashi%16; x2=ashi/16; x1++; if(x2>=2&&x1>=4) { x1=0; x2=0; } if(x1==10) { x1=0; x2++; } ashi=x1+x2*16; write_sfm(10,ashi); write_com(0x80+0x40+11); } } } } if(s3==0) //鬧鐘減鍵 { delayms(5); if(s3==0) { while(!s3); di(); if(s5num==1) { x1=afen%16; x2=afen/16; x1--; if(x1==-1) { x1=9; x2--; if(x2==-1) x2=5; } afen=x1+x2*16; write_sfm(13,afen); write_com(0x80+0x40+14); } if(s5num==2) { x1=ashi%16; x2=ashi/16; x1--; if(x1==-1) { x1=9; x2--; if(x2==-1) { x1=3; x2=2; } } ashi=x1+x2*16; write_sfm(10,ashi); write_com(0x80+0x40+11); } } } } void laba() { if((shi==ashi)&&(fen==afen)&&(miao<=60&&miao>=0)) { di(); } } void main() //主函數 { init(); //大初始化 cmg88(); //關數碼管函數 inital_1302(); //DS1302賦初值的初始化 ashi=ReadSet1302(0xc1); //從DS1302讀出數據 afen=ReadSet1302(0xfd); write_sfm(10,ashi); //讀出數據送給液晶顯示 write_sfm(13,afen); while(1) { keyscan(); laba(); if(flag1==0&&flag2==0) //經過一系列調整后,最終繼續滿足這個條件 { //從DS1302讀數據 miao=ReadSet1302(0x81); //秒 fen=ReadSet1302(0x83); //分 shi=ReadSet1302(0x85); //時 ri=ReadSet1302(0x87); //日 yue=ReadSet1302(0x89); //月 week=ReadSet1302(0x8b); //星期 nian=ReadSet1302(0x8d); //年 write_sfm(7,miao); //把它們送液晶顯示 write_sfm(4,fen); write_sfm(1,shi); write_nyr(9,ri); write_nyr(6,yue); write_nyr(3,nian); write_week(week); } } } |