1、 日歷功能 A、在此功能執行時,不可影響電子表的正常運行。 B、該模式下可顯示年、月、日。 C、使用矩陣鍵盤調節時間。 D、滿足特殊月份31、28天規律。 E、滿足閏年規律。 2、 秒表功能 A、在此功能執行時,不可影響電子表的正常運行。 B、該模式下可實現秒表計時功能。 C、用一根杜邦線(結合程序)插入所需引腳,使得秒表停止計時,拔下杜邦線可繼續計時(此要求下允許電子鐘非正常運行,但不得人為不關閉任何定時器)。 3、定時功能 A、在此功能執行時,不可影響電子表的正常運行。
單片機源程序如下:
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- uint year,year1;
- uchar code table[]={"2018-11-07week3"};
- uchar code table1[]={"19:29:55 "};
- uchar code table2[]={"0:00:00 "};
- sbit lcden=P3^4; //定義液晶使能端
- sbit lcdrs=P3^5; //液晶數據命令選擇端
- sbit rw=P3^6; //定義讀寫選擇
- sbit k0=P3^5;
- sbit dula=P2^6; //聲明U1鎖存端,鎖存器
- sbit wela=P2^7; //聲明U2鎖存端,鎖存器
- sbit beep=P2^3;
- uchar num,num1,a,a2,b,du,shi,shi1,fen,miao,ge,day,mon,week;
- uchar flag,flag1,shi,shi2,fen1,miao1,a1,du1,qie,du2,num3,num4;
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void write_com(uchar com) //寫命令操作
- {
- rw=0;
- lcdrs=0; //選擇寫命令模式
- P0=com; //將要寫的命令字,送到數據總線上
- delay(5); //稍作延時以待數據穩定
- lcden=1; //使能端,給一高脈沖,因為初始化函數,已經將使能端置為0
- delay(5); //稍作延時
- lcden=0; //使能端0完成高脈沖
- }
- void write_data(uint date1) //寫數據操作
- {
- rw=0;
- lcdrs=1;
- P0=date1; //寫數據
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_sfm(uchar add,uint date1) //定義小時,分鐘,秒的地址和數據
- {
- uchar shi,ge;
- shi=date1/10; //將數據分離
- ge=date1%10;
- write_com(0x80+0x40+add);//第二行數據指針位置調整
- write_data(0x30+shi); //更改顯示數據的十位
- write_data(0x30+ge); //更改顯示數據的個位
- }
- void write_md(uchar add,uint date1) //定義月份和天地址和數據
- {
- uchar shi,ge;
- shi=date1/10; //將數據分離
- ge=date1%10;
- write_com(0x80+add); //第一行數據指針位置調整
- write_data(0x30+shi); //更改顯示數據的十位
- write_data(0x30+ge); //更改顯示數據的個位
- }
- void write_y(uchar add,uint date1) //定義年地址和數據
- {
- uchar qian,bai,shi,ge;
- qian=date1/1000;
- bai=date1%1000/100;
- shi=date1%100/10; //將數據分離
- ge=date1%10;
- write_com(0x80+add);//第一行數據指針位置調整
- write_data(0x30+qian); //更改顯示數據的千位
- write_data(0x30+bai); //更改顯示數據的百位
- write_data(0x30+shi); //更改顯示數據的十位
- write_data(0x30+ge); //更改顯示數據的個位
- }
- //void zhuanhua()
- //{
- // switch(week)
- // {
- // case 1:
- // write_com(0x80+0x40+9);
- // write_data('M'); delay(5);
- // write_data('o'); delay(5);
- // write_data('n'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a'); delay(5);
- // write_data('y'); delay(5);
- // write_data(' ');
- // break;
- // case 2:
- // write_com(0x80+0x40+9);
- // write_data('T'); delay(5);
- // write_data('u'); delay(5);
- // write_data('e'); delay(5);
- // write_data('s'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a'); delay(5);
- // write_data('y');
- // break;
- // case 3:
- // write_com(0x80+0x40+9);
- // write_data('W'); delay(5);
- // write_data('e'); delay(5);
- // write_data('d'); delay(5);
- // write_data('n'); delay(5);
- // write_data('e'); delay(5);
- // write_data('s'); delay(5);
- // write_data('d');
- // break;
- // case 4:
- // write_com(0x80+0x40+9);
- // write_data('T'); delay(5);
- // write_data('h'); delay(5);
- // write_data('u'); delay(5);
- // write_data('r'); delay(5);
- // write_data('s'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a');
- // break;
- // case 5:
- // write_com(0x80+0x40+9);
- // write_data('F'); delay(5);
- // write_data('r'); delay(5);
- // write_data('i'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a'); delay(5);
- // write_data('y'); delay(5);
- // write_data(' ');
- // break;
- // case 6:
- // write_com(0x80+0x40+9);
- // write_data('S'); delay(5);
- // write_data('a'); delay(5);
- // write_data('t'); delay(5);
- // write_data('u'); delay(5);
- // write_data('r'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a');
- // break;
- // case 7:
- // write_com(0x80+0x40+9);
- // write_data('S'); delay(5);
- // write_data('u'); delay(5);
- // write_data('n'); delay(5);
- // write_data('d'); delay(5);
- // write_data('a'); delay(5);
- // write_data('y'); delay(5);
- // write_data(' ');
- // break;
- // }
- //}
- void jianpan()
- {
- uchar temp;
- P3=0xfe;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xee: //顯示需要更改地方的光標
- du++;
- while(temp!=0xf0) //按鍵釋放,使每按一次只增加一個數
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(du==1) //移動光標至秒位置,同時暫停計時
- {
- TR0=0;
- write_com(0x80+0x40+6);
- write_com(0x0f); //顯示光標
- }
- if(du==2) //移動光標至分位置
- {
- write_com(0x80+0x40+3);
- }
- if(du==3) //移動光標至時位置
- {
- write_com(0x80+0x40+0);
- }
- if(du==4) //移動光標至天位置
- {
- write_com(0x80+8);
- }
- if(du==5) //移動光標至月位置
- {
- write_com(0x80+5);
- }
- if(du==6) //移動光標至年位置,用于 增加年份
- {
- write_com(0x80+0);
- }
- if(du==7) //移動光標至周位置
- {
- write_com(0x80+14); //先送地址
- // write_data(0x30+week); //輸入的數字
- }
- if(du==8) //移動光標至年位置 減少年份
- {
- write_com(0x80+0);
- }
- if(du==9) //使du循環,恢復定時器
- {
- TR0=1;
- du=0;
- write_com(0x80+0x40+10);
- write_com(0x0c); //關光標
- }
-
- break;
- case 0xde:
- while(temp!=0xf0) //按鍵釋放
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(du==1) //在秒位置時,使秒增加
- {
- miao++;
- if(miao==60)
- {
- miao=0;
- }
- write_sfm(6,miao); //更新秒位置數據
- }
- if(du==2) //在分位置時,使分增加
- {
- fen++;
- if(fen==60)
- {
- fen=0;
- }
- write_sfm(3,fen); //更新秒位置數據
- }
- if(du==3) //在小時位置時,使小時增加
- {
- shi++;
- if(shi==24)
- {
- shi=0;
- }
- if(flag1==0) //顯示24小時模式
- {
- write_sfm(0,shi);
- }
- if(flag1==1) //顯示12小時模式
- {
- if(shi==0)
- {
- shi=12;
- }
- if((shi<=12)&&(shi>=1))
- {
- shi1=shi;
- }
- if(shi>12)
- {
- shi1=shi-12;
- }
- write_sfm(0,shi1); //更新12小時模式的數據
- write_com(0x80+0x40+0);
- }
- }
- if(du==4) //在天位置時,使天增加
- {
- day++;
- if(year%4==0&&year%10!=0) //如果是閏年
- {
- if(mon==2)
- {
- if(day==30)
- {
- day=1;
- }
- }
- }
- if((year%4==0&&year%100==0)||(year%4!=0)) //如果不是閏年
- {
- if(mon==2)
- {
- if(day==29)
- {
- day=1;
- }
- }
- }
-
- if(mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)
- {
- if(day==32)
- {
- day=1;
- }
- }
- if(mon==4||mon==6||mon==9||mon==11)
- {
- if(day==31)
- {
- day=1;
- }
- }
- write_md(8,day);
- }
- if(du==5) //在月位置時,使月增加
- {
- mon++;
- if(mon==13)
- {
- mon=1;
- }
- write_md(5,mon);
- }
- if(du==6) //在年位置時,使年增加
- {
- year++;
- write_y(0,year);
- }
- if(du==7) //在周位置時,使周增加
- {
- week++;
- if(week==8)
- {
- week=1;
- }
- write_com(0x80+14); //位置
- write_data(0x30+week); //顯示數據
- }
- if(du==8) //在天位置時,使年減少
- {
- year--;
- write_y(0,year);
- }
- break;
- case 0xbe:
- flag1++; //使變量flag1++
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(flag1==1) //如果變量flag1為1那么進行12小時模式
- {
- if(shi==0)
- {
- shi=12;
- }
- if((shi<=12)&&(shi>=1))
- {
- write_com(0x80+0x40+8);
- write_data('+');
- shi1=shi;
- }
- if(shi>12)
- {
- write_com(0x80+0x40+8);
- write_data('-');
- shi1=shi-12;
- }
- write_sfm(0,shi1);
- write_com(0x80+0x40+0);
- }
- if(flag1>=2)
- {
- flag1=0;
- }
- if(flag1==0) //如果變量flag1為1那么進行24小時模式
- {
- write_sfm(0,shi);
- write_com(0x80+0x40+0);
- }
- break;
- case 0x7e:
- du1++; //使du1++
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(du1==1) //使定時器1暫停,移動光標至秒表秒位
- {
- write_com(0x80+0x40+14);
- TR1=0;
- write_com(0x0f);//顯示光標
- }
- if(du1==2) //移動光標至秒表 分 位
- {
- write_com(0x80+0x40+11);
- }
- if(du1==3) //時 位
- {
- write_com(0x80+0x40+9);
- }
- if(du1==4) //恢復定時器1,返回原位
- {
- write_com(0x80+0x40+14);
- TR1=1;
- write_com(0x0c); //關閉光標顯示
- }
- if(du1==5)
- {
- du1=0;
- }
- break;
- }
- }
- }
- P3=0xfd;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xed:
- while(temp!=0xf0)
- {
- temp=P3;
- temp=temp&0xf0;
- }
- if(du1==1)
- {
- miao1++; //使秒表光標所在地 秒 加
- if(miao1==60)
- {
- miao1=0;
- }
- write_sfm(14,miao1); //更新
- }
- if(du1==2) //分 加
- {
- fen1++;
- if(fen1==60)
- {
- fen1=0;
- }
- write_sfm(11,fen1);
- }
- if(du1==3) //時 加
- {
- shi2++;
- if(shi2==60)
- {
- shi2=0;
- }
- write_com(0x80+0x40+9);//第二行數據指針位置調整
- write_data(0x30+shi2); //更改顯示數據的個位
- }
- break;
- case 0xdd:
- TR1=1; //開啟秒表(初始值正走)
- break;
- case 0xbd:
- qie=1; //切換 秒表 至倒計時
- break;
- case 0x7d:
- num4=0; //切換鬧鐘鈴聲 一直響
- break;
- }
- }
- }
- P3=0xfb;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- delay(10);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xeb:
- num4=1; //切換鬧鐘鈴聲 間斷響
- break;
- case 0xdb:
- qie=0; //切換 秒表 正計時
- break;
- case 0xbb:
- TR1=0; //使秒表停止計時
- break;
- }
- }
- }
- }
- void shixu1() //定時器1 秒表 正走時序
- {
- if(a1==20)
- {
- a1=0;
- miao1++;
- if(miao1==60)
- {
- miao1=0;
- fen1++;
- if(fen1==60)
- {
- fen1=0;
- shi2++;
-
- if(shi2==10)
- {
- shi2=0;
- }
- write_com(0x80+0x40+9);//第二行數據指針位置調整
- write_data(0x30+shi2); //更改顯示數據的個位
- }
- write_sfm(11,fen1);
- }
- write_sfm(14,miao1);
- }
- }
- void shixu2() //定時器1 秒表 倒走時序
- {
- if(a1==20)
- {
- a1=0;
- miao1--;
- if(miao1==0&&fen1>=1&&shi2>=1) //如果在秒為0,時和分鐘不為零的情況下
- {
- miao1=59;
- fen1--;
- if(fen1==0&&shi2>=1) //如果在分為0,分鐘不為零的情況下
- {
- fen1=59;
- shi2--;
- write_com(0x80+0x40+9);//第二行數據指針位置調整
- write_data(0x30+shi2); //更改顯示數據的個位
- }
- write_sfm(11,fen1);
- }
- write_sfm(14,miao1);
- }
- }
- void shixu() //日歷走時序
- {
- if(a==20)
- {
- a=0;
- miao++;
- if(miao==60)
- {
- miao=0;
- fen++;
- if(fen==60)
- {
- fen=0;
- shi++;
- if(shi==24)
- {
- shi=0;
- day++;
- week++;
- if(week==7)
- {
- week=1;
- }
- if(year%4==0&&year%100!=0) //如果是閏年
- {
- if(mon==2)
- {
- if(day==30)
- {
- day=1;
- mon++;
-
- write_md(5,mon);
- }
- }
- }
- if((year%4==0&&year%100==0)||(year%4!=0)) //如果不是閏年
- {
- if(mon==29)
- {
- if(day==30)
- {
- day=1;
- mon++;
-
- write_md(5,mon);
- }
- }
- }
- if(mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)
- {
- if(day==32)
- {
- day=1;
- mon++;
-
- write_md(5,mon);
- }
- }
- if(mon==4||mon==6||mon==9||mon==11)
- {
- if(day==31)
- {
- day=1;
- mon++;
-
- write_md(5,mon);
- }
- }
-
- if(mon==13)
- {
- mon=1;
- year++;
- write_y(1,year);
- }
- write_com(0x80+14); //位置
- write_data(0x30+week); //顯示數據
- // zhuanhua();
- write_md(8,day);
- }
- if(flag1==0) //切換至24小時模式
- {
- write_sfm(0,shi);
- }
- if(flag1==1) //切換至12小時模式
- {
- if(shi==0)
- {
- shi=12;
- }
- if((shi<=12)&&(shi>=1))
- {
- shi1=shi;
- }
- if(shi>12)
- {
- shi1=shi-12;
- }
- write_sfm(0,shi1);
- }
- }
- write_sfm(3,fen);
- }
- write_sfm(6,miao);
- }
- }
-
- void main()
- {
- TMOD=0x11;
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- TH1=(65536-45872)/256;
- TL1=(65536-45872)%256;
- EA=1;
- ET0=1;
- TR0=1; //定時器0
- ET1=1;
- TR1=0; //定時器1,初始關閉運行
- EX0=1; //外部中斷0中斷允許位
- IT0=0; //外部中斷0電平觸發方式
- shi=19; //日歷初值
- fen=29;
- miao=55;
- day=6;
- mon=11;
- year=2018;
- week=3;
- flag1=0; //小時為24制
- num4=0; //鬧鐘聲為1號
- qie=0; //秒表開啟時先為正走
- dula=0; //關閉段選
- wela=0; //關閉位選
- lcden=0; //使能端制0
- write_com(0x38);
- write_com(0x0c); //開顯示,不顯示光標
- write_com(0x06); //寫一個地址之后,指針加一
- write_com(0x01); //顯示清0,數據指針清0
- write_com(0x80); //第一個行顯示
- {
- for(num=0;num<15;num++)
- {
- write_data(table[num]);
- delay(5);
- }
- write_com(0x80+0x40); //第一個行顯示,左邊顯示數組
- for(num=0;num<13;num++)
- {
- write_data(table1[num]);
- delay(5);
- }
- }
- write_com(0x80+0x40+9); //第一個行顯示,右邊顯示數組
- for(num=0;num<13;num++)
- {
- write_data(table2[num]);
- delay(5);
- }
- // zhuanhua();
- while(1)
- {
- jianpan();
- shixu();
- if(qie==0)
- {
- shixu1(); //秒表正走
- }
- if(qie==1)
- {
- shixu2(); //秒表倒走
- if(shi2==0&&fen1==0&&miao1==0)//如果走到0,那么定時器1 暫停k
- {
- TR1=0;
- }
- }
- }
- }
-
- void T0_time() interrupt 1 //定時器 中斷服務程序k
- {
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- a++;
- if((shi==19&&fen==30)&&(miao<3&&miao>=0)) //如果是在下午19點,30分,那么鬧鐘響鈴3分鐘k
- {
- if(num4==0) //鬧鐘鈴聲1,一直響k
- {
- {
- beep=0;
- }
- }
- if(num4==1) //鬧鐘鈴聲2,響一秒間斷一秒再一秒k
- {
- if(miao==0)
- {
- beep=0;
- }
- if(miao==1)
- {
- beep=1;
- }
- if(miao==2)
- {
- beep=0;
- }
- }
- }
- if(shi==19&&fen==30&&miao==3)
- {
- beep=1;
- }
- }
- void T1_time() interrupt 3 //定時器1 中斷服務程序k
- {
- TH1=(65536-45872)/256;
- TL1=(65536-45872)%256;
- a1++;
- }
-
- void INT0_0() interrupt 0 //外部中斷默認中斷級別最高A
- {
- // TR1=0;
- }
復制代碼
所有資料51hei提供下載:
日歷.docx
(19.08 KB, 下載次數: 11)
2018-11-26 17:40 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|