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

目录

一、实物图

二、资料内容

三、摘要

四、设计要求

五、硬件电路设计

[5.1 单片机电路设计](#5.1 单片机电路设计)

[5.2 键盘电路](#5.2 键盘电路)

5.3蜂鸣器提示电路

5.4液晶显示电路

六、测试验证

6.1整数验证

[6.2 输入出错情况](#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)排针若干,杜邦线若干

八、程序

cpp 复制代码
/*************按键扫描****************************/
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();//更新液晶
}
相关推荐
blessing。。1 小时前
I2C学习
linux·单片机·嵌入式硬件·嵌入式
嵌新程2 小时前
day03(单片机高级)RTOS
stm32·单片机·嵌入式硬件·freertos·rtos·u575
Lin2012303 小时前
STM32 Keil5 attribute 关键字的用法
stm32·单片机·嵌入式硬件
电工小王(全国可飞)3 小时前
STM32 RAM在Memory Map中被分为3个区域
stm32·单片机·嵌入式硬件
maxiumII3 小时前
Diving into the STM32 HAL-----DAC笔记
笔记·stm32·嵌入式硬件
美式小田6 小时前
单片机学习笔记 9. 8×8LED点阵屏
笔记·单片机·嵌入式硬件·学习
兰_博6 小时前
51单片机-独立按键与数码管联动
单片机·嵌入式硬件·51单片机
时光の尘7 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
-一杯为品-7 小时前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
嵌入式大圣8 小时前
单片机结合OpenCV
单片机·嵌入式硬件·opencv