|
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit lcden=P3^4; //液晶使能端
- sbit rs=P3^5; //液晶數(shù)據(jù)命令選擇端
- sbit led=P2^5; //控制LED的鎖存器
- sbit dula=P2^6; //控制LCD的段鎖存器
- sbit wela=P2^7; //控制LCD的位鎖存器
- sbit dsirq=P3^2; //DS12887的中斷請(qǐng)求端
- sbit dsds=P1^7; //DS12887的讀允許輸入端
- sbit dsrw=P1^6; //DS12887的寫允許輸入端
- sbit dsas=P1^5; //DS12887的地址選通端
- sbit dscs=P1^4; //DS12887的芯片片選端
- sbit a=P3^0; //設(shè)置鍵盤用的
- sbit b=P3^1; //設(shè)置鍵盤用的
- sbit c=P3^6; //設(shè)置鍵盤用的
- sbit d=P3^7; //設(shè)置鍵盤用的
- sbit e=P3^3; //設(shè)置鍵盤用的
- uchar code table1[]=" 2000-00-00 ";
- uchar code table2[]=" 00:00:00 ";
- uchar flag1,flag2,temp,temp1;
- /*
- falg1標(biāo)志位是用來(lái)判斷是否執(zhí)行從DS12C887中讀取數(shù)據(jù)并送去液晶顯示;
- flag2標(biāo)志位是用來(lái)判斷LCD上顯示的年數(shù)是否是閏年;
- temp與temp1都時(shí)當(dāng)月的天數(shù)值,用來(lái)判斷DS12C887中的天數(shù)值是否大
- 于當(dāng)月應(yīng)有的天數(shù),如大于則將天數(shù)值置1,如有需要請(qǐng)重新設(shè)置天數(shù)值。
- */
- char miao,fen,nian,yue,ri,xingqi;
- int shi; //小時(shí)的數(shù)值大于128,所以不能選擇char型數(shù)據(jù)
- /*------------
- 延時(shí)子程序
- */
- void delayms(uchar a)
- {
- uchar x,y;
- for(x=a;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*----------------
- 往液晶中寫指令
- ----------------*/
- void write_com(uchar com)
- {
- rs=0; //選擇寫命令模式
- lcden=0; //將lcden置為零
- P0=com; //將要寫的命令字送到數(shù)據(jù)總線上
- delayms(5); //稍做延時(shí)以待數(shù)據(jù)穩(wěn)定
- lcden=1; //使能端給一個(gè)高脈沖
- delayms(5); //稍做延時(shí)
- lcden=0; //將使能端置0以完成高脈沖
- }
- /*----------------
- 往液晶中寫數(shù)據(jù)
- ----------------*/
- void write_date(uchar date)
- {
- rs=1; //選擇寫數(shù)據(jù)模式
- lcden=0; //將lcden置為零
- P0=date; //將要寫的數(shù)據(jù)送到數(shù)據(jù)總線上
- delayms(5); //稍做延時(shí)以待數(shù)據(jù)穩(wěn)定
- lcden=1; //使能端給一個(gè)高脈沖
- delayms(5); //稍做延時(shí)
- lcden=0; //將使能端置0以完成高脈沖
- }
- /*--------------------
- 向DS12C887內(nèi)寫數(shù)據(jù)
- --------------------*/
- void write_ds(uchar add,uchar date)
- {
- dscs=0;
- dsas=1;
- dsds=1;
- dsrw=1;
- P0=add; //先寫地址
- dsas=0;
- dsrw=0;
- P0=date; //再寫數(shù)據(jù)
- dsrw=1;
- dsas=1;
- dscs=1;
- }
- /*--------------------
- 從DS12C887中讀數(shù)據(jù)
- --------------------*/
- uchar read_ds(uchar add)
- {
- uchar temp;
- dscs=0;
- dsas=1;
- dsds=1;
- dsrw=1;
- P0=add; //先寫地址
- dsas=0;
- dsds=0;
- P0=0xff; //讀數(shù)據(jù)之前先將P0口置一
- temp=P0; //再讀數(shù)據(jù)
- dsds=1;
- dsas=1;
- dscs=1;
- return temp;
- }
- /*----------------------------------------------------------------------
- 24小時(shí)制在液晶的指定位置寫入時(shí)分秒,12小時(shí)制在液晶的指定位置寫入分秒
- ----------------------------------------------------------------------*/
- void write_sfm(uchar add,uchar date)
- {
- uchar shi,ge;
- shi=date/10; //分解一個(gè)2位數(shù)的十位和個(gè)位
- ge=date%10;
- write_com(0x80+0x40+add); //設(shè)置顯示位置
- write_date(shi+0x30); //送去液晶顯示十位
- write_date(ge+0x30); //送去液晶顯示個(gè)位
- }
- /*----------------------------
- 在液晶的指定位置寫入年月日
- ----------------------------*/
- void write_nyr(uchar add,uchar date)
- {
- uchar shi,ge;
- shi=date/10; //分解一個(gè)2位數(shù)的十位和個(gè)位
- ge=date%10;
- write_com(0x80+add); //設(shè)置顯示位置
- write_date(shi+0x30); //送去液晶顯示十位
- write_date(ge+0x30); //送去液晶顯示個(gè)位
- }
- /*----------------------------
- 在液晶的指定位置寫入星期
- ----------------------------*/
- void write_xq(uchar date)
- {
- uchar i;
- i=date;
- write_com(0x80+12);
- switch(i) //switch-case語(yǔ)句判斷i的值及執(zhí)行相應(yīng)的操作
- {
- case 1: //當(dāng)i等于1時(shí),送去液晶顯示MON(星期一)
- write_date('M');
- write_date('O');
- write_date('N');
- break;
- case 2: //當(dāng)i等于2時(shí),送去液晶顯示TUE(星期二)
- write_date('T');
- write_date('U');
- write_date('E');
- break;
- case 3: //當(dāng)i等于3時(shí),送去液晶顯示W(wǎng)ED(星期三)
- write_date('W');
- write_date('E');
- write_date('D');
- break;
- case 4: //當(dāng)i等于4時(shí),送去液晶顯示THU(星期四)
- write_date('T');
- write_date('H');
- write_date('U');
- break;
- case 5: //當(dāng)i等于5時(shí),送去液晶顯示FRI(星期五)
- write_date('F');
- write_date('R');
- write_date('I');
- break;
- case 6: //當(dāng)i等于6時(shí),送去液晶顯示SAT(星期六)
- write_date('S');
- write_date('A');
- write_date('T');
- break;
- case 7: //當(dāng)i等于7時(shí),送去液晶顯示SUN(星期日)
- write_date('S');
- write_date('U');
- write_date('N');
- break;
- }
- }
- /*----------------
- 判斷天數(shù)的函數(shù)
- ----------------*/
- char day_num(char nian,char yue)
- {
- char num;
- if(((nian%4==0)&&(nian%100!=0))||((nian%100==0)&&(nian%400==0))) //閏年判斷
- flag2=1;
- else
- flag2=0;
- if(flag2==1) //是閏年時(shí),將第二月的天數(shù)設(shè)為29
- {
- switch(yue)
- {
- case 1:
- num=31; //1月的天數(shù)
- break;
- case 2:
- num=29; //2月的天數(shù)
- break;
- case 3:
- num=31; //3月的天數(shù)
- break;
- case 4:
- num=30; //4月的天數(shù)
- break;
- case 5:
- num=31; //5月的天數(shù)
- break;
- case 6:
- num=30; //6月的天數(shù)
- break;
- case 7:
- num=31; //7月的天數(shù)
- break;
- case 8:
- num=31; //8月的天數(shù)
- break;
- case 9:
- num=30; //9月的天數(shù)
- break;
- case 10:
- num=31; //10月的天數(shù)
- break;
- case 11:
- num=30; //11月的天數(shù)
- break;
- case 12:
- num=31; //12月的天數(shù)
- break;
- }
- }
- if(flag2==0) //不是閏年時(shí),將第二月的天數(shù)設(shè)為28
- {
- switch(yue)
- {
- case 1:
- num=31; //1月的天數(shù)
- break;
- case 2:
- num=28; //2月的天數(shù)
- break;
- case 3:
- num=31; //3月的天數(shù)
- break;
- case 4:
- num=30; //4月的天數(shù)
- break;
- case 5:
- num=31; //5月的天數(shù)
- break;
- case 6:
- num=30; //6月的天數(shù)
- break;
- case 7:
- num=31; //7月的天數(shù)
- break;
- case 8:
- num=31; //8月的天數(shù)
- break;
- case 9:
- num=30; //9月的天數(shù)
- break;
- case 10:
- num=31; //10月的天數(shù)
- break;
- case 11:
- num=30; //11月的天數(shù)
- break;
- case 12:
- num=31; //12月的天數(shù)
- break;
- }
- }
- return num; //函數(shù)的返回值時(shí)當(dāng)月的天數(shù)
- }
- /*--------------
- 鍵盤掃描程序
- --------------*/
- void keyscan()
- {
- uchar num;
- a=0; //設(shè)置矩陣鍵盤S1低電平
- b=1; //設(shè)置矩陣鍵盤S2高電平
- if(c==0) //判斷S3有沒(méi)有被按下
- {
- delayms(5); //去抖延時(shí)
- if(c==0) //判斷S3有沒(méi)有被按下
- {
- while(!c); //判斷按鍵S3有沒(méi)有釋放
- num++; //按下鍵的次數(shù)
- flag1=1; //標(biāo)志位flag1置一
- if(num==1) //當(dāng)num等于1時(shí),光標(biāo)在秒鐘處閃爍
- {
- write_com(0x80+0x40+8);
- write_com(0x0f);
- }
- if(num==2) //當(dāng)num等于2時(shí),光標(biāo)在分鐘處閃爍
- {
- write_com(0x80+0x40+5);
- write_com(0x0f);
- }
- if(num==3) //當(dāng)num等于3時(shí),光標(biāo)在時(shí)鐘處閃爍
- {
- write_com(0x80+0x40+2);
- write_com(0x0f);
- }
- if(num==4) //當(dāng)num等于4時(shí),光標(biāo)在年處閃爍
- {
- write_com(0x80+4);
- write_com(0x0f);
- }
- if(num==5) //當(dāng)num等于5時(shí),光標(biāo)在月處閃爍
- {
- write_com(0x80+7);
- write_com(0x0f);
- }
- if(num==6) //當(dāng)num等于6時(shí),光標(biāo)在日處閃爍
- {
- write_com(0x80+10);
- write_com(0x0f);
- }
- if(num==7) //當(dāng)num等于7時(shí),光標(biāo)在星期處閃爍
- {
- write_com(0x80+14);
- write_com(0x0f);
- }
- if(num==8)
- {
- num=0; //num清0
- write_ds(0x00,miao); //將秒寫入DS12C887
- write_ds(0x02,fen); //將分寫入DS12C887
- write_ds(0x04,shi); //將時(shí)寫入DS12C887
- write_ds(0x06,xingqi); //將星期寫入DS12C887
- write_ds(0x07,ri); //將日寫入DS12C887
- write_ds(0x08,yue); //將月寫入DS12C887
- write_ds(0x09,nian); //將年寫入DS12C887
- flag1=0; //標(biāo)志位flag1清0
- }
- }
- }
- if(num!=0) //當(dāng)功能鍵S3按下后,數(shù)值增大鍵S4才有用
- {
- a=0; //設(shè)置矩陣鍵盤第一排位低電平
- b=1; //設(shè)置矩陣鍵盤第二排位高電平
- if(d==0) //判斷S4有沒(méi)有被按下
- {
- delayms(5); //去抖延時(shí)
- if(d==0) //判斷S4有沒(méi)有被按下
- {
- while(!d); //判斷按鍵S4有沒(méi)有釋放
- if(num==1)
- {
- miao++; //當(dāng)num=1時(shí),秒值加一
- if(miao>59) //當(dāng)秒值大于59時(shí),將秒值置0
- miao=0;
- write_sfm(7,miao); //將秒值寫入液晶顯示
- write_com(0x80+0x40+8); //光標(biāo)在秒值的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==2)
- {
- fen++; //當(dāng)num=2時(shí),分值加一??
- if(fen>59) //當(dāng)分值大于59時(shí),將分值置0
- fen=0;
- write_sfm(4,fen); //將分值寫入液晶顯示
- write_com(0x80+0x40+5); //光標(biāo)在分值的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==3)
- {
- shi++; //當(dāng)num=3時(shí),時(shí)鐘加一?
- if(shi>23) //當(dāng)時(shí)鐘大于23時(shí),將時(shí)鐘置0
- shi=0;
- write_sfm(1,shi); //將時(shí)鐘寫入液晶顯示
- write_com(0x80+0x40+2); //光標(biāo)在時(shí)鐘的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==4)
- {
- nian++; //當(dāng)num=4時(shí),年加一
- if(nian>99) //當(dāng)年大于99時(shí),將年置0
- nian=0;
- write_nyr(3,nian); //將年寫入液晶顯示
- write_com(0x80+4); //光標(biāo)在年的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==5)
- {
- yue++; //當(dāng)num=5時(shí),月加一
- if(yue>12) //當(dāng)月大于12時(shí),將月置1
- yue=1;
- write_nyr(6,yue); //將月寫入液晶顯示
- write_com(0x80+7); //光標(biāo)在月的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==6)
- {
- ri++; //當(dāng)num=6時(shí),日加一
- temp=day_num(nian,yue);
- if(ri>temp) //當(dāng)日大于當(dāng)月的天數(shù)時(shí),將日置1
- ri=1;
- write_nyr(9,ri); //將日寫入液晶顯示
- write_com(0x80+10); //光標(biāo)在月的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==7)
- {
- xingqi++; //當(dāng)num=7時(shí),星期加一
- if(xingqi>7) //當(dāng)星期大于7時(shí),將星期置1
- xingqi=1;
- write_xq(xingqi); //將星期寫入液晶顯示
- write_com(0x80+14); //光標(biāo)在星期的個(gè)位閃爍
- write_com(0x0f);
- }
- }
- }
- }
- if(num!=0) //當(dāng)功能鍵S3按下后,數(shù)值減小鍵S5才有用
- {
- a=1; //設(shè)置矩陣鍵盤第一排位高電平
- b=0; //設(shè)置矩陣鍵盤第二排位低電平
- if(e==0) //判斷S5有沒(méi)有被按下
- {
- delayms(5); //去抖延時(shí)
- if(e==0) //判斷S5有沒(méi)有被按下
- {
- while(!e); //判斷按鍵S5有沒(méi)有釋放
- if(num==1)
- {
- miao--; //當(dāng)num=1時(shí),秒值減一
- if(miao<0) //當(dāng)秒值小于0時(shí),將秒值置59
- miao=59;
- write_sfm(7,miao); //將秒值寫入液晶顯示
- write_com(0x80+0x40+8); //光標(biāo)在秒值的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==2)
- {
- fen--; //當(dāng)num=2時(shí),分值減一
- if(fen<0) //當(dāng)分值小于0時(shí),將分值置59
- fen=59;
- write_sfm(4,fen); //將分值寫入液晶顯示
- write_com(0x80+0x40+5); //光標(biāo)在分值的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==3)
- {
- shi--; //當(dāng)num=3時(shí),時(shí)鐘減一
- if(shi<0) //當(dāng)時(shí)鐘小于0時(shí),將時(shí)鐘置23
- shi=23;
- write_sfm(1,shi); //將時(shí)鐘寫入液晶顯示
- write_com(0x80+0x40+2); //光標(biāo)在時(shí)鐘的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==4)
- {
- nian--; //當(dāng)num=4時(shí),年減一
- if(nian<0) //當(dāng)年小于0時(shí),將年置99
- nian=99;
- write_nyr(3,nian); //將年寫入液晶顯示
- write_com(0x80+4); //光標(biāo)在年的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==5)
- {
- yue--; //當(dāng)num=5時(shí),月減一
- if(yue<1) //當(dāng)月小于1時(shí),將月置12
- yue=12;
- write_nyr(6,yue); //將月寫入液晶顯示
- write_com(0x80+7); //光標(biāo)在月的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==6)
- {
- ri--; //當(dāng)num=6時(shí),日減一
- temp=day_num(nian,yue);
- if(ri>temp)
- ri=temp;
- if(ri<1) //當(dāng)日小于1時(shí),將日置為當(dāng)月的天數(shù)
- ri=temp;
- write_nyr(9,ri); //將日寫入液晶顯示
- write_com(0x80+10); //光標(biāo)在月的個(gè)位閃爍
- write_com(0x0f);
- }
- if(num==7)
- {
- xingqi--; //當(dāng)num=7時(shí),星期加一
- if(xingqi<1) //當(dāng)星期小于1時(shí),將星期置7
- xingqi=7;
- write_xq(xingqi); //將星期寫入液晶顯示
- write_com(0x80+14); //光標(biāo)在星期的個(gè)位閃爍
- write_com(0x0f);
- }
- }
- }
- }
- }
- /*--------------
- ? 初始化時(shí)鐘函數(shù)
- --------------*/
- void set_time()
- {
- write_ds(0,0); //初始化時(shí)鐘秒鐘的數(shù)值為0
- write_ds(2,0); //初始化時(shí)鐘分鐘的數(shù)值為0
- write_ds(4,1); //初始化時(shí)鐘小時(shí)的數(shù)值為1
- write_ds(6,1); //初始化時(shí)鐘星期的數(shù)值為1
- write_ds(7,1); //初始化時(shí)鐘日的數(shù)值為1
- write_ds(8,1); //初始化時(shí)鐘月的數(shù)值為1
- write_ds(9,0); //初始化時(shí)鐘年的數(shù)值為0
- }
- /*------------
- ? 初始化程序
- ------------*/
- void init()
- {
- uchar i;
- dula=0; //關(guān)段鎖存器(不讓數(shù)碼管顯示)
- wela=0; //關(guān)位鎖存器
- lcden=0;
- write_com(0x38); //設(shè)置16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口(LCD初始化設(shè)置)
- write_com(0x0c); //設(shè)置開顯示,不顯示光標(biāo)(LCD初始化設(shè)置)
- write_com(0x06); //寫一個(gè)字符后地址指針自動(dòng)加一(LCD初始化設(shè)置)
- write_com(0x01); //顯示清零,數(shù)據(jù)指針清零(LCD初始化設(shè)置)
- write_com(0x80); //將數(shù)據(jù)指針定位到第一行第一字處
- for(i=0;i<16;i++)
- {
- write_date(table1[i]); //將字符串1寫入液晶
- }
- write_com(0x80+0x40); //將數(shù)據(jù)指針定位到第2行第1字處
- for(i=0;i<16;i++)
- {
- write_date(table2[i]); //將字符串2寫入液晶
- }
- set_time(); //初始化時(shí)鐘
- }
- void main()
- {
- init(); //調(diào)用初始化子程序
- while(1)
- {
- keyscan();
- if(flag1==0) //當(dāng)標(biāo)志位flag1等于0時(shí),才從DS12C887中讀取數(shù)據(jù)并送去液晶顯示
- {
- miao=read_ds(0); //從DS12C887中讀取秒的值
- write_sfm(7,miao); //將秒值送去液晶顯示
- fen=read_ds(0x02); //從DS12C887中讀取分的值
- write_sfm(4,fen); //將分值送去液晶顯示
- shi=read_ds(0x04); //從DS12C887中讀取小時(shí)的值
- write_sfm(1,shi); //將小時(shí)送去液晶顯示
- nian=read_ds(0x09); //從DS12C887中讀取年的值
- write_nyr(3,nian); //將年值送去液晶顯示
- yue=read_ds(0x08); //從DS12C887中讀取月份的值
- write_nyr(6,yue); //將月份送去液晶顯示
- ri=read_ds(0x07); //從DS12C887中讀取日的值
- temp1=day_num(nian,yue); //讀取當(dāng)月的天數(shù)值
- if(ri>temp1) //判斷DS12C887中的天數(shù)值是否大于當(dāng)月應(yīng)有的天數(shù),如大于則將天數(shù)值置1,如有需要請(qǐng)重新設(shè)置
- ri=1;
- write_nyr(9,ri); //將日值送去液晶顯示
- xingqi=read_ds(0x06); //從DS12C887中讀取星期的值
- write_xq(xingqi); //將星期送去液晶顯示
- }
- }
- }
復(fù)制代碼
|
評(píng)分
-
查看全部評(píng)分
|