找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2383|回复: 2
打印 上一主题 下一主题
收起左侧

基于51单片机的计算器 小数点不知道该怎么写程序 求帮助

[复制链接]
跳转到指定楼层
楼主
20黑币
设计一个矩阵键盘5*5的计算器,要求有括号的优先级。还有小数点。。写到小数点就不知道该怎么写。。请各帮帮忙。
  1. #include<reg52.h>
  2. #include<math.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. sbit rs = P2^0;
  6. sbit rw = P2^1;
  7. sbit lcden = P2^2;


  8. uchar code anjian[]={    //键盘值
  9.         'A','(',')','B','C',
  10.         '7','8','9','/','D',
  11.         '4','5','6','*','E',
  12.         '1','2','3','-','F',
  13.         'G','0','.','+','='
  14. };

  15. uchar code shuzhi[]={
  16.         '0','1','2','3','4',
  17.         '5','6','7','8','9'
  18. };


  19. double num[20];                                        //储存数值
  20. double value;                                                //储存结果
  21. char flag;                                                //运算符判断
  22. uchar KeyValue = 30;        //按键值


  23. void delay(uint z) //毫秒级延时
  24. {
  25.         uint x,y;
  26.         for(x=z;x>0;x--)
  27.                 for(y=114;y>0;y--);
  28. }


  29. /*********************** 定时器0初始化 ***********************/
  30. //void Init_timer0()
  31. //{
  32. //        EA = 1;
  33. //        ET0 = 1;
  34. //        TR0 = 1;
  35. //        TMOD = 0x01;
  36. //        TH0 = 0xED;                //定时5ms
  37. //        TL0 = 0xFF;
  38. //}

  39. /*********************** 5*5矩阵键盘 ***********************/
  40. void KeyScan()
  41. {
  42.         P3 = 0xFF;  //列扫描
  43.         P1 = 0;
  44.         while(KeyValue == 30)
  45.         {
  46.                 if(P3 != 0xFF)
  47.                 {
  48.                         delay(10);
  49.                         if(P3 != 0xFF)
  50.                         {
  51.                                 switch(P3)
  52.                                 {
  53.                                         case 0xFE: KeyValue=0; break;
  54.                                         case 0xFD: KeyValue=1; break;
  55.                                         case 0xFB: KeyValue=2; break;
  56.                                         case 0xF7: KeyValue=3; break;
  57.                                         case 0xEF: KeyValue=4; break;
  58.                                 }
  59.                                 P1 = 0xFF;  //行扫描
  60.                                 P3 = 0;
  61.                                 switch(P1)
  62.                                 {
  63.                                         case 0xF7: KeyValue=KeyValue; break;
  64.                                         case 0xEF: KeyValue=KeyValue+5; break;
  65.                                         case 0xDF: KeyValue=KeyValue+10; break;
  66.                                         case 0xBF: KeyValue=KeyValue+15; break;
  67.                                         case 0x7F: KeyValue=KeyValue+20; break;               
  68.                                 }
  69.                                 while(P1 != 0xFF);  //松手检测
  70.                         }
  71.                 }
  72.         }
  73. }


  74. /*********************** LCD1602 ***********************/
  75. void Read_Busy() //判忙函数
  76. {
  77.         uchar busy;
  78.         P0 = 0xFF;
  79.         rs = 0;
  80.         rw = 1;
  81.         do
  82.         {
  83.                 lcden = 1;
  84.                 busy         = P0;
  85.                 lcden = 0;
  86.         }while(busy & 0x80);
  87. }

  88. void Write_Cmd(uchar cmd) //写指令
  89. {
  90.         Read_Busy();
  91.         rs = 0;
  92.         rw = 0;
  93.         P0 = cmd;
  94.         lcden = 1;
  95.         lcden = 0;
  96. }

  97. void Write_Dat(uchar dat) //写数据
  98. {
  99.         Read_Busy();
  100.         rs = 1;
  101.         rw = 0;
  102.         P0 = dat;
  103.         lcden = 1;
  104.         lcden = 0;
  105.         
  106.         KeyValue = 30; //清按键值
  107. }

  108. void Init_lcd() //lcd初始化
  109. {
  110.         Write_Cmd(0x38); //16*2显示
  111.         Write_Cmd(0x0C); //开显示
  112.         Write_Cmd(0x01); //清屏
  113.         Write_Cmd(0x06); //读写一字节后,地址指针加1
  114. }


  115. /*********************** 获取数值 ***********************/
  116. void GetNum(int x)
  117. {
  118.         num[x] = anjian[KeyValue] - 48;
  119.         Write_Dat(anjian[KeyValue]);
  120.         KeyScan();
  121.         while(48 <= anjian[KeyValue] && anjian[KeyValue] <= 57)
  122.         {
  123.                 num[x] = num[x] * 10 + (anjian[KeyValue] - 48);
  124.                 Write_Dat(anjian[KeyValue]);
  125.                 KeyScan();
  126.         }
  127. }


  128. /*********************** 运算符号 ***********************/
  129. void GetFlag()
  130. {
  131.         switch(anjian[KeyValue])
  132.         {
  133.                 case '+':
  134.                         flag = '+';
  135.                         Write_Dat('+'); break;
  136.                 case '-':
  137.                         flag = '-';
  138.                         Write_Dat('-'); break;
  139.                 case '*':
  140.                         flag = '*';
  141.                         Write_Dat('*'); break;
  142.                 case '/':
  143.                         flag = '/';
  144.                         Write_Dat('/'); break;
  145.         }
  146.         KeyScan();
  147.         GetNum(1);
  148. }


  149. /*********************** 计算结果 ***********************/
  150. void calculate()
  151. {
  152.         int ge, shi, bai;
  153.         
  154.         Write_Cmd(0xC0);
  155.         Write_Dat('=');
  156.         
  157.         switch(flag)
  158.         {
  159.                 case '+':
  160.                         value = num[0] + num[1]; break;
  161.                 case '-':
  162.                         value = num[0] - num[1]; break;
  163.                 case '*':
  164.                         value = num[0] * num[1]; break;
  165.                 case '/':
  166.                         value = num[0] / num[1]; break;
  167.         }
  168.         
  169.         if(0 <= fabs(value) && fabs(value) <= 9)                //1位数
  170.         {
  171.                 ge = fabs(value);
  172.                 if(value >= 0)
  173.                         Write_Dat(shuzhi[ge]);
  174.                 else
  175.                 {
  176.                         Write_Dat('-');
  177.                         Write_Dat(shuzhi[ge]);
  178.                 }
  179.         }
  180.         
  181.         if(10 <= fabs(value) && fabs(value) <= 99)        //2位数
  182.         {
  183.                 shi = fabs(value) / 10;
  184.                 ge = (int)fabs(value) % 10;
  185.                 if(value >= 0)
  186.                 {
  187.                         Write_Dat(shuzhi[shi]);
  188.                         Write_Dat(shuzhi[ge]);
  189.                 }
  190.                 else
  191.                 {
  192.                         Write_Dat('-');
  193.                         Write_Dat(shuzhi[shi]);
  194.                         Write_Dat(shuzhi[ge]);
  195.                 }
  196.         }
  197.         
  198.         if(100 <= fabs(value) && fabs(value) <= 999)        //3位数
  199.         {
  200.                 bai = fabs(value) / 100;
  201.                 shi = (int)fabs(value) /10 % 10;
  202.                 ge = (int)fabs(value) % 10;
  203.                 if(value >= 0)
  204.                 {
  205.                         Write_Dat(shuzhi[bai]);
  206.                         Write_Dat(shuzhi[shi]);
  207.                         Write_Dat(shuzhi[ge]);
  208.                 }
  209.                 else
  210.                 {
  211.                         Write_Dat('-');
  212.                         Write_Dat(shuzhi[bai]);
  213.                         Write_Dat(shuzhi[shi]);
  214.                         Write_Dat(shuzhi[ge]);
  215.                 }
  216.         }
  217. }

  218. void main()
  219. {
  220.         //Init_timer0();
  221.         Init_lcd();
  222.         Write_Cmd(0x80); //第一行显示字符
  223.         
  224.         while(1)
  225.         {
  226.                 KeyScan();
  227.                 if(48 <= anjian[KeyValue] && anjian[KeyValue] <= 57) //获取0~9数值
  228.                         GetNum(0);
  229.                
  230.                 if(anjian[KeyValue] == '=')
  231.                         calculate();
  232.                 else
  233.                         GetFlag();
  234.         }
  235. }


  236. /*********************** T0中断函数 ***********************/
  237. //void timer0() interrupt 1
  238. //{
  239. //        TH0 = 0xED;                //定时5ms
  240. //        TL0 = 0xFF;
  241. //        
  242. //        if(anjian[KeyValue] == 'A')
  243. //        {
  244. //                Write_Cmd(0x01); //清屏
  245. //                Write_Cmd(0x80); //第一行显示字符
  246. //                //KeyValue = 0;
  247. //        }
  248. //}
复制代码




捕获.PNG (92.65 KB, 下载次数: 54)

仿真图

仿真图
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:739545 发表于 2020-6-22 17:34 | 只看该作者
按小数点以后,按一个数字就乘以10,然后显示的总数除以10的n次方就是你的小数部分了
回复

使用道具 举报

板凳
ID:739545 发表于 2020-6-22 17:35 | 只看该作者
以小数点为界,后面的数字按n次就是10的n次方,然后用整数做除法就行了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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