找回密码
 立即注册

QQ登录

只需一步,快速开始

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

如何使用AT89c52单片机做出一个简易计算器(加减乘除就好,无需要练算)

[复制链接]
跳转到指定楼层
楼主
ID:844638 发表于 2020-12-23 16:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1黑币
新手学生,看了一个星期了,也看了其他大神的程序等等,但是因为用的器件不同,好多地方都搞不动,希望有大神能具体指导,教教原理和代码,使用的是蓝桥杯的ct107d板子,有仿真图

51hei图片20201223163614.png (342.34 KB, 下载次数: 99)

51hei图片20201223163614.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:844638 发表于 2020-12-23 17:49 | 只看该作者
下面是我的代码,但是每次仿真都有问题,希望有大神能帮帮我
仿真图在附件#include<reg51.h>  //头文件
#define uint unsigned int
#define uchar unsigned char
sbit lcden=P2^3; //定义引脚
sbit rs=P2^4;
sbit rw=P2^0;
sbit busy=P0^7;
char i,j,temp,num,num_1;
long a,b,c;    //a,第一个数 b,第二个数 c,得数
float a_c,b_c;
uchar flag,fuhao;//flag是否有键按下,fuhao按下的是哪个键
uchar code table[]={
7,8,9,0,
4,5,6,0,
1,2,3,0,
0,0,0,0};
uchar code table1[]={
7,8,9,0x2f-0x30,
4,5,6,0x2a-0x30,
1,2,3,0x2d-0x30,
0x01-0x30,0,0x3d-0x30,0x2b-0x30};
void delay(uchar z) //延迟函数
{
uchar y;
for(z;z>0;z--)
   for(y=0;y<110;y++);
}
void check() //判断忙或闲
{
do{
    P0=0xFF;
    rs=0;    //指令   
    rw=1;    //读
    lcden=0;    //禁止读写
    delay(1); //等待,液晶显示器处理数据   
    lcden=1;    //允许读写
    }while(busy==1); //判断忙或闲,1忙,0闲
}
void write_com(uchar com) //写指令函数
{
P0=com;   //com指令给p0
rs=0;
rw=0;
lcden=0;
check();
lcden=1;
}
void write_date(uchar date) //写数据函数
{
    P0=date;
rs=1;
rw=0;
lcden=0;
check();
lcden=1;
}
void init() //初始化
{
        num=-1;
lcden=1; //使信号能成高电平
write_com(0x38); //8位?2行
write_com(0x0c); //显示开,光标关,不闪烁*/
write_com(0x06); //增量方式不位移
write_com(0x80); //监测忙信号
write_com(0x01); //显示开,光标关,不闪烁
num_1=0;
i=0;
j=0;
a=0;    //第一个参和运算的数
b=0;    //第二个参和运算的数
c=0;
flag=0; //flag是否按下  
fuhao=0; // fuhao按下哪个键
}
void keyscan() //键盘扫描
{
P3=0xfe;
if(P3!=0xfe)
{
                delay(20);//延时20ms   
if(P3!=0xfe)   
{
    temp=P3&0xf0;   
switch(temp)   
{
     case 0xe0:num=0;      
break;
     case 0xd0:num=1;      
break;
     case 0xb0:num=2;      
break;
     case 0x70:num=3;      
break;    }
   }
   while(P3!=0xfe);
   if(num==0||num==1||num==2)//如果按下的是7.8.9
{
       if(j!=0)      
{
          write_com(0x01);      
   j=0;      
   }
       if(flag==0)//没按过符号
{
     a=a*10+table[num];   
}
    else//按过符号  
  {
     b=b*10+table[num];   
  }   
}
   else//如果按下的是除
         {

    flag=1;
    fuhao=4;//4表示按过除号
  }
   i=table1[num];   
write_date(0x30+i);
}
P3=0xfd;
if(P3!=0xfd)
{
   delay(5);  
if(P3!=0xfd)   
{
    temp=P3&0xf0;   
switch(temp)   
{
     case 0xe0:num=4;         
break;
     case 0xd0:num=5;      
  break;
     case 0xb0:num=6;      
   break;
     case 0x70:num=7;      
  break;    }
   }
   while(P3!=0xfd);
   if(num==4||num==5||num==6&&num!=7)//如果按下的是4.5.6
  {
    if(j!=0)        
{
          write_com(0x01);      
    j=0;         }
       if(flag==0)//没有按过符号键
  {
     a=a*10+table[num];   
}
    else//按过符号键   
{
     b=b*10+table[num];   
}  
}
   else//按下的是除   
         {
    flag=1;
    fuhao=3;//3表示按下乘号
                }
   i=table1[num];   
write_date(0x30+i);
}
P3=0xfb;
if(P3!=0xfb)
{
   delay(5);  
if(P3!=0xfb)  
{
    temp=P3&0xf0;   
switch(temp)   
{
     case 0xe0:num=8;   
      break;
     case 0xd0:num=9;   
      break;
     case 0xb0:num=10;
        break;
     case 0x70:num=11;   
      break;   
}
   }
   while(P3!=0xfb);
   if(num==8||num==9||num==10)//如果按下的是1.2.3
{
    if(j!=0)   
    {
          write_com(0x01);      
    j=0;     
    }
      if(flag==0)//没有按过符号键  
  {
     a=a*10+table[num];   
  }
    else//如果按过
   {
     b=b*10+table[num];
    }
  }
   else if(num==11)//如果按下的是减号  
{
    flag=1;
    fuhao=2;//2表示按过减号
  }
   i=table1[num];  
write_date(0x30+i);
}
P3=0xf7;
if(P3!=0xf7)
{
   delay(5);   
if(P3!=0xf7)  
{
    temp=P3&0xf0;   
switch(temp)  
  {
     case 0xe0:num=12;      
   break;
     case 0xd0:num=13;   
     break;
     case 0xb0:num=14;   
     break;
     case 0x70:num=15;   
     break;    }
   }
   while(P3!=0xf7);  
switch(num)  
{
    case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//如果按下的是清零  
  break;
    case 13:{               //按下的是0     
if(flag==0)//没按过符号键     
   {
        a=a*10;
        write_date(0x30);   
    P1=0;     
  }
       else if(flag==1)//按过符号建  
     {
        b=b*10;
        write_date(0x30);      
  }  
    }   
  break;
    case 14:{j=1;
           if(fuhao==1){write_com(0x80+0xf);//按下等号,光标前进至第二行最后一个显示处
           write_com(0x04);    //设置从后往前写数据,每写完一个数据,光标后退一格         
c=a+b;
          while(c!=0)           {
             write_date(0x30+c%10);   
          c=c/10;           }
           write_date(0x3d);    //再写"="         
a=0;b=0;flag=0;fuhao=0;         
  }
      else if(fuhao==2){write_com(0x80+0xf);//光标前进至第二行最后一个显示处
            write_com(0x04);    //设置从后往前写数据,每写完一个数据,光标后退一格      
if(a-b>0)
            c=a-b;
          else
             c=b-a;  
         while(c!=0)
          {
             write_date(0x30+c%10);         
   c=c/10;
           }
           if(a-b<0)
             write_date(0x2d);
           write_date(0x3d);    //再写"="                    
  a=0;b=0;flag=0;fuhao=0;          }
      else if(fuhao==3){write_com(0x80+0xf);  
          write_com(0x04);         
   c=a*b;            
while(c!=0)         
   {
             write_date(0x30+c%10);     
        c=c/10;         
    }
             write_date(0x3d);     
          a=0;b=0;flag=0;fuhao=0;      
       }
      else if(fuhao==4){write_com(0x80+0xf);  
          write_com(0x04);      
      i=0;
            c=(long)(((float)a/b)*1000);      
     while(c!=0)      
      {
               write_date(0x30+c%10);     
          c=c/10;  
         i++;      
     if(i==3)
               write_date(0x2e);             }
            if(a/b<=0)
              write_date(0x30);
            write_date(0x3d);
                                         a=0;b=0;flag=0;fuhao=0;  
                  }   
  }   
  break;
     case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;}
   break;
  }
}
}
main()
{
init();
while(1){
   keyscan();
}
}
代码及仿真图.zip (44.64 KB, 下载次数: 12)





回复

使用道具 举报

板凳
ID:88256 发表于 2020-12-23 19:34 | 只看该作者
我没法打开仿真,你的是什么问题?总要描述清楚问题所在啊
回复

使用道具 举报

地板
ID:844638 发表于 2020-12-23 21:29 | 只看该作者
hhdsdy 发表于 2020-12-23 19:34
我没法打开仿真,你的是什么问题?总要描述清楚问题所在啊

就是我写出来的和给定给我的仿真图好像不匹配,图不让自己画(就必须用这个原理图),所以我想请大家看看该怎么修改
回复

使用道具 举报

5#
ID:88256 发表于 2020-12-23 22:57 | 只看该作者
君颜兮梦 发表于 2020-12-23 21:29
就是我写出来的和给定给我的仿真图好像不匹配,图不让自己画(就必须用这个原理图),所以我想请大家看看 ...

就是说这个程序不是你自己写的,而是直接抄的了?否则也不会1602的引脚定义不一样,只是我想不明白,改一下引脚有那么难吗?等1602正常显示了再进行下一步的工作
回复

使用道具 举报

6#
ID:748788 发表于 2020-12-24 10:32 | 只看该作者
作为单片机的新手还是应该从基础学起,编程先学点亮led、流水灯等。这个对你起点太高,难为自己,也难为别人
回复

使用道具 举报

7#
ID:844638 发表于 2020-12-24 12:40 | 只看该作者
hhdsdy 发表于 2020-12-23 22:57
就是说这个程序不是你自己写的,而是直接抄的了?否则也不会1602的引脚定义不一样,只是我想不明白,改一 ...

好的我去看看,我们是小组合作,我们去研究研究
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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