找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2572|回复: 1
收起左侧

51单片机计算器+Proteus仿真+PCB文件设计

[复制链接]
ID:262632 发表于 2019-3-20 19:12 | 显示全部楼层 |阅读模式
Altium Designer画的单片机计算器原理图和PCB图如下:(51hei附件中可下载工程文件)
0.png 3.png 0.png

计算器仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<math.h>
  3. #define unchar unsigned char
  4. #define unint unsigned int
  5. #define Pi 3.141596
  6. sbit rs=P2^0;
  7. sbit rw=P2^1;
  8. sbit en=P2^2;
  9. sbit busy=P0^7;
  10. char i,j,flag,fuhao,y,r,z;
  11. char s[30];
  12. unchar num,temp;
  13. long  a,b,c;
  14. unchar code table[]={7,8,9,0,//内部运算用
  15.                                          4,5,6,0,
  16.                                          1,2,3,0,
  17.                                          0,0,0,0,
  18.                                          0,0,0,0,
  19.                                          0,0,0,0,
  20.                                          0,0,0,0};
  21. unchar code table1[]={7,8,9,0x2f-0x30,//显示用7,8,9,/,//后面加了0x30,所以这里减掉
  22.                                           4,5,6,0x2a-0x30,//4,5,6,*
  23.                                           1,2,3,0x2d-0x30,//1,2,3,-
  24.                                         0x01-0x30,0,0x3d-0x30,0x2b-0x30,//ON/C,0,=,+
  25.                                         0x22-0x30,0x5e-0x30,0x25-0x30,0x21-0x30,//"代表根号,^次方,%,!
  26.                                         0x02-0x30,0x03-0x30,0x04-0x30,//2转10,10转2,10转16,16转10
  27.                                         0x05-0x30,0x06-0x30,0x07-0x30,0x08-0x30};//sin,coa,tan,ln
  28.                                        
  29. void delay(unchar z)
  30. {
  31.         unchar x,y;
  32.         for(x=z;x>0;x--)
  33.                 for(y=110;y>0;y--);
  34. }
  35. void checkbusy()
  36. {        
  37.         while(busy==1)//P0^7最高位为1为忙,0为闲
  38.         {        
  39.                 P0=0xff;
  40.                 rs=0;
  41.                 rw=1;
  42.                 en=0;//禁止读写
  43.                 delay(20);               
  44.                 en=1;               
  45.         }
  46. }

  47. void write_com(unchar com)
  48. {
  49.         rs=0;
  50.         rw=0;
  51.         en=0;
  52.         checkbusy();
  53.         P0=com;
  54.         delay(5);
  55.         en=1;
  56.         delay(5);
  57.         en=0;
  58. }
  59. void write_date(unchar date)
  60. {
  61.         rs=1;
  62.         rw=0;
  63.         en=0;
  64.         checkbusy();
  65.         P0=date;
  66.         delay(5);
  67.         en=1;
  68.         delay(5);
  69.         en=0;        
  70. }
  71. void init()
  72. {               
  73.         write_com(0x38);//16*2显示,5*7点阵,8位数据接口
  74.         delay(50);
  75.         write_com(0x0c);//开显示关光标和闪烁
  76.         delay(50);
  77.         write_com(0x06);//地址向后移
  78.         delay(50);
  79.         write_com(0x80);//光标初始地址
  80.         write_com(0x01);//清屏
  81.         delay(50);
  82.         i=0;flag=0;//赋初值flag表示按符号键后的输入值,默认为没按之前的输入
  83.         fuhao=0;a=0;b=0;c=0;
  84.         
  85.         
  86. }
  87. void lcd_clean()//清屏
  88. {
  89.         write_com(0x01);
  90.         delay(20);
  91. }
  92. void keyscan()
  93. {
  94.         //**************P3口的键盘检测
  95.         P3=0xfe;
  96.         temp=P3;
  97.         temp=temp&0xf0;
  98.         if(temp!=0xf0)
  99.                  {                delay(10);
  100.                                 temp=P3;
  101.                                 temp=temp&0xf0;
  102.                                 if(temp!=0xf0)
  103.                                 {
  104.                                         temp=P3;
  105.                                         switch(temp)
  106.                                                 {
  107.                                                         case 0xee:num=0; break;
  108.                                                         case 0xde:num=1; break;
  109.                                                         case 0xbe:num=2; break;
  110.                                                         case 0x7e:num=3; break;                                                                                                        
  111.                                                 }                                                                                                
  112.                                 }
  113.                         while(P3!=0xfe);
  114.                 if(num==0||num==1||num==2)
  115.                  {           
  116.                         if(flag==0)
  117.                                 a=a*10+table[num];//a是在没按符号键之前输入的值
  118.                         if(flag==1)
  119.                                 b=b*10+table[num];//b是按符号键后输入的值               
  120.                  }
  121.                  if(num==3)//"/"除键
  122.                         {        
  123.                                 flag=1;
  124.                                 fuhao=4;//"/"
  125.                         }                                                                                       
  126.                 i=table1[num];//显示的值
  127.                 write_date(0x30+i);//十六进制表示的ASC码               
  128.         }
  129.                 P3=0xfd;
  130.                 temp=P3;
  131.                 temp=temp&0xf0;
  132.                 if(temp!=0xf0)                                
  133.                   {                delay(5);
  134.                                 temp=P3;
  135.                                 temp=temp&0xf0;
  136.                                 if(temp!=0xf0)
  137.                                 {
  138.                                         temp=P3;
  139.                                         switch(temp)
  140.                                                 {
  141.                                                         case 0xed:num=4; break;
  142.                                                         case 0xdd:num=5; break;
  143.                                                         case 0xbd:num=6; break;
  144.                                                         case 0x7d:num=7; break;                                                                                                
  145.                                                 }                                                                                                        
  146.                                 }
  147.                         while(P3!=0xfd);
  148.                         if(num==4||num==5||num==6)
  149.                                 {
  150.                                         if(flag==0)
  151.                                                 a=a*10+table[num];
  152.                                         else
  153.                                                 b=b*10+table[num];
  154.                                 }
  155.                 if(num==7)//"*"乘
  156.                                 {
  157.                                         flag=1;
  158.                                         fuhao=3;
  159.                                 }
  160.                         i=table1[num];
  161.                         write_date(0x30+i);                                 
  162.                   }
  163.                         P3=0xfb;
  164.                         temp=P3;
  165.                         temp=temp&0xf0;
  166.                         if(temp!=0xf0)                                
  167.                           {        delay(5);
  168.                                 temp=P3;
  169.                                 temp=temp&0xf0;
  170.                                 if(temp!=0xf0)
  171.                                 {
  172.                                         temp=P3;
  173.                                         switch(temp)
  174.                                                 {
  175.                                                         case 0xeb:num=8; break;
  176.                                                         case 0xdb:num=9; break;
  177.                                                         case 0xbb:num=10; break;
  178.                                                         case 0x7b:num=11; break;                                                                                                
  179.                                                 }                                                                                       
  180.                                 }
  181.                 while(P3!=0xfb);
  182.                         if(num==8||num==9||num==10)
  183.                           {
  184.                                 if(flag==0)
  185.                                         {a=a*10+table[num];}
  186.                                 else
  187.                                         {b=b*10+table[num];}                                                                                       
  188.                           }
  189.                         if(num==11)//"-"减
  190.                            {
  191.                                 flag=1;
  192.                                 fuhao=2;
  193.                            }
  194.                         
  195.                         i=table1[num];
  196.                         write_date(0x30+i);                                       
  197.                     }
  198.                         P3=0xf7;
  199.                         temp=P3;
  200.                         temp=temp&0xf0;
  201.                         if(temp!=0xf0)                                
  202.                           {        delay(5);
  203.                                 temp=P3;
  204.                                 temp=temp&0xf0;
  205.                                 if(temp!=0xf0)
  206.                                 {
  207.                                         temp=P3;
  208.                                         switch(temp)
  209.                                                 {
  210.                                                         case 0xe7:num=12; break;
  211.                                                         case 0xd7:num=13; break;
  212.                                                         case 0xb7:num=14; break;
  213.                                                         case 0x77:num=15; break;                                                        
  214.                                                         
  215.                                                 }                                                                                
  216.                                 }
  217.                 while(P3!=0xf7);//松手检测,没有松手则保持显示的状态                                                                                                           
  218.                   switch(num)
  219.                            {
  220.                                 case 12:{        
  221.                                                         lcd_clean();
  222.                                                          a=0;b=0;flag=0;
  223.                                                         fuhao=0;
  224.                                                 } break;
  225.                                 case 13:{        
  226.                                                         if(flag==0)
  227.                                                                 {
  228.                                                                         a=a*10;write_date(0x30);
  229.                                                                 }
  230.                                                         else
  231.                                                         {
  232.                                                                 b=b*10;
  233.                                                                 write_date(0x30);
  234.                                                         }
  235.                                                 } break;                                                                                                
  236.                                 case 14:{//需要按"="的
  237.                                                         if(fuhao==1)
  238.                                                         {        
  239.                                                           write_com(0x80+0x0f);
  240.                                                           lcd_clean();//重新定位后再清屏
  241.                                                           write_com(0x04); i=0;                                                                                                                                                                                                                                                                                                                                                                                                               
  242.                                                                 c=a+b;                                                                                                                                                                                                                                                                        
  243.                                                                 while(c!=0)
  244.                                                                         {
  245.                                                                                 write_date(0x30+c%10);
  246.                                                                                 c=c/10;
  247.                                                                         }                                                                                                                                                                                                                                                                                                                                                                                                                                                               
  248.                                                                         write_date(0x3d);//写"="
  249.                                                                         a=0;b=0;flag=0;fuhao=0;//清0
  250.                                                         }
  251.                                                 else if(fuhao==2)
  252.                                                                 {        
  253.                                                                         write_com(0x80+0x0f);
  254.                                                                         lcd_clean();
  255.                                                                         write_com(0x04);
  256.                                                                         if(a-b>0)
  257.                                                                                 c=a-b;
  258.                                                                         else
  259.                                                                                 c=b-a;
  260.                                                                         while(c!=0)
  261.                                                                                 {
  262.                                                                                         write_date(0x30+c%10);                                                                                                
  263.                                                                                         c=c/10;
  264.                                                                                 }
  265.                                                                         if(a-b<0)
  266.                                                                         write_date(0x2d);//"-"减
  267.                                                                         write_date(0x3d);
  268.                                                                         a=0;b=0;flag=0;fuhao=0;
  269.                                                                 }
  270.                                                         else if(fuhao==3)
  271.                                                                 {
  272.                                                                   write_com(0x80+0x0f);
  273.                                                                   lcd_clean();
  274.                                                                   write_com(0x04);
  275.                                                                   c=a*b;
  276.                                                                         while(c!=0)
  277.                                                                                 {
  278.                                                                                     write_date(0x30+c%10);                                                               
  279.                                                                                         c=c/10;
  280.                                                                                 }
  281.                                                                         write_date(0x3d);
  282.                                                                         a=0;b=0;flag=0;fuhao=0;
  283.                                                                 }
  284.                                                 else if(fuhao==4)
  285.                                                         {
  286.                                                                 write_com(0x80+0x0f);
  287.                                                                 lcd_clean();
  288.                                                                  write_com(0x04);
  289.                                                                 i=0;
  290.                                                                 c=(long)(((float)a/b)*1000);//化整后再加小数点                                                        
  291.                                                                 while(c!=0)
  292.                                                                 {
  293.                                                                    write_date(0x30+c%10);
  294.                                                                         c=c/10;                i++;
  295.                                                                 if(i==3)
  296.                                                                 write_date(0x2e);//加小数点"."
  297.                                                                 }
  298.                                                                 if(a/b<=0)
  299.                                                                         write_date(0x30);
  300.                                                                         write_date(0x3d);
  301.                                                                         a=0;b=0;flag=0;fuhao=0;
  302.                                                         }
  303.                                                 else if(fuhao==5)
  304.                                                         {
  305.                                                                 write_com(0x80+0x0f);
  306.                                                                 lcd_clean();
  307.                                                                  write_com(0x04);
  308.                                                                 c=(long)(pow((float)a,(float)1/b)*1000);
  309.                                                                 i=0;
  310.                                                                 while(c!=0)
  311.                                                                         {
  312.                                                                                 write_date(0x30+c%10);
  313.                                                                                 c=c/10;
  314.                                                                                 i++;
  315.                                                                                 if(i==3)
  316.                                                                                 write_date(0x2e);
  317.                                                                         }                                                               
  318.                                                                 write_date(0x3d);
  319.                                                                 a=0;b=0;flag=0;fuhao=0;                                                               
  320.                                                         }
  321.                                                 else if(fuhao==6)
  322.                                                         {
  323.                                                                 write_com(0x80+0x0f);
  324.                                                                 lcd_clean();
  325.                                                                  write_com(0x04);
  326.                                                                 c=pow((float)a,(float)b);//c52内部的函数
  327.                                                                 while(c!=0)
  328.                                                                         {
  329.                                                                                 write_date(0x30+c%10);
  330.                                                                                 c=c/10;
  331.                                                                         }
  332.                                                                 write_date(0x3d);
  333.                                                                 a=0;b=0;flag=0;fuhao=0;        
  334.                                                         }
  335.                                                 else if(fuhao==7)
  336.                                                         {
  337.                                                                 write_com(0x80+0x0f);
  338.                                                                 lcd_clean();
  339.                                                                  write_com(0x04);
  340.                                                                 c=a%b;
  341.                                                                 if(c==0)
  342.                                                                         write_date(0x30);
  343.                                                                 while(c>0)
  344.                                                                         {
  345.                                                                                 write_date(0x30+c%10);
  346.                                                                                 c=c/10;
  347.                                                                         }
  348.                                                                 write_date(0x3d);
  349.                                                                 a=0;b=0;flag=0;fuhao=0;
  350.                                                         }
  351.                                        
  352.                                                 }        break;
  353.                         case 15:{        
  354.                                                 i=table1[num];
  355.                                                 write_date(0x30+i);//"+"加
  356.                                                 flag=1;fuhao=1;
  357.                                         } break;
  358.                         
  359.                                 
  360.                            }
  361.                       }
  362. //*********************P1口的键盘检测
  363.         P1=0xfe;
  364.         temp=P1;
  365.         temp=temp&0xf0;
  366.         if(temp!=0xf0)                                
  367.                 {                delay(5);
  368.                                 temp=P1;
  369.                                 temp=temp&0xf0;
  370.                                 if(temp!=0xf0)
  371.                                 {
  372.                                         temp=P1;
  373.                                         switch(temp)
  374.                                                 {
  375.                                                         case 0xee:num=16; break;
  376.                                                         case 0xde:num=17; break;
  377.                                                         case 0xbe:num=18; break;
  378.                                                         case 0x7e:num=19; break;                                                                                                
  379.                                                 }                                                                                                        
  380.                                 }
  381.                 while(P1!=0xfe);
  382.                 switch(num)
  383.                    {        
  384.                         case 16:{
  385.                                         i=table1[num];
  386.                                          write_date(0x30+i);//"x开y次方
  387.                                         flag=1;fuhao=5;                                       
  388.                                         } break;
  389.                         case 17:{
  390.                                                 i=table1[num];
  391.                                                 write_date(0x30+i);//"^"x的y次方
  392.                                                 flag=1;fuhao=6;
  393.                                         } break;
  394.                         case 18:{
  395.                                                 i=table1[num];
  396.                                                 write_date(0x30+i);//"%"求余
  397.                                                 flag=1;fuhao=7;
  398.                                         }  break;
  399.                         case 19:{//单独出来不用按"="号得结果
  400.                                                 unsigned long int c_1;
  401.                                                 i=table1[num];
  402.                                                 write_date(0x30+i);
  403.                                                 fuhao=8;//"!"阶乘                                                                                                                        
  404.                                                 write_com(0x80+0x0f);
  405.                                                 lcd_clean();
  406.                                                 write_com(0x04);
  407.                                                 c_1=1;
  408.                                                 for(i=1;i<=a;i++)//a的最大值为12,13时已经超出了无符号长整型的范围无法计算
  409.                                                 c_1=c_1*i;
  410.                                                 while(c_1!=0)
  411.                                                         {
  412.                                                                 write_date(0x30+c_1%10);
  413.                                                                 c_1=c_1/10;
  414.                                                         }
  415.                                                         write_date(0x3d);
  416.                                                         a=0;fuhao=0;                                                                                                        
  417.                                         }  break;
  418.                         }
  419.                 }
  420.                 P1=0xfd;
  421.                 temp=P1;
  422.                 temp=temp&0xf0;
  423.                 if(temp!=0xf0)                                
  424.                   {                delay(5);
  425.                                 temp=P1;
  426.                                 temp=temp&0xf0;
  427.                                 if(temp!=0xf0)
  428.                                 {
  429.                                         temp=P1;
  430.                                         switch(temp)
  431.                                                 {
  432.                                                         case 0xed:num=20; break;
  433.                                                         case 0xdd:num=21; break;
  434.                                                         case 0xbd:num=22; break;
  435.                                                         case 0x7d:num=23; break;                                                                                                
  436.                                                 }                                                                                                        
  437.                                 }
  438.                         while(P1!=0xfd);
  439.                         switch(num)
  440.                                 {
  441.                                                 case 20:{
  442.                                                                  write_com(0x80+0x0f);
  443.                                                                 lcd_clean();
  444.                                                                 write_com(0x04);
  445.                                                                 j=0;i=0;c=0;fuhao=9;//2进制转10进制
  446.                                                                 while(a!=0)
  447.                                                                 {
  448.                                                                         r=a%10;
  449.                                                                         s[i++]=r;
  450.                                                                         a=a/10;        
  451.                                                                 }
  452.                                                                 for(j=i-1;j>=0;j--)
  453.                                                                         {
  454.                                                                                 c=c*2+s[j];
  455.                                                                         }
  456.                                                                 while(c!=0)
  457.                                                                         {
  458.                                                                                 write_date(0x30+c%10);
  459.                                                                                 c=c/10;
  460.                                                                         }
  461.                                                                 write_date(0x3d);
  462.                                                                 c=0;a=0;fuhao=0;                                                                                                                                
  463.                                                         } break;
  464.                                         case 21:{        
  465.                                                                 write_com(0x80+0x0f);
  466.                                                                 lcd_clean();
  467.                                                                 write_com(0x04);
  468.                                                                 i=0; fuhao=10;//10进制转2进制
  469.                                                                 while(a!=0)
  470.                                                                         {
  471.                                                                                 r=a%2;
  472.                                                                                 write_date(0x30+r);
  473.                                                                                 y=a/2;
  474.                                                                                 a=y;
  475.                                                                         }                                                                                                                                
  476.                                                                                 write_date(0x3d);
  477.                                                                                 a=0;fuhao=0;                                                                                                                                                                                                               
  478.                                                         } break;
  479.                                         case 22:{
  480.                                                                 write_com(0x80+0x0f);
  481.                                                                 lcd_clean();
  482.                                                                 write_com(0x04);
  483.                                                                 fuhao=11;//10进制转16进制
  484.                                                                 while(a!=0)
  485.                                                                 {
  486.                                                                         r=a%16;//循环求余
  487.                                                                         if(r>=0&&r<=9)//一位一位输出                                                                                
  488.                                                                         write_date(0x30+r);
  489.                                                                         if(r>=10&&r<=15)                                                                                                                                       
  490.                                                                         write_date(0x57+r);
  491.                                                                         y=a/16;
  492.                                                                         a=y;               
  493.                                                                 }                                                                                                                                                                                
  494.                                                                 write_date(0x78);
  495.                                                                 write_date(0x30);                                                               
  496.                                                                 write_date(0x3d);
  497.                                                                 a=0;fuhao=0;               
  498.                                                         } break;
  499.                                         case 23:{
  500.                                                                 write_com(0x80+0x0f);
  501.                                                                 lcd_clean();
  502.                                                                 write_com(0x04);
  503.                                                                 j=0;i=0;c=0;fuhao=12;//2进制转16进制
  504.                                                                 while(a!=0)
  505.                                                                 {
  506.                                                                         r=a%10;
  507.                                                                         s[i++]=r;
  508.                                                                         a=a/10;        
  509.                                                                 }
  510.                                                                 for(j=i-1;j>=0;j--)//2进制先转为10进制
  511.                                                                         {
  512.                                                                                 c=c*2+s[j];
  513.                                                                         }                                                        
  514.                                                                 while(c!=0)
  515.                                                                 {
  516.                                                                         r=c%16;
  517.                                                                         if(r>=0&&r<=9)                                                                                
  518.                                                                         write_date(0x30+r);//得到的10进制再转为16进制
  519.                                                                         if(r>=10&&r<=15)                                                                                                                                       
  520.                                                                         write_date(0x57+r);
  521.                                                                         y=c/16;
  522.                                                                         c=y;               
  523.                                                                 }                                                                                                                                                                                
  524.                                                                 write_date(0x78);
  525.                                                                 write_date(0x30);                                                               
  526.                                                                 write_date(0x3d);
  527.                                                                 a=0;c=0;fuhao=0;                                                        
  528.                                                         } break;                                       
  529.                                 }
  530.                  }
  531.                 P1=0xfb;
  532.                 temp=P1;
  533.                 temp=temp&0xf0;
  534.                 if(temp!=0xf0)                                
  535.                   {                delay(5);
  536.                                 temp=P1;
  537.                                 temp=temp&0xf0;
  538.                                 if(temp!=0xf0)
  539.                                 {
  540.                                         temp=P1;
  541.                                         switch(temp)
  542.                                                 {
  543.                                                         case 0xeb:num=24; break;
  544.                                                         case 0xdb:num=25; break;
  545.                                                         case 0xbb:num=26; break;
  546.                                                         case 0x7b:num=27; break;                                                                                                
  547.                                                 }                                                                                       
  548.                                 }
  549.                 while(P1!=0xfb);                                                                                                
  550.                 switch(num)
  551.                         {
  552.                                 case 24:{
  553.                                                         write_date(0x53);
  554.                                                         write_date(0x69);
  555.                                                         write_date(0x6e);
  556.                                                         write_com(0x80+0x0f);
  557.                                                         lcd_clean();
  558.                                                         write_com(0x04);
  559.                                                         fuhao=13;i=0;//sin
  560.                                                         if(a>=0&&a<=360)
  561.                                                                 {
  562.                                                                         c=(long)((sin((float)a*Pi/180))*1000);
  563.                                                                         while(c!=0)
  564.                                                                                 {
  565.                                                                                         write_date(0x30+c%10);
  566.                                                                                         c=c/10;i++;
  567.                                                                                         if(i==3)
  568.                                                                                                 write_date(0x2e);
  569.                                                                                 }
  570.                                                                                 write_date(0x30);
  571.                                                                                 write_date(0x3d);
  572.                                                                                 i=0;fuhao=0;a=0;c=0;
  573.                                                                 }        
  574.                                                 } break;
  575.                                 case 25:{        
  576.                                                         write_date(0x43);
  577.                                                         write_date(0x6f);
  578.                                                         write_date(0x73);
  579.                                                         write_com(0x80+0x0f);
  580.                                                         lcd_clean();
  581.                                                         write_com(0x04);
  582.                                                         fuhao=14;i=0;//cos
  583.                                                         if(a>=0&&a<=360)
  584.                                                                 {
  585.                                                                         c=(long)((cos((float)a*Pi/180))*1000);
  586. ……………………

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

所有资料51hei提供下载:
计算器.rar (446.67 KB, 下载次数: 36)
回复

使用道具 举报

ID:492496 发表于 2019-3-24 17:42 | 显示全部楼层
打开看了,仿真有错误啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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