找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4538|回复: 0
收起左侧

51单片机实现多位十进制计算器 带Proteus仿真原理图

[复制链接]
ID:791490 发表于 2020-6-28 09:33 | 显示全部楼层 |阅读模式
1)系统通过4×4的矩阵键盘输入数字及运算符。
2)可以进行多位十进制数以内的运算(包括加,减,乘,除,幂次方,对数,三角函数等功能),如果计算结果超过显示范围,则屏幕显示E
3)可显示输入时的数字及结果
4)设计控制电路总体方案;
    (5)电路的设计、仿真与调试;
之前做的,已经仿真实现功能,内含参考文档,比较详细,应该无需修改。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

proteus原理图

proteus原理图


单片机源程序如下:
  1. #include <stdio.h>
  2. #include <reg51.h>
  3. #include <intrins.h>
  4. #include <math.h>
  5. #include <ctype.h>               

  6. #define uchar unsigned char
  7. #define uint unsigned int
  8. #define Lint unsigned long int
  9. #define E 100000000
  10. #define C 999999

  11. uchar operand1[9], operand2[9];  /*   操作数   */
  12. uchar operator;                                         /*   操作符   */
  13. uchar k ;                /*   运算符切换标志    */

  14. Lint mf(Lint pa, Lint pb);   
  15. Lint number(uchar* operand[] );

  16. uchar keyscan();

  17. void buf(Lint value);
  18. void disp(void);
  19. void delay(uint);

  20. Lint compute(Lint va1,Lint va2,uchar optor);
  21.                                                                                                                                  
  22. uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,
  23.                                 0x92,0x82,0xf8,0x80,0x90,0xff,0x86};     /*   字符码表   */

  24. uchar dbuf[8] = {10,10,10,10,10,10,10,10};                    /*   显示缓存   */

  25. /*   延时函数   */               
  26. void delay(uint z)
  27. {
  28. uint x,y;
  29. for(x=z;x>0;x--)
  30.         for(y=110;y>0;y--);
  31. }

  32. /*******************************************
  33.               键盘扫描程序
  34.        将按键转化为字符并作为输出
  35.     '
  36. [/size][/color][/font][/align]
  37. ,'#'分别表示清零键和没有键按下
  38.     'S'表示shift键,用于切换运算符
  39. *******************************************/
  40. uchar keyscan()
  41. {
  42.         uchar skey;                     /*   按键值标记变量    */


  43. /***********************
  44.      扫描键盘第1行   
  45. ************************/
  46.         P1 = 0xfe;
  47.         while((P1 & 0xf0) != 0xf0)                     /*      有按键按下     */
  48.         {
  49.                 delay(3);                                                /*      去抖动延时     */

  50.                 while((P1 & 0xf0) != 0xf0)                                   /*      仍有键按下     */
  51.                 {
  52.                         switch(P1)                                                                         /*    识别按键并赋值   */
  53.                         {
  54.                                 case 0xee: skey = '7'; break;
  55.                                 case 0xde: skey = '8'; break;
  56.                                 case 0xbe: skey = '9'; break;
  57.                                 case 0x7e: if(k==0){skey = '/';}else if (k==1){skey = '~'; k=0 ;} break;
  58.                                        
  59.                                 default:   skey = '#';
  60.                         }

  61.                         while((P1 & 0xf0) != 0xf0)
  62.                                 ;
  63.                 }
  64.         }

  65. /***********************
  66.      扫描键盘第2行   
  67. ************************/
  68.         P1 = 0xfd;        
  69.         while((P1 & 0xf0) != 0xf0)
  70.         {
  71.                 delay(3);

  72.                 while((P1 & 0xf0) != 0xf0)
  73.                 {
  74.                         switch(P1)
  75.                         {
  76.                                 case 0xed: skey = '4'; break;
  77.                                 case 0xdd: skey = '5'; break;
  78.                                 case 0xbd: skey = '6'; break;
  79.                                 case 0x7d: if(k==0){skey = '*';}else if(k==1){skey = '^'; k=0 ;} break;
  80.                                        
  81.                                 default:   skey = '#';
  82.                         }

  83.                         while((P1 & 0xf0) != 0xf0)
  84.                                 ;
  85.                 }
  86.         }


  87. /***********************
  88.      扫描键盘第3行   
  89. ************************/
  90.         P1 = 0xfb;
  91.         while((P1 & 0xf0) != 0xf0)
  92.         {
  93.                 delay(3);
  94.                
  95.                 while((P1 & 0xf0) != 0xf0)
  96.                 {
  97.                         switch(P1)
  98.                         {
  99.                                 case 0xeb: skey = '1'; break;
  100.                                 case 0xdb: skey = '2'; break;
  101.                                 case 0xbb: skey = '3'; break;
  102.                                 case 0x7b: if(k==0){skey = '+';}else if(k==1){skey = '-'; k=0 ;} break;
  103.                                        
  104.                                 default: skey = '#';
  105.                         }

  106.                         while((P1 & 0xf0) != 0xf0)
  107.                                 ;
  108.                 }
  109.         }
  110. /***********************
  111.      扫描键盘第4行  &   判别运算符  
  112. ************************/
  113.         P1 = 0xf7;
  114.         while((P1 & 0xf0) != 0xf0)     
  115.         {
  116.                 delay(3);                    

  117.                 while((P1 & 0xf0) != 0xf0)   
  118.                 {
  119.                         switch(P1)                  /*    识别按键并赋值   */
  120.                         {
  121.                                 case 0xe7: skey = '
  122. [/size][/color][/font][/align]
  123. ; k = 0 ; break;
  124.                                 case 0xd7: skey = '0'; break;
  125.                                 case 0xb7: skey = '='; break;
  126.                                 case 0x77: skey = 'S'; k = 1 ; break;
  127.                                        
  128.                                 default:   skey = '#';
  129.                         }

  130.                         while((P1 & 0xf0) != 0xf0)   /*    等待按键松开    */
  131.                                 ;
  132.                 }
  133.         }
  134.    
  135.         return skey;
  136. }

  137. void main()
  138. {        
  139.         Lint value1, value2, value;                   /*    数值1,数值2,结果    */
  140.         uchar ckey, cut1 = 0, cut2 = 0;  /*    ckey键盘输入字符    */
  141.         uchar operator;                               /*         运算符         */
  142.         uchar i, bool = 0, k=0, s=0, t=0 ;

  143. init:                                                                   /*    goto语句定位标签    */

  144.         buf(0);                            /*         初始化         */
  145.         disp();
  146.         value1=value2=0 ;
  147.         value = 0;
  148.         cut1 = cut2 = 0;
  149.         bool = 0;                        /*操作数标识符*/         
  150.         k = 0 ;                          /* shift转换符号*/
  151.         s = 0 ;                                /*防止重复运算*/
  152.         t = 0 ;                                 /*连续运算*/
  153.         
  154.         for(i = 0;i < 9;i++)
  155.         {
  156.                 operand1[i] = '\0';
  157.                 operand2[i] = '\0';
  158.         }                                  /*         初始化         */

  159.         while(1)
  160.         {
  161.                 ckey = keyscan();             /*         读取键盘        */
  162.                 if(ckey != '#')
  163.                 { /*  isdigit函数,字符是阿拉伯数字返回非0值,否则返回0  */
  164.                         if(isdigit(ckey))         
  165.                         {
  166.                                 switch(bool)        
  167.                                 {
  168.                                         case 0:
  169.                                                   if(cut1 > 7) { value1 = E ; buf(value1); disp() ; break ; }
  170.                                                         operand1[cut1] = ckey;                        
  171.                                                         operand1[cut1+1] = '\0';
  172.                                                         value1 = number(operand1);  /*  将字符串转化为整数  */
  173.                                                         cut1++;        
  174.                                                         buf(value1);
  175.                                                         disp();
  176.                                                         break;
  177.                                         case 1:
  178.                                                   if(cut2 > 7) { value2 = E ; buf(value2); disp() ; break ; }
  179.                                                         t = 1 ;
  180.                                                         operand2[cut2] = ckey;
  181.                                                         operand2[cut2+1] = '\0';
  182.                                                         value2 = number(operand2);
  183.                                                         cut2++;
  184.                                                         buf(value2);
  185.                                                         disp();
  186.                                                         break;
  187.                                                         
  188.                                         default: break;
  189.                                 }
  190.                         }
  191.                         else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/'||ckey=='^'||ckey=='~')
  192.                         {
  193.                                 bool = 1;        
  194.                                 if( t == 1 && s == 0)                      /*  判断是否为连续运算  */
  195.                                 {
  196.                                    value1=compute(value1,value2,operator);     /*  显示上一步运算结果  */
  197.                                    cut2 = 0 ;
  198.                                 }
  199.                                 buf(value1);
  200.                                 disp();
  201.                                 operator = ckey;
  202.                                 s = 0 ;
  203.                         }
  204.                         else if(ckey == 'S')
  205.                         {
  206.                            if( t == 1 )
  207.                                 {
  208.                                    value1=compute(value1,value2,operator);     
  209.                                    cut2 = 0 ;
  210.                                    s = 1 ;                                       /*  防重复运算标志  */
  211.                                 }
  212.                            buf(value1);
  213.                            disp();
  214.                         }
  215.                         else if(ckey == '=')
  216.                         {
  217.                                 value = compute(value1,value2,operator);
  218.                                 buf(value);
  219.                                 disp();                                                                     
  220.                                 while(1)                     /*   计算结束等待清零键按下   */
  221.                                 {
  222.                                         ckey = keyscan();
  223.                                         if(ckey == '
  224. [/size][/color][/font][/align]
  225. )           /* 如果按下清零键则跳回开始 */
  226.                                                 goto init;
  227.                                         else
  228.                                                 {
  229.                                                         buf(value);
  230.                                                         disp();
  231.                                                 }
  232.                                 }
  233.                         }
  234.                         else if(ckey == '
  235. [/size][/color][/font][/align]
  236. )
  237.                         {        goto init;}
  238.                 }
  239.                 disp();
  240.         }
  241. }

  242. /******************************************
  243.                  number函数
  244.                      将字符串转化为整数
  245. *******************************************/

  246. Lint number(uchar operand[] )
  247. {
  248.         Lint n=0, i, j ;
  249.         for(i=0 ; i<10 ; i++ )
  250.         {
  251.            if(operand[i]=='\0'){ break ; }
  252.            n=n*10 ;                                                                  
  253.            j=operand[i]-'0' ;                                          
  254.            n=n+j ;
  255.         }
  256.         return n ;
  257. }

  258. /******************************************
  259.                  运算函数

  260. 输入:操作数和操作符
  261. 输出:计算结果
  262. *******************************************/
  263. Lint compute(Lint va1,Lint va2,uchar optor)
  264. {
  265.         Lint value;

  266.         switch(optor)
  267.         {
  268.                
  269.                 case '+' : value = va1+va2;        break;
  270.                
  271.                 case '-' :
  272.       if(va1 < va2)
  273.                         {value = E ; break ;}
  274.                         else
  275.                         {value = va1-va2;        break  ;}
  276.                         
  277.                 case '*' : value = va1*va2;        break;
  278.                         
  279.                 case '/' :
  280.                         if(va2 == 0)
  281.                         {value = E ; break ; }
  282.                         else
  283.                         {value = va1/va2;        break;}
  284.                         
  285.                 case '^' : value = mf(va1,va2); break;
  286.                         
  287.                 case '~' : value = log(va2)/log(va1); break;
  288.                         
  289.                 default : value = E ; break;
  290.         }
  291.         return value;
  292. }

  293. /*******************************************
  294.                幂方函数      
  295. *******************************************/

  296. Lint mf(Lint pa, Lint pb)
  297. {
  298.     uint a, b ;
  299.         a=pa ;
  300.         b=pb ;
  301.         for( ; b>1 ; b-- )
  302.         {
  303.             a=a*pa ;         
  304.         }
  305.         return a ;
  306. }

  307. /*******************************************
  308.               更新显示缓存

  309. 输入:无符号整数
  310. 输出:将输入送入显示缓存,溢出或出错显示E
  311. *******************************************/
  312. void buf(Lint val)
  313. {
  314.         uchar i;
  315.         if(val == 0)
  316.         {
  317.                 dbuf[7] = 0;
  318.                 i = 6;
  319.         }
  320.         
  321.         else if        (val == E || val > C )     
  322.         {
  323.            dbuf[7] = 11 ;
  324.            i = 6 ;
  325.         }         
  326.         else
  327.         {
  328.                 for(i = 7; val > 0; i--)                        
  329.                 {
  330.                         dbuf[i] = val % 10;
  331.                         val /= 10;
  332.                 }
  333.         }
  334.         for( i=i+1; i > 0; i--)
  335.                 dbuf[i-1] = 10;        
  336. }

  337. /*******************************************
  338.                显示函数      
  339. *******************************************/
  340. void disp(void)
  341. {
  342.         uchar bsel, n;
  343.         
  344.         bsel=0x01;
  345.     for(n=0;n<8;n++)
  346.     {
  347.                 P2=bsel;
  348.                 P0=table[dbuf[n]];
  349.                 bsel=_crol_(bsel,1);
  350.                 delay(3);
  351.                 P0=0xff;
  352.     }
  353. }
复制代码

全部资料51hei下载地址:
计算器设计.rar (595.87 KB, 下载次数: 115)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表