|
(1)系統通過4×4的矩陣鍵盤輸入數字及運算符。 (2)可以進行多位十進制數以內的運算(包括加,減,乘,除,冪次方,對數,三角函數等功能),如果計算結果超過顯示范圍,則屏幕顯示E。 (3)可顯示輸入時的數字及結果 (4)設計控制電路總體方案; (5)電路的設計、仿真與調試; 之前做的,已經仿真實現功能,內含參考文檔,比較詳細,應該無需修改。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
$V20R2`5Y)(S3[]J)BPMBNR.png (33.28 KB, 下載次數: 79)
下載附件
proteus原理圖
2020-6-28 09:33 上傳
單片機源程序如下:
- #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]; /* 操作數 */
- uchar operator; /* 操作符 */
- uchar k ; /* 運算符切換標志 */
- 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}; /* 顯示緩存 */
- /* 延時函數 */
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*******************************************
- 鍵盤掃描程序
- 將按鍵轉化為字符并作為輸出
- '
- [/size][/color][/font][/align]
- ,'#'分別表示清零鍵和沒有鍵按下
- 'S'表示shift鍵,用于切換運算符
- *******************************************/
- uchar keyscan()
- {
- uchar skey; /* 按鍵值標記變量 */
- /***********************
- 掃描鍵盤第1行
- ************************/
- P1 = 0xfe;
- while((P1 & 0xf0) != 0xf0) /* 有按鍵按下 */
- {
- delay(3); /* 去抖動延時 */
- while((P1 & 0xf0) != 0xf0) /* 仍有鍵按下 */
- {
- switch(P1) /* 識別按鍵并賦值 */
- {
- 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行 & 判別運算符
- ************************/
- P1 = 0xf7;
- while((P1 & 0xf0) != 0xf0)
- {
- delay(3);
- while((P1 & 0xf0) != 0xf0)
- {
- switch(P1) /* 識別按鍵并賦值 */
- {
- 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) /* 等待按鍵松開 */
- ;
- }
- }
-
- return skey;
- }
- void main()
- {
- Lint value1, value2, value; /* 數值1,數值2,結果 */
- uchar ckey, cut1 = 0, cut2 = 0; /* ckey鍵盤輸入字符 */
- uchar operator; /* 運算符 */
- uchar i, bool = 0, k=0, s=0, t=0 ;
- init: /* goto語句定位標簽 */
- buf(0); /* 初始化 */
- disp();
- value1=value2=0 ;
- value = 0;
- cut1 = cut2 = 0;
- bool = 0; /*操作數標識符*/
- k = 0 ; /* shift轉換符號*/
- s = 0 ; /*防止重復運算*/
- t = 0 ; /*連續運算*/
-
- for(i = 0;i < 9;i++)
- {
- operand1[i] = '\0';
- operand2[i] = '\0';
- } /* 初始化 */
- while(1)
- {
- ckey = keyscan(); /* 讀取鍵盤 */
- if(ckey != '#')
- { /* isdigit函數,字符是阿拉伯數字返回非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); /* 將字符串轉化為整數 */
- 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) /* 判斷是否為連續運算 */
- {
- value1=compute(value1,value2,operator); /* 顯示上一步運算結果 */
- 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 ; /* 防重復運算標志 */
- }
- buf(value1);
- disp();
- }
- else if(ckey == '=')
- {
- value = compute(value1,value2,operator);
- buf(value);
- disp();
- while(1) /* 計算結束等待清零鍵按下 */
- {
- ckey = keyscan();
- if(ckey == '
- [/size][/color][/font][/align]
- ) /* 如果按下清零鍵則跳回開始 */
- goto init;
- else
- {
- buf(value);
- disp();
- }
- }
- }
- else if(ckey == '
- [/size][/color][/font][/align]
- )
- { goto init;}
- }
- disp();
- }
- }
- /******************************************
- number函數
- 將字符串轉化為整數
- *******************************************/
- 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 ;
- }
- /******************************************
- 運算函數
- 輸入:操作數和操作符
- 輸出:計算結果
- *******************************************/
- 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;
- }
- /*******************************************
- 冪方函數
- *******************************************/
- Lint mf(Lint pa, Lint pb)
- {
- uint a, b ;
- a=pa ;
- b=pb ;
- for( ; b>1 ; b-- )
- {
- a=a*pa ;
- }
- return a ;
- }
- /*******************************************
- 更新顯示緩存
- 輸入:無符號整數
- 輸出:將輸入送入顯示緩存,溢出或出錯顯示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;
- }
- /*******************************************
- 顯示函數
- *******************************************/
- 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;
- }
- }
復制代碼
全部資料51hei下載地址:
計算器設計.rar
(595.87 KB, 下載次數: 116)
2020-6-28 09:29 上傳
點擊文件名下載附件
多位十進制計算器帶仿真 下載積分: 黑幣 -5
|
|