|
Proteus仿真和電路圖還有源程序在本帖附件中下載.
制作出來的實物圖:
計算器.jpg (63.31 KB, 下載次數(shù): 52)
下載附件
2018-7-5 12:54 上傳
Altium Designer畫的計算器與萬年歷原理圖和PCB圖如下:(51hei附件中可下載工程文件)
0.png (43.75 KB, 下載次數(shù): 45)
下載附件
2018-7-5 16:55 上傳
0.png (73.35 KB, 下載次數(shù): 33)
下載附件
2018-7-5 16:55 上傳
0.png (14.98 KB, 下載次數(shù): 41)
下載附件
2018-7-5 16:56 上傳
計算器與萬年歷仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (33.48 KB, 下載次數(shù): 34)
下載附件
2018-7-5 16:56 上傳
單片機計算器與萬年歷源程序如下:
- #include <reg52.h>
- #include <intrins.h> //包含_nop_()函數(shù)定義的頭文件
- #define uchar unsigned char
- #define uint unsigned int
- //以下是對1302的定義
- sbit clk= P2^3; //實時時鐘時鐘線引腳
- sbit IO= P2^2; //實時時鐘數(shù)據(jù)線引腳
- sbit rst =P2^1; //實時時鐘復(fù)位線引腳
- uchar second,minute,hour,week,day,month,year; //8421碼表示的時間 高四位用于表示十位,低四位用于表示個位
- char second1,minute1,hour1,week1,day1,month1,year1;//十進制表示的時間 也即普通意義下的時間
- uchar read_byte(uchar com);
- uchar readyear_byte(uchar com);
- void write_byte(uchar com,uchar date);
- void init_1302();
- void readtime();
- //以下是對lcd1602的定義
- sbit wela=P2^6;
- sbit dula=P2^7;
- uchar table[]="0123456789";
- sbit LCM_RS=P2^6; //寄存器選擇位,將RS位定義為P2.6引腳
- sbit LCM_EN=P2^5; //使能信號位,將E位定義為P2.5引腳
- bit lcd_bz(void);
- void write_com(unsigned char CMD);
- void write_date(unsigned char dataW);
- void init_1602();
- void displaytime();
- void delaynms(unsigned char n);
- //以下是對按鍵調(diào)時程序的定義
- sbit mode=P1^0; //調(diào)整鬧鐘或者時間時的選擇按鍵
- sbit plus=P1^1; //加1鍵
- sbit minus=P1^2; //減1鍵
- sbit s1=P1^3; //計算器和萬年歷切換鍵
- void key();
- void delay20ms();
- //以下是對溫度采集部分的定義
- sbit DS=P2^0; //DS18B20數(shù)據(jù)端口
- uchar code wendu[]="0123456789"; //利用一個溫度表解決溫度顯示亂碼
- void write_byte(uchar com,uchar date); //寫一個字節(jié)
- void tmpDelay(int num); // 延時
- void Init_DS18B20(); //初始化DS18B20
- unsigned char ReadOneChar(); //讀一個字節(jié)
- void WriteOneChar(unsigned char dat); //寫數(shù)據(jù)
- unsigned int Readtemp(); //讀溫度
- void display(); //顯示溫度
- uchar num;
- sbit lcden=P2^5; //定義引腳
- sbit rs=P2^6;
- sbit busy=P0^7; //LCD1602忙
- //計算器有關(guān)變量定義
- char i,j,temp,num_1,num1_2=0;
- long a,b,c; //a,第一個數(shù) b,第二個數(shù) c,得數(shù)
- float a_c,b_c;
- uchar flag,fuhao;//flag表示是否有符號鍵按下,fuhao表征按下的是哪個符號
- uchar code table1[]={
- 7,8,9,0,
- 4,5,6,0,
- 1,2,3,0,
- 0,0,0,0};
- uchar code table2[]={
- 7,8,9,0x2f-0x30,
- 4,5,6,0x2a-0x30,
- 1,2,3,0x2d-0x30,
- 0x01-0x30,0,0x3d-0x30,0x2b-0x30};
- void delay2(uchar z) // 延遲函數(shù)
- {
- uchar y;
- for(z;z>0;z--)
- for(y=0;y<110;y++);
- }
- void check() // 判斷忙或空閑
- {
- do{
- P0=0xFF; rs=0; //指令
- lcden=0; //禁止讀寫
- delay2(1); //等待,液晶顯示器處理數(shù)據(jù)
- lcden=1; //允許讀寫
- delay2(1); busy=0;
- }while(busy==1); //判斷是否為空閑,1為忙,0為空閑
- }
- void write_com1(uchar com) // 寫指令函數(shù)
- {
- P0=com; //com指令付給P0口
- rs=0;lcden=0;
- check();lcden=1;
- }
- void write_date1(uchar date) // 寫數(shù)據(jù)函數(shù)
- {
- P0=date;
- rs=1;
- lcden=0;
- check();
- lcden=1;
- }
- void init1() //初始化
- {
- num=-1;
- lcden=1; //使能信號為高電平
- write_com1(0x38); //8位,2行
- delay2(5);
- write_com1(0x38); //8位,2行
- delay2(5);
- write_com1(0x0c); //顯示開,光標(biāo)關(guān),不閃爍*/
- delay2(1);
- write_com1(0x06); //增量方式不移位
- delay2(1);
- write_com1(0x80); //檢測忙信號
- delay2(1);
- write_com1(0x01); //顯示開,光標(biāo)關(guān),不閃爍
- num_1=0;
- i=0;
- j=0;
- a=0; //第一個參與運算的數(shù)
- b=0; //第二個參與運算的數(shù)
- c=0;
- flag=0; //flag表示是否有符號鍵按下,
- fuhao=0; // fuhao表征按下的是哪個符號
- }
- void keyscan1() // 鍵盤掃描程序
- {
- P3=0xfe;
- if(P3!=0xfe)
- { delay2(20);// 延遲20ms
- if(P3!=0xfe) { temp=P3&0xf0;
- switch(temp)
- {
- case 0xe0:num=0; break;
- case 0xd0:num=1; break;
- case 0xb0:num=2; break;
- case 0x70:num=3; break;
- }
- } while(P3!=0xfe);
- if(num==0||num==1||num==2)//如果按下的是'7','8'或'9
- {
- if(j!=0){ write_com1(0x01); j=0; }
- if(flag==0){ a=a*10+table1[num]; }//沒有按過符號鍵
- else{ b=b*10+table1[num]; }//如果按過符號鍵
- }
- else//如果按下的是'/'
- { flag=1; fuhao=4;}//4表示除號已按
- i=table2[num]; write_date1(0x30+i);
- }
- P3=0xfd;
- if(P3!=0xfd)
- { delay2(20);
- if(P3!=0xfd){ temp=P3&0xf0;
- switch(temp)
- {
- case 0xe0:num=4; break;
- case 0xd0:num=5; break;
- case 0xb0:num=6; break;
- case 0x70:num=7; break;
- }
- } while(P3!=0xfd);
- if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
- {
- if(j!=0){write_com1(0x01); j=0;}
- if(flag==0){ a=a*10+table1[num]; }//沒有按過符號鍵
- else{ b=b*10+table1[num]; }//如果按過符號鍵
- }
- else//如果按下的是'/'
- { flag=1; fuhao=3;}//3表示乘號已按
- i=table2[num]; write_date1(0x30+i);
- }
- P3=0xfb;
- if(P3!=0xfb)
- { delay2(20);
- if(P3!=0xfb) { temp=P3&0xf0;
- switch(temp)
- {
- case 0xe0:num=8; break;
- case 0xd0:num=9; break;
- case 0xb0:num=10; break;
- case 0x70:num=11; break;
- }
- } while(P3!=0xfb);
- if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
- {
- if(j!=0){ write_com1(0x01); j=0; }
- if(flag==0){ a=a*10+table1[num]; }//沒有按過符號鍵
- else//如果按過符號鍵
- { b=b*10+table1[num]; }
- }
- else if(num==11)//如果按下的是'-'
- { flag=1; fuhao=2;}//2表示減號已按
- i=table2[num]; write_date1(0x30+i);
- }
- P3=0xf7;
- if(P3!=0xf7)
- { delay2(20);
- if(P3!=0xf7) {temp=P3&0xf0;
- switch(temp)
- {
- case 0xe0:num=12; break;
- case 0xd0:num=13; break;
- case 0xb0:num=14; break;
- case 0x70:num=15; break;
- }
- } while(P3!=0xf7);
- switch(num)
- {
- case 12:{write_com1(0x01);a=0;b=0;flag=0;fuhao=0;} break;//按下的是"清零"
- case 13:{ //按下的是"0"
- if(flag==0)//沒有按過符號鍵
- { a=a*10; write_date1(0x30); P2=0; }
- else if(flag>=1)//如果按過符號鍵
- { b=b*10; write_date1(0x30); }
- } break;
- case 14:{j=1;
- if(fuhao==1)
- {
- write_com1(0x80+0x4f);//按下等于鍵,光標(biāo)前進至第二行最后一個顯示處
- write_com1(0x04); //設(shè)置從后住前寫數(shù)據(jù),每寫完一個數(shù)據(jù),光標(biāo)后退一格
- c=a+b;
- while(c!=0){write_date1(0x30+c%10);c=c/10; }
- write_date1(0x3d); //再寫"="
- a=0;b=0;flag=0;fuhao=0;
- }
- else if(fuhao==2)
- {
- write_com1(0x80+0x4f);//光標(biāo)前進至第二行最后一個顯示處
- write_com1(0x04); //設(shè)置從后住前寫數(shù)據(jù),每寫完一個數(shù)據(jù),光標(biāo)后退一格(這個照理說順序不對,可顯示和上段一樣)
- if(a-b>0) c=a-b;
- else c=b-a;
- while(c!=0) {write_date1(0x30+c%10);c=c/10; }
- if(a-b<0) write_date1(0x2d);
- write_date1(0x3d); //再寫"="
- a=0;b=0;flag=0;fuhao=0;
- }
- else if(fuhao==3)
- {write_com1(0x80+0x4f); write_com1(0x04);
- c=a*b;
- while(c!=0){ write_date1(0x30+c%10);c=c/10;}
- write_date1(0x3d); a=0;b=0;flag=0;fuhao=0;
- }
- else if(fuhao==4)
- { write_com1(0x80+0x4f); write_com1(0x04);
- i=0;
- if(b!=0){
- c=(long)(((float)a/b)*1000);
- while(c!=0) { write_date1(0x30+c%10); c=c/10;
- i++;
- if(i==3)write_date1(0x2e); }
- if(a/b<=0) {
- if(i<=2) {if(i==1) write_date1(0x30);
- write_date1(0x2e); // .
- write_date1(0x30);}
- write_date1(0x30); //
- }
- write_date1(0x3d); a=0;b=0;flag=0;fuhao=0;
- }
- else
- {
- write_date1('!'); write_date1('R');
- write_date1('O'); write_date1('R');
- write_date1('R'); write_date1('E');
- }
- }
- } break;
- case 15:{write_date1(0x30+table2[num]);flag=1;fuhao=1;} break;
- }
- }
- }
- /**************************************************************
- 時鐘、計算器切換程序
- *************************************************************/
- void switchfunction()
- {unsigned char ID;
- if(!s1) //切換鍵按下
- { delay2(20); //延時
- if(!s1) //再判
- { init1(); //計算器初始化
- ID=1; //設(shè)置計算器工作模式標(biāo)志
- while(!s1) ;//等待切換鍵釋放
- while(ID)
- {
- keyscan1(); //調(diào)矩陣鍵盤掃描 ,進入計算器工作模式
- if(!s1) //切換鍵按下
- { delay2(20); if(!s1)
- { ID=0; //退出計算器工作模式,進入萬年歷工作模式
- init_1602();//萬年歷工作模式LCD1602初始化
- }
- while(!s1) ; //等待切換鍵按下
- }
- }
- }
- }
- }
- /**************************************************************
- 主程序
- *************************************************************/
- main()
- { init_1602(); //LCD1602初始化
- while(1)
- {readtime(); //讀時間
- displaytime(); //顯示時間
- key(); //調(diào)整時間鍵盤
- display(); //讀溫度并顯示
- switchfunction();//調(diào)功能切換程序,若功能切換鍵按下,進入計算器顯示模式
- }
- }
- /*****************************************************
- 函數(shù)功能:延時若干毫秒
- 入口參數(shù):n
- ***************************************************/
- void delaynms(unsigned char n) { unsigned char t,i,j;
- for(t=0;t<n;t++) for(i=0;i<10;i++) for(j=0;j<33;j++); }
- /*********************************************************************
- ds1302寫一個字節(jié)的數(shù)據(jù)
- 參數(shù):com 選擇要寫數(shù)據(jù)的寄存器地址
- date 向寄存器寫入的數(shù)據(jù)
- **********************************************************************/
- void write_byte(uchar com,uchar date)
- {
- uchar i;
- rst=0; //沒有先前的低電平不能工作,所以先將RST置成的低電平
- clk=0; //在寫命令前clk也是低電平
- rst=1; //開始寫命令
- for(i=0;i<8;i++)
- {
- if(com&0x01) IO=1;//獲取com的最低位
- else IO=0;
- com=com>>1; //移位,為下一位的發(fā)送做好準(zhǔn)備
- clk=1; _nop_(); //clk的高電平至少為250ns
- clk=0;
- } //到此,命令傳輸完畢
- for(i=0;i<8;i++) //緊接著傳輸數(shù)據(jù)
- {
- if(date&0x01) IO=1;
- else IO=0;
- date=date>>1; clk=1; _nop_(); clk=0;
- }
- rst=0; //結(jié)束傳輸
- }
- /*********************************************************************
- ds1302讀一個字節(jié)的數(shù)據(jù)
- 參數(shù):com 選擇要讀數(shù)據(jù)的寄存器地址
- date 從寄存器讀出的數(shù)據(jù)
- 由于讀出數(shù)據(jù)的最高位丟失(為0),這對于除了年變量以外的都沒有關(guān)系。但對于年,
- 當(dāng)年份超過2080年,將不能正常顯示,為此我為讀年專一再寫一個讀函數(shù)。
- **********************************************************************/
- uchar read_byte(uchar com)
- {
- uchar i;
- uchar date; //用來存儲讀到的數(shù)據(jù)
- rst=0; //沒有先前的低電平不能工作,所以先將RST置成的低電平
- clk=0; //在寫命令前clk也是低電平
- rst=1; //開始寫命令
- for(i=0;i<8;i++)
- {
- if(com&0x01) IO=1;//獲取com的最低位
- else IO=0;
- com=com>>1; //移位,為下一位的發(fā)送做好準(zhǔn)備
- clk=0; _nop_(); //clk的低電平至少為250ns
- clk=1;
- } //到此,命令傳輸完畢
- /*********************************************************************
- 接收數(shù)據(jù),接收的是1302發(fā)送的低7位,而dete的最高位為0,這樣做的目的是避免了后邊對
- 接收到數(shù)據(jù)的處理(因為日歷的七個變量的最高位在計算時必須處理成0)。
- 這里通過少接收一次數(shù)據(jù)實現(xiàn)除去最高位。
- *********************************************************************/
- for(i=0;i<8;i++)
- {
- if(IO==1) date|=0x80;//雖然也接收了八次,但第一次接收的數(shù)據(jù)不對(接收的肯定是1),且后來移位除掉了。實際上是接收了七位
- date=date>>1;
- clk=1; _nop_(); clk=0; //時鐘的下降沿,ds1302開始向主機發(fā)送數(shù)據(jù)
- }
- rst=0; //結(jié)束傳輸
- return date;
- }
- /*********************************************************************
- 這個函數(shù)能完整的讀取1302所傳的一個字節(jié)(八位數(shù)據(jù)),它的高位沒有丟失
- 當(dāng)年份超過2080年,也能正常顯示,這是我為讀年專一寫的一個函數(shù)。
- ************************************************************************/
- uchar readyear_byte(uchar com)
- {
- uchar i;
- uchar date; //用來存儲讀到的數(shù)據(jù)
- rst=0; //沒有先前的低電平不能工作,所以先將RST置成的低電平
- clk=0; //在寫命令前clk也是低電平
- rst=1; //開始寫命令
- for(i=0;i<8;i++)
- {
- if(com&0x01) IO=1;//獲取com的最低位
- else IO=0;
- com=com>>1; //移位,為下一位的發(fā)送做好準(zhǔn)備
- clk=0;
- _nop_(); //clk的低電平至少為250ns
- clk=1;
- } //到此,命令傳輸完畢
- for(i=0;i<8;i++)
- {
- date=date>>1; //由于空移了一次,所以沒有浪費數(shù)據(jù)
- clk=0; //時鐘的下降沿,ds1302開始向主機發(fā)送數(shù)據(jù)
- if(IO==1) date|=0x80;//這一次就能接收八次數(shù)據(jù),沒有無用的,也沒有浪費
- clk=1;
- }
- rst=0; //結(jié)束傳輸
- clk=0;
- return date;
- }
-
- void readtime()//讀出時間 時間的每一部分的最高位都已經(jīng)置零
- {
- year=readyear_byte(0x8d);
- month=read_byte(0x89);
- day=read_byte(0x87);
- hour=read_byte(0x85);
- minute=read_byte(0x83);
- second=read_byte(0x81);
- week=read_byte(0x8b);
- }
- /*********************************************************************************
- 一下是對lcd1602的操作
- ***********************************************************************************/
- /*******************************/ //lcd1602寫命令
- void write_com(unsigned char CMD)
- {
- delaynms(10); LCM_RS=0; LCM_EN=0; _nop_(); _nop_();
- P0=CMD; _nop_(); _nop_(); _nop_(); _nop_();
- LCM_EN=1;_nop_();_nop_();_nop_(); _nop_();LCM_EN=0;
- }
- /*******************************/ //lcd1602寫數(shù)據(jù)
- void write_date(unsigned char dataW)
- {
- delaynms(10); LCM_RS=1; LCM_EN=0; _nop_();
- P0=dataW; _nop_(); _nop_(); _nop_(); _nop_();
- LCM_EN=1; _nop_(); _nop_(); _nop_(); _nop_();
- LCM_EN=0;
- }
- void init_1602()//初始化液晶
- {
- wela=0;dula=0;
- write_com(0x38);delay20ms();
- write_com(0x38); delay20ms();
- write_com(0x38);delay20ms(); //初始化三次確保功能設(shè)定成功
- write_com(0x0c); write_com(0x06); write_com(0x01);
-
- write_com(0x85);//以下將液晶上不變的字符先顯示出來
- write_date('/');
- write_com(0x88);write_date('/');
- write_com(0xc2);write_date(':');
- write_com(0xc5);write_date(':');
- write_com(0xc0+13);write_date(0xdf); write_date('C');
- }
- /***************************************************************************
- 顯示時間 在計算時間(年 、月、日等等)的十位和個位時需要注意
- 這需要將8421碼表示的兩位十進制數(shù)的十位和個位分別求出來 十位=時間(比方說天)/16;個位=時間%16
- *****************************************************************************/
- void displaytime()
- {
- write_com(0x81); write_date(table[2]);write_date(table[0]);
- write_date(table[year/16]); write_date(table[year%16]);//顯示出年
-
- write_com(0x86);write_date(table[month/16]);write_date(table[month%16]);//顯示出月
-
- write_com(0x89);write_date(table[day/16]); //顯示出日
- write_date(table[day%16]);
-
- write_com(0x80+12); //顯示出星期
- switch(week) {
- case 1:write_date('M'); write_date('O'); write_date('N'); break;
- case 2:write_date('T'); write_date('U'); 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('T'); 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;
- }
- write_com(0xc0);write_date(table[hour/16]); write_date(table[hour%16]);//顯示出小時
- write_com(0xc3);write_date(table[minute/16]); write_date(table[minute%16]);//顯示出分鐘
- write_com(0xc6);write_date(table[second/16]);write_date(table[second%16]);//顯示出秒
- }
- /****************************************************************************
- 以下是有關(guān)鍵盤調(diào)時內(nèi)容的程序
- ******************************************************************************/
- /**************************************************************
- 函數(shù)功能:延時20ms的子程序
- **************************************************************/
- void delay20ms(){ unsigned char i,j;
- for(i=0;i<100;i++) for(j=0;j<60;j++) ;}
- void delay1(uchar z){ uchar x,y;
- for(x=1000;x>1;x--) for(y=z;y>1;y--); }
- /**************************************************************
- 函數(shù)功能:掃描鍵盤調(diào)時程序
- **************************************************************/
- void key()
- { uchar timenum; //調(diào)整時的標(biāo)志符。當(dāng)num=0時,正常工作狀態(tài)。當(dāng)num!=0時,就是調(diào)時狀態(tài)。
- if(mode==0) //當(dāng)按下模式選擇鍵就開始進入調(diào)時模式,直到num=0為止
- {delay20ms(); if(mode==0) { timenum++;}
- while(!mode==1); }
- if(timenum) //當(dāng)num不為零時,就處于調(diào)時狀態(tài),就讓1302停止計時。調(diào)時完成后,就重新打開計時
- {write_byte(0x8e,0); //調(diào)時過程中允許寫入
- second=read_byte(0x81); //先求出秒的數(shù)值
- write_byte(0x80,second|0x80);//再讓1302停止
- while(timenum) //進入循環(huán)的調(diào)時狀態(tài),直到num=0,跳出調(diào)時模塊
- {switch(timenum)
- { case 1:write_com(0x84); write_com(0x0f); //年
- delaynms(200); //讓年的個位閃爍需要足夠的時間
- year1=(year/16)*10+year%16; //把當(dāng)前從1302中讀出的8424碼表示的數(shù),轉(zhuǎn)化成十進制計算
- if(plus==0) //掃描按鍵
- { delay20ms(); //延遲后再檢測去除抖動
- if(plus==0){ year1++; //確認(rèn)按下后就加1
- if(year1==100) year1=0; write_byte(0x8c,((year1/10)*16+year1%10));}//將更改后的十進制年轉(zhuǎn)換成8421碼存入1302的年寄存器中
- } while(!plus) ; //等待按鍵釋放
- if(minus==0){delay20ms();
- if(minus==0){ year1--; if(year1==-1) year1=99;
- write_byte(0x8c,((year1/10)*16+year1%10)); }
- }while(!minus) ;
- year=readyear_byte(0x8d); //將年讀出來
- write_com(0x83); //將年顯示出來,以使調(diào)整后能看到變化
- write_date(table[year/16]); write_date(table[year%16]); break;
- case 2: write_com(0x87); //選擇光標(biāo)閃爍的位置,月的個位
- delaynms(200); //讓月的個位閃爍需要足夠的時間
- month1=(month/16)*10+month%16; //把當(dāng)前從1302中讀出的8424碼表示的數(shù),轉(zhuǎn)化成十進制計算
- if(plus==0) { delay20ms();
- if(plus==0) {month1++; if(month1==13) month1=1;write_byte(0x88,((month1/10)*16+month1%10));}
- } while(!plus) ;
- if(minus==0){ delay20ms();
- if(minus==0){ month1--; if(month1==0) month1=12;
- write_byte(0x88,((month1/10)*16+month1%10)); }
- } while(!minus) ;
- month=read_byte(0x89);
- write_com(0x86); write_date(table[month/16]);
- write_date(table[month%16]);//顯示出月
- break;
- case 3:write_com(0x80+10);
- delaynms(200);
- day1=(day/16)*10+day%16; //把當(dāng)前從1302中讀出的8424碼表示的數(shù),轉(zhuǎn)化成十進制計算
- if(plus==0){ delay20ms();
- if(plus==0){ day1++;
- switch(month1)//對于日的調(diào)整比較麻煩1,3,5,7,8,10,12月有31天;而4,6,9,11有30天;閏年的2月29天,平年則有28天
- {case 1:case 3:case 5:case 7:case 8:case 10:case 12: if(day1==32) day1=1;break;
- case 4:case 6:case 9:case 11: if(day1==31) day1=1;break;
- case 2:if(year1%4==0) {if(day1==30) day1=1;}
- else {if(day1=29) day1=1;} break;
- }
- write_byte(0x86,((day1/10)*16+day1%10));
- }
- }while(!plus) ;
- if(minus==0){ delay20ms();
- if(minus==0){ day1--;
- switch(month1)
- {case 1:case 3:case 5:case 7:case 8:case 10:case 12: if(day1==0) day1=31;break;
- case 4:case 6:case 9:case 11: if(day1==0) day1=30;break;
- case 2:if(year1%4==0) {if(day1==0) day1=29;}
- else {if(day1=0) day1=28;} break;
- }
- write_byte(0x86,((day1/10)*16+day1%10));
- }
- }while(!minus) ;
- day=read_byte(0x87);write_com(0x89);
- write_date(table[day/16]); write_date(table[day%16]);
- break;
- case 4:write_com(0x80+14); //星期
- delaynms(200);
- week1=(week/16)*10+week%16; //把當(dāng)前從1302中讀出的8424碼表示的數(shù),轉(zhuǎn)化成十進制計算
- if(plus==0){ delay20ms();
- if(plus==0) { week1++;
- if(week1==8) week1=1;
- write_byte(0x8a,((week1/10)*16+week1%10)); }
- } while(!plus) ;
- if(minus==0){ delay20ms();
- if(minus==0) { week1--;
- if(week1==0) week1=7;
- write_byte(0x8a,((week1/10)*16+week1%10)); }
- }while(!minus) ;
- week=read_byte(0x8b);//顯示出星期
- write_com(0x80+12);
- switch(week)
- {
- case 1: write_date('M');write_date('O'); write_date('N');break;
- case 2:write_date('T');write_date('U');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('T');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;
- } break;
- case 5: write_com(0xc1); //時
- delaynms(200);
- hour1=(hour/16)*10+hour%16; //把當(dāng)前從1302中讀出的8424碼表示的數(shù),轉(zhuǎn)化成十進制計算
- if(plus==0){ delay20ms();
- if(plus==0){ hour1++; if(hour1==24) hour1=0;
- write_byte(0x84,((hour1/10)*16+hour1%10)); }
- }while(!plus) ;
- if(minus==0) {delay20ms();
- if(minus==0){ hour1--; if(hour1==-1) hour1=23;
- write_byte(0x84,((hour1/10)*16+hour1%10)); }
- } while(!minus) ;
- hour=read_byte(0x85);write_com(0xc0);
- write_date(table[hour/16]); write_date(table[hour%16]);//顯示出小時
-
- break;
- case 6: write_com(0xc4); //分
- delaynms(200);
- minute1=(minute/16)*10+minute%16; //把當(dāng)前從1302中讀出的8424碼表示的數(shù),轉(zhuǎn)化成十進制計算
- if(plus==0){ delay20ms();
- if(plus==0){minute1++; if(minute1==60) minute1=0;
- write_byte(0x82,((minute1/10)*16+minute1%10)); }
- }while(!plus) ;
- if(minus==0){delay20ms();
- if(minus==0){ minute1--; if(minute1==-1) minute1=59; }
- write_byte(0x82,((minute1/10)*16+minute1%10));
- } while(!minus) ;
- minute=read_byte(0x83); write_com(0xc3);
- write_date(table[minute/16]);write_date(table[minute%16]);//顯示出分鐘
- break;
- case 7: write_com(0xc7); //秒
- delaynms(200);
- second1=(second/16)*10+second%16; //把當(dāng)前從1302中讀出的8424碼表示的數(shù),轉(zhuǎn)化成十進制計算
- if(plus==0) { delay20ms();
- if(plus==0){ second1++;if(second1==60) second1=0;
- write_byte(0x80,((second1/10)*16+second1%10)|0x80);//將更改后的十進制秒轉(zhuǎn)換成8421碼存入1302的年寄存器中
- //由于read_byte()函數(shù)的最高位沒讀(為0)。雖然秒的最高位在停止時已經(jīng)置成1,但是由于最高位的丟失,所以按前邊的寫進去必定又將計時啟動了。
- //這里在char型變量秒的最高位添了1以保證調(diào)秒時也停止計時
- }
- } while(!plus) ;
- if(minus==0){delay20ms();
- if(minus==0){second1--; if(second1==-1) second1=59;
- write_byte(0x80,((second1/10)*16+second1%10)|0x80); }
- } while(!minus) ;
- second=read_byte(0x81); write_com(0xc6);
- write_date(table[second/16]);write_date(table[second%16]);//顯示出秒
- break;
- }
- if(mode==0) //當(dāng)按下模式選擇鍵選擇要調(diào)整的量,當(dāng)num=0時跳出調(diào)時狀態(tài)
- { delay20ms();
- if(mode==0) { timenum++; }
- while(!mode==1);
- }
- if(timenum==8){ timenum=0; } //當(dāng)調(diào)整完時,num=0,就可以脫離調(diào)時狀態(tài)
-
- }
- second=read_byte(0x81); //先求出秒的數(shù)值
- write_byte(0x80,second&0x7f); //再讓1302啟動
- write_byte(0x8e,0x80); //禁止寫入
- write_com(0x0c); //光標(biāo)在調(diào)整年(num=1)時開始閃爍,在調(diào)整其他位(num=2,3,4,5,6,7)時也在閃爍,。調(diào)整完(num=0)時,停止閃爍
- }
- }
- /*************DS18B20溫度讀取模塊*************/
- void tmpDelay(int num)//延時函數(shù)
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
0.png (43.32 KB, 下載次數(shù): 35)
下載附件
2018-7-5 16:57 上傳
所有資料51hei提供下載:
計算器與萬年歷.zip
(796.33 KB, 下載次數(shù): 83)
2018-7-5 12:58 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|