找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6391|回复: 3
收起左侧

单片机矩阵键盘实现简易计算器的仿真源码与实物制作

[复制链接]
ID:372961 发表于 2018-7-22 16:26 | 显示全部楼层 |阅读模式
protues仿真:

原理图

原理图

被加数

被加数

加号

加号

加数

加数

结果

结果

IMG_0205.JPG IMG_0206.JPG IMG_0208.JPG


  1. /*******************************************************************************
  2. *  标题:                     矩阵键盘实现简易计算器                            *
  3. *  时间                      2018年7月22日15:53:57                                                   *
  4. *                                                                                                                                                           *
  5. *  实验说明:用矩阵键盘实现简易计算器,可以进行四位数的加减乘除,数字显示在动态*
  6. 数码管,+、-、*、/显示在静态数码管上,每次必须输入四个数字数码管才会亮,例如, *
  7. 要计算 6+7,那么第一步是输入0006,才会在数码管上显示0006,第二步是+,静态数码管 *
  8. 上就会出现一个类似+的符号,接着输入0007,步骤同上,最后按=,得出结果                       *                                                      
  9. ********************************************************************************
  10. * 实验心得:做这个简易计算器一共做了快四天,碰到了许多问题,时间浪费最多的是在 *
  11. 数组定义那里,如果定义成unsigned int code[].那么该数组就不能进行值的改变,所以 *
  12. 需要                                                                                                                                               *
  13. 定义成unsigned int[]。还有一个问题就是很奇怪的一个,就是把xianshi()这个函数放在*
  14. while(1)                                                                                                                                           *
  15.            {                                                                                                                                           *
  16.                    Two();                                                                                                                                   *
  17.                 if(KeyScan()==8)                                                                                                           *
  18.                 {                                                                                                                                       *
  19.                         KeyValue=12;                                                                                                           *
  20.                     RES();                                                                                                                           *
  21.                         First[0]=16;                                                                                                           *
  22.                         First[1]=16;                                                                                                           *
  23.                         First[2]=16;                                                                                                           *
  24.                         First[3]=16;                                                                                                           *
  25.                         KeyValue=8;                                                                                                                   *
  26.                     break;                                                                                                                           *
  27.                 }这个里面,就输出不了结果,很奇怪???现在还不知道为什么会这样,如果有*
  28.                 知道                                                                                                                                   *
  29. 的,评论啊。                                                                                                                                   *
  30. 最后一个就是protues仿真那里,keypad的线怎么接???,一直不行                  *
  31. ********************************************************************************/

  32. #include <reg52.h>
  33. #include <math.h>
  34. unsigned int result,m,n;//result为计算结果,m为被X数,n为X数
  35. unsigned int KeyValue=-1;//相当于一个flag的作用
  36. unsigned char code DIG_CODE[16]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
  37.                                  0x7F, 0x6F, 0x70, 0x40, 0x76, 0x49,0x09};//数码管上显示编码(0~9,+、-、*、/、=)
  38. unsigned int code change[17]={0x3F,0x06,0x66,0x07,0x3F,0x5B,0x6D,0x7F,0x09,0x4F,0x7D,0x6F,0x70,0x40,0x76,0x49,0x00};
  39. unsigned int code changenumber[16]={0,1,4,7,0,2,5,8,14,3,6,9,10,11,12,13};


  40. unsigned int First[4];//定义一个有4个单元的数组,如果定义成 unsigned int code First[4],这个数组就不能修改值
  41. unsigned int Second[4];
  42. unsigned int value[8];//给计算出来的result存放值

  43. #define GPIO_SHOW P0
  44. #define GPIO_KEY P1
  45. #define GPIO_DIG P2

  46. sbit LSA = P3^0;
  47. sbit LSB = P3^1;
  48. sbit LSC = P3^2;

  49. void RES();//返回计算结果函数
  50. void xianshi();        //显示最终的计算结果
  51. void caculate();//计算第一个数和最后一数
  52. void Rejudge();//判断第二个数的函数
  53. void judge();//判断第一个数的函数
  54. int KeyScan(void);//按键扫描函数
  55. void Delay10ms(unsigned int c);//延迟函数
  56. void One();//被X数
  57. void Two();//X数

  58. void main()
  59. {
  60.         while(1)
  61.         {
  62.         judge();
  63.         while(1)
  64.         {
  65.           One();
  66.          
  67.           if(KeyValue==8)
  68.           {
  69.                  GPIO_DIG=change[8];
  70.                   xianshi();
  71.                 if(KeyScan()==0)
  72.                 break;
  73.            
  74.           }

  75.           if(KeyScan()==0)
  76.           {
  77.           GPIO_SHOW=0x00;
  78.           KeyValue=-1;
  79.           break;
  80.           }
  81.          
  82.           else if(KeyScan()==12)
  83.           {
  84.          
  85.            GPIO_DIG=change[12];
  86.            KeyValue=-1;
  87.            Rejudge();
  88.            while(1)
  89.            {
  90.                    Two();
  91.                 if(KeyScan()==8)
  92.                 {
  93.                         KeyValue=12;        
  94.                     RES();
  95.                         First[0]=16;
  96.                         First[1]=16;
  97.                         First[2]=16;
  98.                         First[3]=16;
  99.                         KeyValue=8;
  100.                     break;
  101.                 }
  102.         
  103.            }
  104.          
  105.            }
  106.                         

  107.           else if(KeyScan()==13)
  108.           {
  109.            GPIO_DIG=change[13];
  110.            KeyValue=-1;
  111.            Rejudge();
  112.            while(1)
  113.            {
  114.                    Two();

  115.                 if(KeyScan()==8)
  116.                 {
  117.                     KeyValue=13;        
  118.                     RES();
  119.                         First[0]=16;
  120.                         First[1]=16;
  121.                         First[2]=16;
  122.                         First[3]=16;
  123.                         KeyValue=8;
  124.                     break;
  125.                 }
  126.            }
  127.           }

  128.           else if(KeyScan()==14)
  129.           {
  130.            GPIO_DIG=change[14];
  131.            KeyValue=-1;
  132.            Rejudge();
  133.            while(1)
  134.            {
  135.             Two();
  136.             if(KeyScan()==8)
  137.                 {
  138.                     KeyValue=14;        
  139.                     RES();
  140.                         First[0]=16;
  141.                         First[1]=16;
  142.                         First[2]=16;
  143.                         First[3]=16;
  144.                         KeyValue=8;
  145.                     break;
  146.             }
  147.            }
  148.            
  149.           }

  150.           else if(KeyScan()==15)
  151.           {
  152.            GPIO_DIG=change[15];
  153.            KeyValue=-1;
  154.            Rejudge();
  155.            while(1)
  156.            {
  157.                    Two();
  158.                 if(KeyScan()==8)
  159.                 {
  160.                     KeyValue=15;        
  161.                     RES();
  162.                         First[0]=16;
  163.                         First[1]=16;
  164.                         First[2]=16;
  165.                         First[3]=16;
  166.                         KeyValue=8;
  167.                     break;
  168.                 }
  169.            }
  170.          
  171.           }
  172.         }
  173.         }
  174. }


  175. void One ()
  176. {
  177.     unsigned char j;
  178.         unsigned char i;
  179.         for(i=0;i<4;i++)
  180.         {
  181.                  switch(i)
  182.                 {
  183.             case(0):
  184.                         LSA=0;LSB=0;LSC=1;        
  185.                         break;//显示第4位
  186.                 case(1):
  187.                         LSA=1;LSB=0;LSC=1;
  188.                     break;//显示第5位
  189.                 case(2):
  190.                         LSA=0;LSB=1;LSC=1;
  191.                         break;//显示第6位
  192.                 case(3):
  193.                         LSA=1;LSB=1;LSC=1;
  194.                         break;//显示第7位
  195.                 }
  196.                 GPIO_SHOW=change[First[i]];
  197.                 j=10;                                                 //扫描间隔时间设定
  198.                 while(j--);        
  199.                 GPIO_SHOW=0x00;//消隐
  200.         }
  201. }

  202. void judge()
  203. {
  204.         unsigned int i;
  205.         for(i=0;i<4;i++)
  206.         {
  207.                 do
  208.                 {
  209.                         KeyScan();
  210.                         First[i]=KeyScan();
  211.                 }while(KeyValue==-1);
  212.                 KeyValue=-1;
  213.       
  214.         
  215.         }
  216.         m = 1000*changenumber[First[0]]+100*changenumber[First[1]]+10*changenumber[First[2]]+changenumber[First[3]]; //;m为被X数
  217. }

  218. void Two()
  219. {
  220.     unsigned char j;
  221.         unsigned char i;

  222.         for(i=0;i<4;i++)
  223.         {
  224.                  switch(i)
  225.                 {
  226.             case(0):
  227.                         LSA=0;LSB=0;LSC=1;        
  228.                         break;//显示第4位
  229.                 case(1):
  230.                         LSA=1;LSB=0;LSC=1;
  231.                     break;//显示第5位
  232.                 case(2):
  233.                         LSA=0;LSB=1;LSC=1;
  234.                         break;//显示第6位
  235.                 case(3):
  236.                         LSA=1;LSB=1;LSC=1;
  237.                         break;//显示第7位
  238.                 }
  239.                 GPIO_SHOW=change[Second[i]];
  240.                 j=10;                                                 //扫描间隔时间设定
  241.                 while(j--);        
  242.                 GPIO_SHOW=0x00;//消隐
  243.         }
  244. }

  245. void Rejudge()
  246. {
  247.     unsigned int i;
  248.         for(i=0;i<4;i++)
  249.         {
  250.                 do
  251.                 {
  252.                         KeyScan();
  253.                         Second[i]=KeyScan();
  254.                 }while(KeyValue==-1);
  255.                 KeyValue=-1;
  256.       
  257.         
  258.         }
  259.         n = 1000*changenumber[Second[0]]+100*changenumber[Second[1]]+10*changenumber[Second[2]]+changenumber[Second[3]]; //;n为X数        
  260. }

  261. void RES()
  262. {
  263.         if(KeyValue==12)
  264.                 {
  265.                 result=m+n;
  266.             caculate();
  267.                 }
  268.                 else if(KeyValue==13)
  269.                 {
  270.                 result=m-n;
  271.                 caculate();
  272.                 }
  273.                 else if(KeyValue==14)
  274.                 {
  275.                 result=m*n;
  276.                 caculate();
  277.                 }
  278.                 else if(KeyValue==15)
  279.                 {
  280.                 result=m/n;
  281.                 caculate();
  282.                 }
  283.         

  284. }

  285. void caculate()
  286. {
  287. //    unsigned int i;
  288. //        for(i=0;i<8;i++)
  289. //        {
  290. //                value[i]=(result%(int)(pow(10,(8-i))))/((int)pow(10,(7-i)));
  291. //        }

  292.     value[0]=result/10000000;
  293.         value[1]=(result%10000000)/1000000;
  294.         value[2]=(result%1000000)/100000;
  295.         value[3]=(result%100000)/10000;
  296.         value[4]=(result%10000)/1000;
  297.         value[5]=(result%1000)/100;
  298.         value[6]=(result%100)/10;
  299.         value[7]=(result%10);
  300.         
  301. }

  302. void xianshi()
  303. {
  304.     unsigned char j;
  305.         unsigned char i;
  306.         for(i=0;i<8;i++)
  307.         {
  308.                  switch(i)
  309.                 {
  310.         case(0):
  311.             LSA=0;LSB=0;LSC=0; break;//显示第0位
  312.                 case(1):
  313.                         LSA=1;LSB=0;LSC=0; break;//显示第1位
  314.                 case(2):
  315.                         LSA=0;LSB=1;LSC=0; break;//显示第2位
  316.                 case(3):
  317.                         LSA=1;LSB=1;LSC=0; break;//显示第3位
  318.                 case(4):
  319.                         LSA=0;LSB=0;LSC=1; break;//显示第4位
  320.                 case(5):
  321.                         LSA=1;LSB=0;LSC=1; break;//显示第5位
  322.                 case(6):
  323.                         LSA=0;LSB=1;LSC=1; break;//显示第6位
  324.                 case(7):
  325.                         LSA=1;LSB=1;LSC=1; break;//显示第7位        
  326.                 }
  327.                 GPIO_SHOW=DIG_CODE[value[i]];
  328.                 j=10;                                                 //扫描间隔时间设定
  329.                 while(j--);        
  330.                 GPIO_SHOW=0x00;//消隐
  331.         }
  332.         
  333. }

  334. int KeyScan(void)          //测试行(row)的时候就是线是竖着的的那一列为1,测试列(col)的时候就是线是横着的那几行为1
  335. {
  336.         char a = 0;
  337.         GPIO_KEY=0x0f;
  338.         if(GPIO_KEY!=0x0f)//读取按键是否按下
  339.         {
  340.                 Delay10ms(1);//延时10ms进行消抖
  341.                 if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
  342.                 {
  343.                         //测试列
  344.                         GPIO_KEY=0X0F;
  345.                         switch(GPIO_KEY)
  346.                         {
  347.                                 case(0X07):        KeyValue=0;break;
  348.                                 case(0X0b):        KeyValue=4;break;
  349.                                 case(0X0d): KeyValue=8;break;
  350.                                 case(0X0e):        KeyValue=12;break;
  351.                         }
  352.                         //测试行
  353.                         GPIO_KEY=0XF0;
  354.                         switch(GPIO_KEY)
  355.                         {
  356.                                 case(0X70):        KeyValue=KeyValue+3;break;
  357.                                 case(0Xb0):        KeyValue=KeyValue+2;break;
  358.                                 case(0Xd0): KeyValue=KeyValue+1;break;
  359.                                 case(0Xe0):        KeyValue=KeyValue;break;
  360.                         }
  361.                         while((a<50) && (GPIO_KEY!=0xf0))         //检测按键松手检测
  362.                         {
  363.                                 Delay10ms(1);
  364.                                 a++;
  365.                         }
  366.                         
  367.                 }
  368.         }

  369.         return KeyValue;//这一步的return值很重要,需要等KeyValue值准确的出来后,才能返回,不用return的话就是一个中途的KeyValue值(刚行扫描完就赋值给数组)。
  370.         
  371. }



  372. void Delay10ms(unsigned int c)   //误差 0us
  373. {
  374.     unsigned char a, b;

  375.         //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
  376.     for (;c>0;c--)
  377.         {
  378.                 for (b=38;b>0;b--)
  379.                 {
  380.                         for (a=130;a>0;a--);
  381.                 }         
  382.         }      
  383. }
复制代码

0.png

全部资料51hei下载地址:
protues版.rar (73.05 KB, 下载次数: 38)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1 发表于 2018-7-23 02:20 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:372961 发表于 2018-7-23 03:19 来自手机 | 显示全部楼层
admin 发表于 2018-7-23 02:20
好资料,51黑有你更精彩!!!

哈哈,是51黑让我变得更优秀。所以,我也要呈现自己满意的,学习过程中的项目给51黑。
回复

使用道具 举报

ID:538077 发表于 2019-5-14 16:25 | 显示全部楼层
兄弟 怎么接线的能发一下吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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