(1)系統(tǒng)通過(guò)4×4的矩陣鍵盤輸入數(shù)字及運(yùn)算符。 (2)可以進(jìn)行多位十進(jìn)制數(shù)以內(nèi)的運(yùn)算(包括加,減,乘,除,冪次方,對(duì)數(shù),三角函數(shù)等功能),如果計(jì)算結(jié)果超過(guò)顯示范圍,則屏幕顯示E。 (3)可顯示輸入時(shí)的數(shù)字及結(jié)果 (4)設(shè)計(jì)控制電路總體方案; (5)電路的設(shè)計(jì)、仿真與調(diào)試; 之前做的,已經(jīng)仿真實(shí)現(xiàn)功能,內(nèi)含參考文檔,比較詳細(xì),應(yīng)該無(wú)需修改。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
proteus原理圖
單片機(jī)源程序如下:
- #include <stdio.h>
- #include <reg51.h>
- #include <intrins.h>
- #include <math.h>
- #include <ctype.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define Lint unsigned long int
- #define E 100000000
- #define C 999999
- uchar operand1[9], operand2[9]; /* 操作數(shù) */
- uchar operator; /* 操作符 */
- uchar k ; /* 運(yùn)算符切換標(biāo)志 */
- Lint mf(Lint pa, Lint pb);
- Lint number(uchar* operand[] );
- uchar keyscan();
- void buf(Lint value);
- void disp(void);
- void delay(uint);
- Lint compute(Lint va1,Lint va2,uchar optor);
-
- uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,
- 0x92,0x82,0xf8,0x80,0x90,0xff,0x86}; /* 字符碼表 */
- uchar dbuf[8] = {10,10,10,10,10,10,10,10}; /* 顯示緩存 */
- /* 延時(shí)函數(shù) */
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*******************************************
- 鍵盤掃描程序
- 將按鍵轉(zhuǎn)化為字符并作為輸出
- '
- [/size][/color][/font][/align]
- ,'#'分別表示清零鍵和沒(méi)有鍵按下
- 'S'表示shift鍵,用于切換運(yùn)算符
- *******************************************/
- uchar keyscan()
- {
- uchar skey; /* 按鍵值標(biāo)記變量 */
- /***********************
- 掃描鍵盤第1行
- ************************/
- P1 = 0xfe;
- while((P1 & 0xf0) != 0xf0) /* 有按鍵按下 */
- {
- delay(3); /* 去抖動(dòng)延時(shí) */
- while((P1 & 0xf0) != 0xf0) /* 仍有鍵按下 */
- {
- switch(P1) /* 識(shí)別按鍵并賦值 */
- {
- case 0xee: skey = '7'; break;
- case 0xde: skey = '8'; break;
- case 0xbe: skey = '9'; break;
- case 0x7e: if(k==0){skey = '/';}else if (k==1){skey = '~'; k=0 ;} break;
-
- default: skey = '#';
- }
- while((P1 & 0xf0) != 0xf0)
- ;
- }
- }
- /***********************
- 掃描鍵盤第2行
- ************************/
- P1 = 0xfd;
- while((P1 & 0xf0) != 0xf0)
- {
- delay(3);
- while((P1 & 0xf0) != 0xf0)
- {
- switch(P1)
- {
- case 0xed: skey = '4'; break;
- case 0xdd: skey = '5'; break;
- case 0xbd: skey = '6'; break;
- case 0x7d: if(k==0){skey = '*';}else if(k==1){skey = '^'; k=0 ;} break;
-
- default: skey = '#';
- }
- while((P1 & 0xf0) != 0xf0)
- ;
- }
- }
- /***********************
- 掃描鍵盤第3行
- ************************/
- P1 = 0xfb;
- while((P1 & 0xf0) != 0xf0)
- {
- delay(3);
-
- while((P1 & 0xf0) != 0xf0)
- {
- switch(P1)
- {
- case 0xeb: skey = '1'; break;
- case 0xdb: skey = '2'; break;
- case 0xbb: skey = '3'; break;
- case 0x7b: if(k==0){skey = '+';}else if(k==1){skey = '-'; k=0 ;} break;
-
- default: skey = '#';
- }
- while((P1 & 0xf0) != 0xf0)
- ;
- }
- }
- /***********************
- 掃描鍵盤第4行 & 判別運(yùn)算符
- ************************/
- P1 = 0xf7;
- while((P1 & 0xf0) != 0xf0)
- {
- delay(3);
- while((P1 & 0xf0) != 0xf0)
- {
- switch(P1) /* 識(shí)別按鍵并賦值 */
- {
- case 0xe7: skey = '
- [/size][/color][/font][/align]
- ; k = 0 ; break;
- case 0xd7: skey = '0'; break;
- case 0xb7: skey = '='; break;
- case 0x77: skey = 'S'; k = 1 ; break;
-
- default: skey = '#';
- }
- while((P1 & 0xf0) != 0xf0) /* 等待按鍵松開(kāi) */
- ;
- }
- }
-
- return skey;
- }
- void main()
- {
- Lint value1, value2, value; /* 數(shù)值1,數(shù)值2,結(jié)果 */
- uchar ckey, cut1 = 0, cut2 = 0; /* ckey鍵盤輸入字符 */
- uchar operator; /* 運(yùn)算符 */
- uchar i, bool = 0, k=0, s=0, t=0 ;
- init: /* goto語(yǔ)句定位標(biāo)簽 */
- buf(0); /* 初始化 */
- disp();
- value1=value2=0 ;
- value = 0;
- cut1 = cut2 = 0;
- bool = 0; /*操作數(shù)標(biāo)識(shí)符*/
- k = 0 ; /* shift轉(zhuǎn)換符號(hào)*/
- s = 0 ; /*防止重復(fù)運(yùn)算*/
- t = 0 ; /*連續(xù)運(yùn)算*/
-
- for(i = 0;i < 9;i++)
- {
- operand1[i] = '\0';
- operand2[i] = '\0';
- } /* 初始化 */
- while(1)
- {
- ckey = keyscan(); /* 讀取鍵盤 */
- if(ckey != '#')
- { /* isdigit函數(shù),字符是阿拉伯?dāng)?shù)字返回非0值,否則返回0 */
- if(isdigit(ckey))
- {
- switch(bool)
- {
- case 0:
- if(cut1 > 7) { value1 = E ; buf(value1); disp() ; break ; }
- operand1[cut1] = ckey;
- operand1[cut1+1] = '\0';
- value1 = number(operand1); /* 將字符串轉(zhuǎn)化為整數(shù) */
- cut1++;
- buf(value1);
- disp();
- break;
- case 1:
- if(cut2 > 7) { value2 = E ; buf(value2); disp() ; break ; }
- t = 1 ;
- operand2[cut2] = ckey;
- operand2[cut2+1] = '\0';
- value2 = number(operand2);
- cut2++;
- buf(value2);
- disp();
- break;
-
- default: break;
- }
- }
- else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/'||ckey=='^'||ckey=='~')
- {
- bool = 1;
- if( t == 1 && s == 0) /* 判斷是否為連續(xù)運(yùn)算 */
- {
- value1=compute(value1,value2,operator); /* 顯示上一步運(yùn)算結(jié)果 */
- cut2 = 0 ;
- }
- buf(value1);
- disp();
- operator = ckey;
- s = 0 ;
- }
- else if(ckey == 'S')
- {
- if( t == 1 )
- {
- value1=compute(value1,value2,operator);
- cut2 = 0 ;
- s = 1 ; /* 防重復(fù)運(yùn)算標(biāo)志 */
- }
- buf(value1);
- disp();
- }
- else if(ckey == '=')
- {
- value = compute(value1,value2,operator);
- buf(value);
- disp();
- while(1) /* 計(jì)算結(jié)束等待清零鍵按下 */
- {
- ckey = keyscan();
- if(ckey == '
- [/size][/color][/font][/align]
- ) /* 如果按下清零鍵則跳回開(kāi)始 */
- goto init;
- else
- {
- buf(value);
- disp();
- }
- }
- }
- else if(ckey == '
- [/size][/color][/font][/align]
- )
- { goto init;}
- }
- disp();
- }
- }
- /******************************************
- number函數(shù)
- 將字符串轉(zhuǎn)化為整數(shù)
- *******************************************/
- Lint number(uchar operand[] )
- {
- Lint n=0, i, j ;
- for(i=0 ; i<10 ; i++ )
- {
- if(operand[i]=='\0'){ break ; }
- n=n*10 ;
- j=operand[i]-'0' ;
- n=n+j ;
- }
- return n ;
- }
- /******************************************
- 運(yùn)算函數(shù)
- 輸入:操作數(shù)和操作符
- 輸出:計(jì)算結(jié)果
- *******************************************/
- Lint compute(Lint va1,Lint va2,uchar optor)
- {
- Lint value;
- switch(optor)
- {
-
- case '+' : value = va1+va2; break;
-
- case '-' :
- if(va1 < va2)
- {value = E ; break ;}
- else
- {value = va1-va2; break ;}
-
- case '*' : value = va1*va2; break;
-
- case '/' :
- if(va2 == 0)
- {value = E ; break ; }
- else
- {value = va1/va2; break;}
-
- case '^' : value = mf(va1,va2); break;
-
- case '~' : value = log(va2)/log(va1); break;
-
- default : value = E ; break;
- }
- return value;
- }
- /*******************************************
- 冪方函數(shù)
- *******************************************/
- Lint mf(Lint pa, Lint pb)
- {
- uint a, b ;
- a=pa ;
- b=pb ;
- for( ; b>1 ; b-- )
- {
- a=a*pa ;
- }
- return a ;
- }
- /*******************************************
- 更新顯示緩存
- 輸入:無(wú)符號(hào)整數(shù)
- 輸出:將輸入送入顯示緩存,溢出或出錯(cuò)顯示E
- *******************************************/
- void buf(Lint val)
- {
- uchar i;
- if(val == 0)
- {
- dbuf[7] = 0;
- i = 6;
- }
-
- else if (val == E || val > C )
- {
- dbuf[7] = 11 ;
- i = 6 ;
- }
- else
- {
- for(i = 7; val > 0; i--)
- {
- dbuf[i] = val % 10;
- val /= 10;
- }
- }
- for( i=i+1; i > 0; i--)
- dbuf[i-1] = 10;
- }
- /*******************************************
- 顯示函數(shù)
- *******************************************/
- void disp(void)
- {
- uchar bsel, n;
-
- bsel=0x01;
- for(n=0;n<8;n++)
- {
- P2=bsel;
- P0=table[dbuf[n]];
- bsel=_crol_(bsel,1);
- delay(3);
- P0=0xff;
- }
- }
復(fù)制代碼
全部資料51hei下載地址:
計(jì)算器設(shè)計(jì).rar
(595.87 KB, 下載次數(shù): 116)
2020-6-28 09:29 上傳
點(diǎn)擊文件名下載附件
多位十進(jìn)制計(jì)算器帶仿真
|