找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7194|回复: 4
收起左侧

Lcd1602计算器设计(薄膜键盘,连续计算)附单片机源码

[复制链接]
ID:243507 发表于 2017-11-22 00:10 | 显示全部楼层 |阅读模式
利用STC89C52RC单片机,LCD屏,薄膜式矩阵键盘,制作的计算器,可以连续计算,等号左边的式子在第一行,等号右边结果在第二行,清楚明了。
IMG_20170828_201502_HDR.jpg

单片机源程序如下:
  1. #include <reg51.h>
  2. #include <math.h>
  3. #include <lcd.h>

  4. #define GPIO_KEY P1//薄膜按键所用I/O口,P1^0~P1^7

  5. unsigned char KeyValue=13;//矩阵键盘按键默认值
  6. unsigned int error=0;//非法运算标志
  7. unsigned int bei=0;//标志变量,若被加(减、乘、除)数未输入,则bei为0
  8. unsigned char x=0;//储存运算符
  9. unsigned int xf=0;//标志变量,若运算符刚被输入,则置为1
  10. unsigned char dan;//储存刚输入的单个数位上的字符型数字
  11. unsigned int y=0;//标志变量,若要输出运算结果则置为1
  12. unsigned char e[9]=" Error!!!";

  13. void LcdDisplay_1(long number);//用于在第一行输出被加减乘除数
  14. void LcdDisplay_2(long number);//用于在第二行输出结果
  15. void Delay_ms(unsigned int ms);
  16. //void UsartConfiguration();

  17. void main()
  18. {
  19. //        UsartConfiguration();
  20.         LcdInit();                         //初始化LCD1602
  21.         while(1)
  22.            {
  23.             static long key=0,result=0,temp=0,a=0,b=0,c=0,d=0;//设置静态局部变量,可保留上一次运算的值
  24.             unsigned char i=0;

  25.             GPIO_KEY=0x0f;
  26.             if(GPIO_KEY!=0x0f)//读取按键是否按下
  27.                 {
  28.                         Delay_ms(10);//延时消抖
  29.                         if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
  30.                         {                       
  31.                                 //测试列
  32.                                 GPIO_KEY=0X0f;
  33.                                 switch(GPIO_KEY)
  34.                                 {
  35.                                         case(0X07):        KeyValue=0;break;
  36.                                         case(0X0b):        KeyValue=1;break;
  37.                                         case(0X0d): KeyValue=2;break;
  38.                                         case(0X0e):        KeyValue=3;break;
  39.                                 }
  40.                                 //测试行
  41.                                 GPIO_KEY=0Xf0;
  42.                                 switch(GPIO_KEY)
  43.                                 {
  44.                                         case(0X70):        KeyValue=KeyValue+0;break;
  45.                                         case(0Xb0):        KeyValue=KeyValue+4;break;
  46.                                         case(0Xd0): KeyValue=KeyValue+8;break;
  47.                                         case(0Xe0):        KeyValue=KeyValue+12;break;
  48.                                 }
  49.                                 while((i<60)&&(GPIO_KEY!=0xf0))         //松手检测
  50.                                 {
  51.                                         Delay_ms(10);
  52.                                         i++;
  53.                                 }

  54.                                 switch (KeyValue)
  55.                                 {
  56.                                         //key计算最新键入的值,用temp存放被加(减、乘、除)数,result存放最新键入的值或计算结果
  57.                                         case  0:dan='1';key=key*10+1;result=key;break;//键入1,dan储存刚输入的单个数位上的数字
  58.                                            case  1:dan='2';key=key*10+2;result=key;break;//键入2
  59.                                          case  2:dan='3';key=key*10+3;result=key;break;//键入3
  60.                                         case  3:x='+';xf=1;temp=result;key=0;a=1;break;      //选择加法,x储存选择的运算符,选择后xf置为1
  61.                                         case  4:dan='4';key=key*10+4;result=key;break;//键入4
  62.                                          case  5:dan='5';key=key*10+5;result=key;break;//键入5
  63.                                         case  6:dan='6';key=key*10+6;result=key;break;//键入6
  64.                                         case  7:x='-';xf=1;temp=result;key=0;b=1;break;          //选择减法,
  65.                                         case  8:dan='7';key=key*10+7;result=key;break;//键入7
  66.                                         case  9:dan='8';key=key*10+8;result=key;break;//键入8
  67.                                         case 10:dan='9';key=key*10+9;result=key;break;//键入9
  68.                                         case 11:x='*';xf=1;temp=result;key=0;c=1;break;          //选择乘法
  69.                                         case 12:temp=key=result=0;a=b=c=d=0;x=dan=0;xf=y=bei=0;break;//所有清零
  70.                                         case 13:dan='0';key=key*10+0;result=key;break;//键入0
  71.                                         case 14:if(a==1) {result=temp+result;a=0;key=0;}          //计算运算结果
  72.                                                         if(b==1) {result=temp-result;b=0;key=0;}
  73.                                                         if(c==1) {result=temp*result;c=0;key=0;}
  74.                                                         if(d==1)
  75.                                                         {
  76.                                                                 if (result==0)         //若除数为0,运算非法,error置为1
  77.                                                                         {error=1;result=0;d=0;key=0;}
  78.                                                                 else
  79.                                                                         {result=temp/result;d=0;key=0;}                               
  80.                                                         }
  81.                                                         y=1;                                //将要输出运算结果,则y置为1
  82.                                                         break;
  83.                                         case 15:x='/';xf=1;temp=result;key=0;d=1;break;           //选择除法
  84.                                 }

  85.                                 //LCD显示
  86.                                  if (y==0)//若y为0,则不是输出结果,而是输出等式的左边       
  87.                                 {
  88.                                         if (KeyValue==12) LcdWriteCom(0x01);//清零则清屏
  89.                                         else if(x==0&&bei==0) bei=1,LcdWriteCom(0x01),LcdWriteData(dan);//若x和bei都为0,则当前正开始输入被加(减、乘、除)数,要清屏再输出,同时bei置为1
  90.                                          else if(x==0&&bei==1) LcdWriteData(dan);//若x为0,bei为1,则运算符未选择,即当前仍然在输入被加(减、乘、除)数,继续逐位输出显示
  91.                                         else if(x!=0&&xf==1) xf=0,bei=0,LcdWriteCom(0x01),LcdDisplay_1(result),LcdWriteData(x);//若x和xf都不为0,则为刚选择运算符,将运算符输出且xf重新置为0,此时被加(减、乘、除)数已输完,bei也要重新置为0
  92.                                         else if(x!=0&&xf==0) LcdWriteData(dan);//若运算符已选但不是刚选,则当前正输入加(减、乘、除)数,逐位输出显示
  93.                                 }
  94.                                 else         //否则输出结果
  95.                                 {
  96.                                         LcdDisplay_2(result);        //输出结果
  97.                                         x=0;                                        //运算符已选,重新置为0
  98.                                         y=0;                                        //输出结果后,重新置为0
  99.                                 }       
  100.                         }
  101.                 }
  102.         }
  103. }

  104. void LcdDisplay_1(long number)//在第一行输出被加(减、乘、除)数
  105. {
  106.         int i,n[5]={0};                          //不能设成unsigned
  107.         if (number<0)
  108.                 LcdWriteData('-');
  109.         number=abs(number);                  //取绝对值
  110.         if (number-10000>=0) i=5; //判断有效位数
  111.         else if (number-1000>=0) i=4;
  112.         else if (number-100>=0) i=3;
  113.         else if (number-10>=0) i=2;
  114.         else i=1;                       
  115.         n[4]=number/ 10000;                  //提取各位上的数
  116.         n[3]=number % 10000 / 1000;
  117.         n[2]=number % 1000 / 100;
  118.         n[1]=number % 100 / 10;
  119.         n[0]=number % 10;
  120.         for (i=i-1;i>=0;i--)          //若设成unsigned,此处形成死循环!!!
  121.         {
  122.                 LcdWriteData(n[i]+48);//输出
  123.         }
  124. }

  125. void LcdDisplay_2(long number)//在第二行输出结果
  126. {
  127.         int i,n[5];                                //不能设成unsigned
  128.         //判断运算是否合法
  129.         if (error==1)                        //若error为1,则运算非法
  130.         {
  131.                 error=0;                        //error重新置为0
  132.                 LcdWriteCom(0x01);  //清屏
  133.                 LcdWriteCom(0x80);  //数据指针返回首位
  134.                 for (i=0;i<9;i++)        //输出提示
  135.                         LcdWriteData(e[i]);
  136.                 Delay_ms(1500);
  137.                 LcdWriteCom(0x01);  //再次清屏
  138.         }
  139.         else                                        //合法则输出结果
  140.         {
  141.                  LcdWriteData('=');        //先在第一行输出'='
  142.                  LcdWriteCom(0xc0);        //数据指针设置在第二行首位
  143.                  if (number<0)                //负数则输出负号
  144.                          LcdWriteData('-');
  145.                  number=abs(number);
  146.                  if (number-10000>=0) i=5; //判断有效位数
  147.                  else if (number-1000>=0) i=4;
  148.                  else if (number-100>=0) i=3;
  149.                  else if (number-10>=0) i=2;
  150.                  else i=1;                       
  151.                  n[4]=number/10000;
  152.                  n[3]=number%10000/1000;
  153.                  n[2]=number%1000/100;
  154.                  n[1]=number%100/10;
  155.                  n[0]=number%10;
  156.                  for (i=i-1;i>=0;i--)           //若设成unsigned,此处形成死循环!!!
  157.                  {
  158.                         LcdWriteData(n[i]+48);
  159.                  }
  160.         }
  161. /*
  162.         SBUF = '0'+m;        //将接收到的数据放入到发送寄存器
  163.         while (!TI);        //等待发送数据完成
  164.         TI = 0;                        //发送完成标志位清零
  165. */
  166. }

  167. void Delay_ms(unsigned int ms)//延时函数,延时1ms
  168. {
  169.         int j;
  170.         for(;ms>0;ms--)
  171.           for(j=140;j>0;j--);
  172. }

  173. /*        //此函数适合数码管显示时使用
  174. unsigned int num(long num,unsigned int p)//提取各位上的数
  175. {
  176.     unsigned int i,t,n;
  177.     for(t=1,i=0;i<p;i++)
  178.         {
  179. ……………………

  180. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
0.png

所有资料51hei提供下载:
Lcd计算器(Lcd适应版,薄膜键盘).zip (48.97 KB, 下载次数: 166)

评分

参与人数 2黑币 +59 收起 理由
阳光的360zz + 9 很给力!成功试验
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:425307 发表于 2018-11-12 21:38 | 显示全部楼层
正好需要 谢谢楼主开源
回复

使用道具 举报

ID:594206 发表于 2019-8-2 16:40 | 显示全部楼层
正好需要 谢谢
回复

使用道具 举报

ID:633321 发表于 2019-12-5 15:15 | 显示全部楼层
很受用,感谢
回复

使用道具 举报

ID:787061 发表于 2020-6-22 22:42 | 显示全部楼层
很好 还不错
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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