找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机课程设计 简易计算器仿真图+代码(含注释)

[复制链接]
跳转到指定楼层
楼主
仅供参考,需要的自取。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. ///////////////////////////////////////////////////
  2. //功能 0 1 2 3 4 5 6 7 8 9 + - × ÷ = 清零  表3-1  3.2 计算器的软件设计
  3. #include<reg51.h>   //头文件
  4. #define uint unsigned int //  
  5. #define uchar unsigned char   
  6. sbit lcden=P2^3; //定义引脚
  7. sbit rs=P2^4;
  8. sbit rw=P2^0;
  9. sbit busy=P0^7;
  10. char i,j,temp,num,num_1;
  11. long a,b,c;     //a,第一个数 b,第二个数 c,得数
  12. float a_c,b_c;
  13. uchar flag,fuhao;//flag表示是否有符号键按下,fuhao表征按下的是哪个符号  
  14. uchar code table[]={ 7,8,9,0, 4,5,6,0, 1,2,3,0, 0,0,0,0};
  15. uchar code table1[]={
  16. ///////////////////////////////////////////////////
  17. 7,8,9,0x2f-0x30,
  18. 4,5,6,0x2a-0x30,
  19. 1,2,3,0x2d-0x30,
  20.   0x01-0x30,0,0x3d-0x30,0x2b-0x30};  
  21. void delay(uchar z) // 延迟函数
  22. {
  23. uchar y;
  24. for(z;z>0;z--)
  25.      for(y=0;y<110;y++);
  26. }   void check() // 判断忙或空闲
  27. {
  28. do{
  29.      P0=0xFF;
  30.      rs=0;     //指令
  31.      rw=1;     //读
  32.       lcden=0;     //禁止读写
  33.       delay(1); //等待,液晶显示器处理数据
  34.      lcden=1;     //允许读写
  35.       }while(busy==1); //判断是否为空闲,1为忙,0为空闲
  36. }  
  37. void write_com(uchar com) // 写指令函数  
  38. ///////////////////////////////////////////////////
  39. {
  40.   P0=com;    //com指令付给P0口
  41. rs=0;
  42. rw=0;
  43. lcden=0;
  44. check();
  45. lcden=1;
  46. }   
  47. void write_date(uchar date) // 写数据函数
  48. {
  49.      P0=date;
  50. rs=1;
  51. rw=0;
  52. lcden=0;
  53. check();
  54. lcden=1;
  55. }   
  56. void init() //初始化
  57. {
  58.      num=-1;
  59.   lcden=1; //使能信号为高电平
  60. write_com(0x38); //8位,2行
  61. ///////////////////////////////////////////////////
  62. write_com(0x0c); //显示开,光标关,不闪烁*/
  63. write_com(0x06); //增量方式不移位 显竟獗暌贫 柚?
  64. write_com(0x80); //检测忙信号
  65.   write_com(0x01); //显示开,光标关,不闪烁
  66. num_1=0;
  67. i=0;
  68. j=0;
  69.   a=0;     //第一个参与运算的数
  70. b=0;     //第二个参与运算的数
  71. c=0;
  72.   flag=0; //flag表示是否有符号键按下,
  73.   fuhao=0; // fuhao表征按下的是哪个符号
  74. }
  75.   void keyscan() // 键盘扫描程序
  76. {
  77.    P3=0xfe;
  78.   if(P3!=0xfe)
  79. {
  80.      delay(20); //延迟20ms
  81.     if(P3!=0xfe)
  82.     {
  83.      temp=P3&0xf0;
  84.      switch(temp)
  85. ///////////////////////////////////////////////////
  86.     {
  87.       case 0xe0:num=0;
  88.         break;
  89.        case 0xd0:num=1;
  90.         break;
  91.        case 0xb0:num=2;
  92.         break;
  93.       case 0x70:num=3;
  94.         break;
  95.      }
  96.    }
  97.      while(P3!=0xfe);
  98.      if(num==0||num==1||num==2)//如果按下的是'7','8'或'9
  99.    {
  100.         if(j!=0)
  101.          {
  102.              write_com(0x01);
  103.           j=0;
  104.           }
  105.         if(flag==0)//没有按过符号键
  106.      {
  107.        a=a*10+table[num];
  108.      }
  109.       else//如果按过符号键
  110. ///////////////////////////////////////////////////
  111.     {
  112.       b=b*10+table[num];
  113.      }
  114.     }
  115.      else//如果按下的是'/'
  116.    {
  117.      flag=1;
  118.      fuhao=4;//4表示除号已按
  119.    }
  120.      i=table1[num];
  121.    write_date(0x30+i);
  122. }
  123.   P3=0xfd;
  124. if(P3!=0xfd)
  125. {
  126.      delay(5);
  127.     if(P3!=0xfd)
  128.     {
  129.       temp=P3&0xf0;
  130.      switch(temp)
  131.      {
  132.       case 0xe0:num=4;
  133.          break;
  134. ///////////////////////////////////////////////////
  135.      case 0xd0:num=5;
  136.           break;
  137.               case 0xb0:num=6;
  138.           break;
  139.               case 0x70:num=7;
  140.           break;
  141.      }
  142.     }
  143.      while(P3!=0xfd);
  144.      if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
  145.     {
  146.       if(j!=0)
  147.          {
  148.             write_com(0x01);
  149.           j=0;
  150.           }
  151.          if(flag==0)//没有按过符号键
  152.      {
  153.       a=a*10+table[num];
  154.       }
  155.       else//如果按过符号键
  156. ///////////////////////////////////////////////////
  157.     {
  158.        b=b*10+table[num];
  159.      }
  160.    }
  161.      else//如果按下的是'/'
  162.     {
  163.      flag=1;
  164.      fuhao=3;//3表示乘号已按
  165.     }
  166.      i=table1[num];
  167.     write_date(0x30+i);
  168. }
  169.   P3=0xfb; if(P3!=0xfb)
  170. {
  171.      delay(5);
  172.     if(P3!=0xfb)
  173.     {
  174.       temp=P3&0xf0;
  175.      switch(temp)
  176.      {
  177.       case 0xe0:num=8;
  178.          break;
  179. ///////////////////////////////////////////////////
  180.      case 0xd0:num=9;
  181.          break;
  182.              case 0xb0:num=10;
  183.           break;
  184.               case 0x70:num=11;
  185.           break;
  186.      }
  187.     }
  188.     while(P3!=0xfb);
  189.     if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
  190.    {
  191.       if(j!=0)
  192.          {
  193.              write_com(0x01);
  194.            j=0;
  195.           }
  196.        if(flag==0)//没有按过符号键
  197.      {
  198.        a=a*10+table[num];
  199.       }
  200.      else//如果按过符号键
  201. ///////////////////////////////////////////////////
  202.     {
  203.        b=b*10+table[num];
  204.       }
  205.     }
  206.      else if(num==11)//如果按下的是'-'
  207.     {
  208.      flag=1;
  209.       fuhao=2;//2表示减号已按
  210.     }
  211.      i=table1[num];
  212.     write_date(0x30+i);
  213. }
  214.   P3=0xf7;
  215.   if(P3!=0xf7)
  216. {
  217.      delay(5);
  218.     if(P3!=0xf7)
  219.     {
  220.       temp=P3&0xf0;
  221.      switch(temp)
  222.      {
  223.        case 0xe0:num=12;
  224.           break;
  225. ///////////////////////////////////////////////////
  226.               case 0xd0:num=13;
  227.           break;
  228.              case 0xb0:num=14;
  229.           break;
  230.               case 0x70:num=15;
  231.           break;
  232.      }
  233.     }
  234.     while(P3!=0xf7);
  235.     switch(num)
  236.     {
  237.       case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
  238.       break;
  239.       case 13:{                //按下的是"0"
  240.         if(flag==0)          //没有按过符号键
  241.         {
  242.          a=a*10;
  243.         write_date(0x30);
  244.          P1=0;
  245.         }
  246.         else if(flag==1)//如果按过符号键  
  247. ///////////////////////////////////////////////////
  248.        {
  249.          b=b*10;
  250.          write_date(0x30);
  251.          }
  252.        }
  253.       break;
  254.      case 14:{j=1;
  255.             if(fuhao==1){write_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处
  256.             write_com(0x04);     //设置从后住前写数据,每写完一个数据,光标后退一格
  257.             c=a+b;
  258.             while(c!=0)
  259.             {
  260.                 write_date(0x30+c%10);
  261.               c=c/10;
  262.             }
  263.               write_date(0x3d);     //再写"="
  264.             a=0;b=0;flag=0;fuhao=0;
  265.             }
  266.         else if(fuhao==2){write_com(0x80+0x4f);   //光标前进至第二行最后一个显示处
  267.              write_com(0x04);     //设置从后住前写数据,每写完一个数据,光标后退一格
  268.                                            //(这个照理说顺序不对,可显示和上段一样)
  269.             if(a-b>0)
  270.              c=a-b;
  271. ///////////////////////////////////////////////////
  272.          else
  273.                c=b-a;
  274.             while(c!=0)
  275.             {
  276.                 write_date(0x30+c%10);
  277.               c=c/10;
  278.             }
  279.              if(a-b<0)
  280.                write_date(0x2d);
  281.              write_date(0x3d);     //再写"="
  282.                       a=0;b=0;flag=0;fuhao=0;
  283.           }
  284.        else if(fuhao==3){write_com(0x80+0x4f);
  285.             write_com(0x04);
  286.               c=a*b;
  287.              while(c!=0)
  288.               {
  289.                write_date(0x30+c%10);
  290.              c=c/10;
  291.               }
  292.                write_date(0x3d);
  293.                 a=0;b=0;flag=0;fuhao=0;
  294.               }
  295.        else if(fuhao==4){write_com(0x80+0x4f);
  296. ///////////////////////////////////////////////////
  297.             write_com(0x04);
  298.              i=0;
  299.               c=(long)(((float)a/b)*1000);
  300.              while(c!=0)
  301.              {
  302.                  write_date(0x30+c%10);
  303.                 c=c/10;
  304.             i++;
  305.            if(i==3)
  306.                 write_date(0x2e);
  307.               }
  308.              if(a/b<=0)
  309.               write_date(0x30);
  310.               write_date(0x3d);
  311.                                           a=0;b=0;flag=0;fuhao=0;
  312.                      }
  313.       }
  314.       break;
  315.        case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;}
  316.      break;
  317.     }
  318. }
  319. }

  320. ///////////////////////////////////////////////////
  321. main()
  322. {
  323. init();
  324. while(1)
  325. {
  326.      keyscan();
  327. }
  328. }
复制代码

所有资料51hei提供下载:
计算器2.zip (23.68 KB, 下载次数: 100)


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

使用道具 举报

沙发
ID:91165 发表于 2018-11-20 14:47 | 只看该作者
不错,学习了,谢谢楼主分享
回复

使用道具 举报

板凳
ID:439189 发表于 2018-12-4 14:40 | 只看该作者
很有用 谢谢楼主
回复

使用道具 举报

地板
ID:448302 发表于 2018-12-18 20:16 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

5#
ID:449493 发表于 2018-12-19 00:57 来自手机 | 只看该作者
最近正在做这个,谢谢楼主
回复

使用道具 举报

6#
ID:553652 发表于 2019-6-9 16:39 来自手机 | 只看该作者
运行不了,说源程序出错,,,
回复

使用道具 举报

7#
ID:584445 发表于 2019-7-15 15:01 | 只看该作者
正要用这个 ,谢谢楼主
回复

使用道具 举报

8#
ID:587714 发表于 2019-8-4 21:05 | 只看该作者
wer12 发表于 2019-6-9 16:39
运行不了,说源程序出错,,,

#include<reg52.h> ?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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