基于51单片机的多功能计算器全套设计资料下载(PCB+源码+仿真+论文)

目录

一、实物图

二、资料内容

三、摘要

四、设计要求

五、硬件电路设计

5.1 单片机电路设计

5.2 键盘电路

5.3蜂鸣器提示电路

5.4液晶显示电路

六、测试验证

6.1整数验证

6.2 输入出错情况

七、元器件清单

八、程序

资料下载地址:基于51单片机的多功能计算器全套设计资料下载(PCB+源码+仿真+论文)

一、实物图

二、资料内容

 

三、摘要

          当今社会,随着人们物质生活的不断提高,电子产品已经走进了家家户户,无论是生活或学习,还是娱乐和消遣几乎样样都离不开电子产品,大型复杂的计算能力是人脑所不能胜任的,而且人脑比较容易出错。计算器作为一种快速通用的计算工具方便了用户的使用。计算器可谓是我们最亲密的电子伙伴之一。本设计着重在于分析计算器设计开发过程中的环节和步骤,并从实践经验出发对计算器设计做了详细的分析和研究。
        本设计是以STC89C52单片机为核心的计算器模拟系统设计,输入采用5×8矩阵键盘,可以进行加、减、乘、除等十几种数字运算,同时支持括号的嵌套使用级浮点数的运算,并在LCD1602上显示操作过程。
        本次设计注重设计方法及流程,首先根据原理设计电路,利用keil编程,借助实验开发平台进行仿真实验,进而利用altium designer 制作PCB,最后到焊接元器件,直至调试成功。在设计的同时,特别注重keil软件和altium designer软件的使用方法和技巧以及常用的LCD显示器和矩阵键盘的设计和使用方法。

四、设计要求

1、掌握MCS-51系列某种产品(例如8051)的最小电路及外围扩展电路的设计方法;

2、计算器能实现加、减、乘、除、平方、开方、N次方、开N次方、正弦函数、                                  余弦函数、正切函数、反正弦、反余弦、反正切、对数运算、阶乘(N<=34)、排列、                 组合、累加等十九种功能。

3、支持浮点数运算;

4、较为友好的界面显示,对输入实时显示,对计算结果输出显示;

5、能够具备比较完善的报错系统

五、硬件电路设计

5.1 单片机电路设计

为使单片机正常工作,除电源供电部分外,还需提供晶振电路和复位电路。具体电路如下:

        由图可知,9脚外接的是按键复位电路,18,19脚外接的是晶振电路,这样,就构成了单片机正常工作的必备电路。同时,为使P0口正常工作,并增加其带负载能力,P0口需接了上拉电阻。图中EA为外部访问允许,欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。在这里,STC89C52单片机8k的程序存储器已经够本设计使用,无需外部程序储存器,故EA直接接高电平。

5.2 键盘电路

        图是键盘电路,共20个按键,用来实现人机交互和运算表达式的输入,S0~S3、S5~S8、S10~S13、S15~S18共16个按键组成一组4*4的矩阵键盘,行线第一行到第四行分别接在P3.0~P3.3口,列线第一列到第四列分别接在P3.4~P3.7口,这样P3口就完成了对4*4的矩阵键盘的接线。同时,注意到按键数量还达不到要求,故增加了四个独立按键S4,S9,S14,S19。他们依次接在P20~P23口。可见,矩阵键盘相对来讲更节省I/O口,但本着学习的目的,加之本设计并不需要太多的I/O口,故为充分学习和利用资源,在这里也设计了4个这样的独立按键。

5.3蜂鸣器提示电路

        蜂鸣器主要用于按键时发出声音,提示当前的按键操作,电路如图2.5所示,三极管主要用于驱动蜂鸣器,因为单片机I/O的驱动能力有限。同时单片机I/O口还在这里还起到开关作用,为‘0’时打开蜂鸣器通道,使蜂鸣器发声。

5.4液晶显示电路

LCD也是本次设计的重要组成部分之一,主要用于显示输入和输出。电路如图所示,LCD数据端与单片机P0口相连,控制端与P24~P26连接,电位器用于调节对比度。

六、测试验证

6.1整数验证

        在此以整数运算为例,介绍计算器的使用方法即流程。首先打开电源,看到LCD打开显示,说明运行正常,接着,输入表达式:12*(56+23)*2,其结果本身应为1896。

        输入结束后,点“=”按键,即可在第二行显示出运算结果,由图可见运算完全正确。在使用时,可以通过声音开关按钮控制按键音的打开和关闭,在LCD上也有显示,如果再第二行第一个位置没有显示,则没有打开声音,可以通过按钮打开。若有显示,则声音已经打开,可以通过按钮关闭声音。如图所示,此时已经打开声音。

 

6.2 输入出错情况

        由图可以看出,可以进行浮点数运算,还可以从第二行第一个字符,蜂鸣器处于关闭状态。

 再按“=”号,将会出现出错画面。

七、元器件清单

1)晶振12M一个

(2)stc89c52芯片一片

(3)30pf 2个;10uf 1个;

(4)40脚活动底座一个

(5)LCD液晶一个

(6)按键21个

(7)发光二极管1个

(8)9引脚排阻 1个

(9)680Ω 1个;10k 2个;1k  1个;10k滑动变阻器 1个; 10Ω 1个;

(10) 开关1个

(11) 5V有源蜂鸣器1个

(12) 三极管S8550一个

(13)排针若干,杜邦线若干

八、程序

/*************按键扫描****************************/
char scan()
{

  char h_data,l_data,i,key_num;
  P2=P2&0XE0;//P2低5位送0
  P1=P1|0X0F;//P1低4位送1
  while((P1|0xf0)==0xff)//判断P1低4位是否全为1
  {
   while((P1|0xf0)==0xff);
   DelayMs(10);//延时10ms
  }
   l_data=~(P1|0xf0);//记入列标志
   P2=P2|0X1F;//P2低五位送1
   P1=P1&0XF0;//P1低四位送0
   h_data=~(P2|0xe0);//记入行标志
   for(i=0;i<=4;i++)//计算行号(0~4)
            {
           if(h_data==1)break;
           h_data=h_data>>1;
         }
h_data=i;//行号
  for(i=1;i<=4;i++)//计算列号(1~4)
         {
          if(l_data==1)break;
          l_data=l_data>>1;
        }
l_data=i;//列号
   key_num=h_data*4+l_data;        

  P2=P2&0XE0;//P2低5位送0
  P1=P1|0X0F;//P1低4位送1
  while((P1|0xf0)!=0xff)//判断P1低4位是否全为1
  {
   while((P1|0xf0)!=0xff);
   DelayMs(10);//延时10ms
  }
  return key_num;
}
void float_to_char(float a,char* p)
{
  char i,flag,length;
  flag=0;
  sprintf(p,"%f",a);
  length=strlen (p);
  for(i=0;i<length;i++)
  {
    if(*(p+i)=='.')flag=1;
  }
  if(flag==1)
  for(i=length-1;i>=0;i--)
  {
    if(*(p+i)=='.'){*(p+i)='\0';break;}
    if(*(p+i)!='0'){*(p+i+1)='\0';break;}
  }
}
/**********************更新液晶*************************/
void refresh()//更新液晶
{
  char length,i,j;
  char dot;
  dot=0;
         
  float_to_char(num2,c_num2);//num2转为字符型
  length=strlen(c_num2);
  for(i=0,j=0;i<length;i++)        
  {
    if(c_num2[i]=='.')
        dot=1;
        if(dot==1)
    j++;
  }
  if(j<len)
  {
          if(dot==1)
          {        
            for(i=length;i<(length+len-j);i++)
                 {
                   c_num2[i]='0';
        
                 }
                 c_num2[i]='\0';
          }
          else
                {
                  
                  c_num2[length]='.';
                  if(len-j>1)
                  {
                    for(i=length+1;i<(length+len-j);i++)
                         c_num2[i]='0';
                  }
                  c_num2[length+len-j]='\0';
                }  
  }

  if(neg_flag==1)//'+/-'按下首位加‘-’
   {
      length=strlen(c_num2);//计算c_num2长度         
                    for(i=length-1;i>=0;i--)
                  {
                          c_num2[i+1]=c_num2[i];
                  }
                  c_num2[length+1]='\0';
                  c_num2[0]='-';
   }
   
   if(sqrt_flag==1)
           {
      length=strlen(c_num2);//计算c_num2长度
             for(i=length-1;i>=0;i--)
          {
                  c_num2[i+1]=c_num2[i];
          }
          c_num2[length+1]='\0';
          c_num2[0]=0xe8;//字符根号
   }
   
   
   if(error==0)
   {
           float_to_char(num1,c_num1);//num1转为字符型
           WriteCommand(0x01); //显示清屏
           ShowString(0,c_num1);
           ShowString(1,c_num2);  
           ShowChar(15,yun_flag);
   }else
   {
       WriteCommand(0x01); //显示清屏
           ShowString(0,"error!!!");
   }
}
//键值处理
void operation1(char keynum)//按下 ’+、-、*、/处理
{
  if(key_last==1)//上次按键为 数字、小数点、+/-、sqrt
   {
     if(neg_flag==1)num2=-num2;//'+/-'按下
         if(sqrt_flag==1)//sqrt按下
         {
         if(num2>=0)
         num2=sqrt(num2);
         else
         error=1;
         }
         if(yun_flag=='+')num1=num1+num2; //按下的是‘+’
         if(yun_flag=='-')num1=num1-num2;//按下的是‘-’
         if(yun_flag=='*')num1=num1*num2;//按下的是‘*’
         if(yun_flag=='/')//按下的是‘/’
         {
           if(num2!=0)
           num1=num1/num2;
           else
           error=1;
         }
         num2=0;//num2清零
         sqrt_flag=0;//sqrt_flag清零
     neg_flag=0;//neg_flag清零
         pos_flag=1;//pos_flag回1
   }
   if(keynum==4)yun_flag='+';//yun_flag更新
   if(keynum==8)yun_flag='-';
   if(keynum==12)yun_flag='*';
   if(keynum==16)yun_flag='/';
   len=0;
   key_last=0;//key_last更新   
   refresh();
}
//
void operation2(char keynum)//输入数字
{
  float Data1;
   
  if(keynum==1)Data1=7;//分析输入数字
  if(keynum==2)Data1=8;
  if(keynum==3)Data1=9;
  if(keynum==5)Data1=4;
  if(keynum==6)Data1=5;
  if(keynum==7)Data1=6;
  if(keynum==9)Data1=1;
  if(keynum==10)Data1=2;
  if(keynum==11)Data1=3;
  if(keynum==13)Data1=0;
  if(pos_flag==1)//更新num2
  num2=num2*10+Data1;
  else
  {            
    num2=num2+(Data1/pos_flag);
        pos_flag=pos_flag*10;
        len++;
  }
  key_last=1;//更新key_last        
  refresh();
}

void operation3()//输入小数点
{
  if(pos_flag==1)//首次出现小数点
  {
   pos_flag=pos_flag*10;//小数位权*10
   len++;
  }
  key_last=1;//更新key_last
  refresh();//更新液晶
}
/
void operation4()//输入'='
{
     if(neg_flag==1)num2=-num2;//'+/-'按下
         if(sqrt_flag==1)//sqrt按下
         {
         if(num2>=0)
         num2=sqrt(num2);
         else
         error=1;
         }
         if(yun_flag=='+')num1=num1+num2; //按下的是‘+’
         if(yun_flag=='-')num1=num1-num2;//按下的是‘-’
         if(yun_flag=='*')num1=num1*num2;//按下的是‘*’
         if(yun_flag=='/')//按下的是‘/’
         {
           if(num2!=0)
           num1=num1/num2;
           else
           error=1;
         }
         num2=0;//num2清零
         sqrt_flag=0;//sqrt_flag清零
     neg_flag=0;//neg_flag清零
         pos_flag=1;//pos_flag回1
     yun_flag='+';//yun_flag更新
         len=0;
   key_last=0;//key_last更新   
   refresh();
}

void operation5()//输入clear all
{

   num1=0;// num1清零
   num2=0;//num2清零
   sqrt_flag=0;//清sqrt_flag
   neg_flag=0;// 清neg_flag
   pos_flag=1;// Pos_flag=1
   yun_flag='+';// yun_flag(为'+')
   error=0;//清error
   len=0;
   key_last=0;//更新key_flag
   refresh();//更新液晶
}
///
void operation6()//输入'C'
{
num2=0;//num2清零
sqrt_flag=0;//清sqrt_flag
neg_flag=0;//清neg_flag
pos_flag=1;//pos_flag=1
len=0;
key_last=0;//key_last
refresh();//更新液晶
}

void operation7()//输入'+/-'
{
  if(neg_flag==0)//neg_flag反转
  neg_flag=1;
  else neg_flag=0;
  key_last=1;//key_last
  refresh();// 更新液晶
}
/
void operation8()//输入'sqrt'
{
if(sqrt_flag==0)//sqrt_flag反转
  sqrt_flag=1;
else sqrt_flag=0;
key_last=1;//更新key_last
refresh();//更新液晶
}

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
智能计算器软件源码: ```c #include <reg51.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char sbit k0 = P3^2; sbit k1 = P3^3; sbit k2 = P3^4; sbit k3 = P3^5; sbit beep = P2^3; uchar code table[] = { '0','1','2','3','+', '4','5','6','-', 0, '7','8','9','*', 0, '.','=','C','/', 0 }; void delay(uint z){ uint x,y; for(x=z;x>0;x--){ for(y=110;y>0;y--); } } void key_scan(){ uchar temp,i; P0 = 0xf0; temp = P0; temp &= 0xf0; if(temp != 0xf0){ delay(5); temp = P0; temp &= 0xf0; if(temp != 0xf0){ temp >>= 4; switch(temp){ case 0x0e: P2 = 0xfe; for(i=0;i<20;i++){ if(!k0) break; delay(10); } if(i == 20){ beep = 0; } break; case 0x0d: P2 = 0xfd; for(i=0;i<20;i++){ if(!k1) break; delay(10); } if(i == 20){ beep = 0; } break; case 0x0b: P2 = 0xfb; for(i=0;i<20;i++){ if(!k2) break; delay(10); } if(i == 20){ beep = 0; } break; case 0x07: P2 = 0xf7; for(i=0;i<20;i++){ if(!k3) break; delay(10); } if(i == 20){ beep = 0; } break; default: break; } P2 = 0xff; } } } void write_com(uchar com){ P2 = 0; P0 = com; _nop_(); P2 = 0x40; delay(2); P2 = 0; } void write_data(uchar date){ P2 = 0x80; P0 = date; _nop_(); P2 = 0xc0; delay(2); P2 = 0; } void init(){ write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); } void main(){ uchar n=0,s=0,c=0; init(); while(1){ key_scan(); if(!k0){ beep = 0; write_data(table[n]); delay(500); beep = 1; n++; n %= 20; } if(!k1){ beep = 0; write_data(table[s]); delay(500); beep = 1; s++; s %= 20; } if(!k2){ beep = 0; write_com(0x18); c++; if(c > 15){ c = 0; write_com(0x18); } beep = 1; } if(!k3){ beep = 0; write_com(0x01); n = 0; s = 0; c = 0; beep = 1; } } } ``` 这是基于51单片机,使用按键键盘和LCD1602显示屏设计的智能计算器软件源码。其中使用了4个按键进行控制,按键K0~K3分别对应数字和运算符的输入、切换显示内容、清空屏幕和清零操作。源码实现通过按键输入数字和运算符,将输入内容显示在LCD1602上。同时还实现了蜂鸣器功能,以便在按下按键时发出提示音。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森旺电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值