|
(1)系统通过4×4的矩阵键盘输入数字及运算符。 (2)可以进行多位十进制数以内的运算(包括加,减,乘,除,幂次方,对数,三角函数等功能),如果计算结果超过显示范围,则屏幕显示E。 (3)可显示输入时的数字及结果 (4)设计控制电路总体方案; (5)电路的设计、仿真与调试; 之前做的,已经仿真实现功能,内含参考文档,比较详细,应该无需修改。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
proteus原理图
单片机源程序如下:
- #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)
|
|