精华内容
下载资源
问答
  • 基于51单片机计算器设计

    万次阅读 多人点赞 2019-04-22 16:05:21
    能做计算器的单片机 ...它主要由51单片机的数码管,键盘等模块组成。本计算器是将键盘输入信息经处理通过缓存,送入数码管显示,数码管采用动态扫描方式,计算功能通过软件实现,用C语言对单片机可编芯片进行编程...

    能做计算器的单片机

    单片机的出现是计算机制造技术高速发展的产物,它是嵌入式控制系统的核心,如今,它已广泛的应用到我们生活的各个领域,电子、科技、通信、汽车、工业等。本次设计是设计一个简易计算器,能够进行多位的加减乘除运算。它主要由51单片机的数码管,键盘等模块组成。本计算器是将键盘输入信息经处理通过缓存,送入数码管显示,数码管采用动态扫描方式,计算功能通过软件实现,用C语言对单片机可编芯片进行编程,实现计算器的设计。

    把期中做的作业放上来哈哈

    硬件电路描述

    要进行数据的计算就必须先进行数据的输入,也就必须确定按键输入的数值是什么,这就需要对键盘进行扫描,从而确定究竟是哪个键按下。 对于键盘的扫描,这里采用行列扫描的方法来完成对键盘的扫描。原理就是先确定按键在哪一行,接着再确定是哪一列,这样就可以知道是哪个按键被按下了。我是将P3口作为按键扫描口的,比如,先使行线输出全“0”,读列线,再使列线输出全为“0”,读行线。两次结果再相与,则得到一个值为键值。同理,每个按键都会有一个对应的十六进制值,把它们列出来进行一一对应就行了。如下图。
    在这里插入图片描述

    程序设计描述

    1.程序总流程图
    在这里插入图片描述
    2.编程思路
    在单片机接通电源后,单片机就会一直重复检测键盘上的按钮是否被按下。如果有键被按下,就会进入选择判断,当按下数字键,相应数字计入变量keynum中并在数码管上移位显示;当按下运算符键和特殊功能键,也将对应的10到15数字计入到keynum中并进行第二次判断,如果keynum是0~9,则将数据变量dat×10加上keynum;如果是10(加号对应值),进入加法程序(加法标识变量加1,其他运算符标识变量归零,把dat赋值给另一变量datA;当法标识变量大于1时,就是连加,需要将dat等于dat加上datA的值)。其他运算符也是差不多的程序。keynum等于14,就进入等于运算程序。这个程序中也就是四个if语句,如果运算符变量为1就运行相应代码。如加法运算符为1,则使dat加上datA的值赋给dat。最后将dat放入显示程序中显示,而无论何时按下keynum等于15时,所有状态清零。这就是我写的代码的主要思路。

    源代码及注释

    #include <reg51.h>
    #define long unsigned long
    #define KEYPORT P3
    sbit beep=P1^4;
    bit dot;
    typedef unsigned char byte;
    
    long dat;       //数据
    long datA;      //过度数据
    byte addflag;   //加法标志位
    byte subflag;   //减法标志位
    byte mulflag;   //乘法标志位
    byte divflag;   //除法标志位
    byte clrflag;   //数据处理标志位
    byte scanok;
    int checkok;
    int keynum;    //按键键值
    static byte dispbuf[6];
    //数码管字段表
    sbit duan=P2^6;
    sbit wela=P2^7;
    unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                            0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
    //变量定义
    
    void delayms(int ms)//这个软件大约可以等待ms毫秒
    {
    	  int i,k;
    	  for(k=0; k<ms;k++)	{   for(i=0;i<50;i++);  }
    }
    
    
    /*---------------------------------------------------------------
    查询是否有键按下,有键按下返回键值,无键按下则返回0xff
    ---------------------------------------------------------------*/
    byte keysearch(void)
    {
    	byte k;
     	KEYPORT=0xf0;
     	k=KEYPORT;
     	KEYPORT=0x0f;
     	k=KEYPORT|k;
     	scanok=1;return k;
    }
    void HEX_TO_BCD(int num)
    {	dispbuf[5]  = num%1000000/100000;
        dispbuf[4]  = num%100000/10000;
        dispbuf[3]  = num%10000/1000;
        dispbuf[2]  = num%1000/100;
        dispbuf[1]  = num%100/10;
        dispbuf[0]  = num%10;
    }
    /*---------------------------------------------------------------
    显示子程序
    轮流导通各位数码管,再送出字段码
    延时显示一段时间后再继续导通下一位
    ---------------------------------------------------------------*/
    void scandisp(void)       
    {
    	byte posi=0x1f,i,temp;
    	//posi,为position的缩写,指显示哪一个8字
    	for(i=0;i<6;i++)
     	{
        	temp= dispbuf[i];         //显示缓存区数据查表
        	temp= table[temp];
        	if(i==2&&dot)temp|=0x80;  //i是小数点位置,变量dot=1,点亮小数点
        	P0 = 0;	     duan=1;   duan=0;//先关闭数码管,再切换
        	P0 = posi;   wela=1;   wela=0;  	
        	P0 = temp;   duan=1;   duan=0;
        	delayms(5);//延时 
        	posi>>=1;  posi|=0x20;    //循环右移
     	}
    }
    
    /*---------------------------------------------------------------
    移位显示子程序
    把显示数组中的最低3位赋给高3位,使最新输入的键盘值赋给数组的最低位
    输入:键值
    返回:无
    ---------------------------------------------------------------*/
    void digitin(byte val)               
    { 
    	dispbuf [3]= dispbuf [2];
     	dispbuf [2]= dispbuf [1];
    	dispbuf [1]= dispbuf [0];
     	dispbuf [0]= val;
    }
    
    /*---------------------------------------------------------------
    扫描得到的键值和实际需要的键盘任务的转换函数
    也叫键盘码散转程序
    输入:键值,有0x00~0xff钟可能性,根据显示的键值可以修改此函数
    返回:无
    ---------------------------------------------------------------*/
    void keybranch(byte k)          
    {	if(scanok)
       {scanok=0;
    	switch(k)
     	{
     	    case 0x00:break;
         	case 0xee:keynum=1;break;
         	case 0xde:keynum=2;break;
         	case 0xbe:keynum=3;break;
         	case 0xed:keynum=4;break;
         	case 0xdd:keynum=5;break;
        	case 0xbd:keynum=6;break;
         	case 0xeb:keynum=7;break;
         	case 0xdb:keynum=8;break;
         	case 0xbb:keynum=9;break;
         	case 0xd7:keynum=0;break;
    		case 0x7e:keynum=10;break;//加法
    		case 0x7d:keynum=11;break;//减法
    		case 0x7b:keynum=12;break;//乘法
    		case 0x77:keynum=13;break;//除法
    		case 0xb7:keynum=14;break;//等于
    		case 0xe7:keynum=15;break;//清零
         	default:break;
     	 } checkok=1;
    } }
    /*---------------------------------------------------------------
    处理程序,键值为15时或者清除标志为1时,数据清零
    ---------------------------------------------------------------*/
    void datchuli(void)
    {if(keynum==15)
      {
       dat=0;  datA=0;
       HEX_TO_BCD(dat);
      }
    else if(clrflag)                    //清除标志为1,则执行以下。
      {        
       dat=0;
       clrflag=0;                 //为下次使用准备。
       HEX_TO_BCD(dat);
      }
      if(keynum<10)
      {
      digitin(keynum);
      dat=dat*10+keynum;
      }
    }
    
    void add(void)
    {
       addflag++;                          //加法标志置1。。。
       subflag=mulflag=divflag=0;          //将其它运算标志清零。。(一次只能作一种运算)
       clrflag=1;                          //清零标标置1,(当按下加号后,再按第二个加数时,这时应该显示第二加数。。所以要清掉第一个加数。)
       if(addflag>1)
       {
       dat=datA+dat;
       datA=dat;
       }
       datA=dat;
    }
    void sub(void)						   //减法
    { subflag++;
      addflag=mulflag=divflag=0;
      clrflag=1;
      if(subflag>1)
      {
      dat=datA-dat;
      datA=dat;
      }
      datA=dat;
    }
    void mul(void)							//chengfa
    { mulflag++;
      addflag=subflag=divflag=0;
      clrflag=1;
      if(mulflag>1)
      {
      dat=dat*datA;
      datA=dat;
      }
      datA=dat;
    }
    void div(void)							//chufa
    { divflag++;
      addflag=subflag=mulflag=0;
      clrflag=1;
      if(divflag>1)
      {
      dat=datA/dat;
      datA=dat;
      }
      datA=dat;
    }
    void equ(void)
    {
     
       if(addflag)                           //如果些时做加法运算。。
       {
       dat=dat+datA;                     //计算各存入dat(显示程序会将dat显示的。。)
       }
       if(subflag)
       {
       dat=datA-dat;
       }
       if(mulflag)
       {
       dat=datA*dat;
       }
       if(divflag)
       {
       dat=datA/dat;
       }
       addflag=subflag=mulflag=divflag=0;//运算一次完成后将所有运标志清零。为下次运算作准备。。
       HEX_TO_BCD(dat);	clrflag=1;
    }
    void calculate_handle(void)//计算函数。。
    {	
     if(checkok)//如果检测键值完。则执行以下。
     {
      checkok=0;//检测完标志清零..
      switch (keynum)//如果是+,-,*,/,=则进入相应的函数。。
      {
       case 10 : {add();HEX_TO_BCD(dat);} break;    //如果是按了"+",则进入加法函数。
       case 11 : {sub();HEX_TO_BCD(dat);} break;    //如果是按了"-",则进入减法函数。
       case 12 : {mul();HEX_TO_BCD(dat);} break;    //如果是按了"*",则进入乘法函数。
       case 13 : {div();HEX_TO_BCD(dat);} break;    //如果是按了"/",则进入除法函数。
       case 14 : equ(); break;    //如果是按了"=",则进入等于函数。
       default : datchuli();       //如果不是,计算符(即为数字),则进入数据处理函数。
      }
    
     }}
    /*---------------------------------------------------------------
    主函数:将4X4键盘的键值显示在数码管上
    ---------------------------------------------------------------*/
    void main(void)
    {
    	byte k;
    	while(1)
     	{
     		k=keysearch();
    		
    		if(k!=0xff)   
        {
        	delayms(10);//有键按下
        	k=keysearch();
    		keybranch(k);
      		do
    		{
      			k=keysearch();
    			scandisp();
      		} while(k!=0xff);      //等待键释放
         }
    	 calculate_handle();
    	 scandisp();
      }
    }
    
    

    设计体会

    一开始只是会矩阵键盘和LCD扫描显示,所以当时是想做一个计算器应该还是挺容易的,但直到真正开始做的时候,才发现并不简单。一开始,想的就是,把运算键前输入的数值存到一个变量,后面的数值存到另一个变量内,然后再运算。但问题就来了,如何让单片机知道两次输入的数值要存到不同的变量去?如何把这些变量分别显示到显示管上?然后就要引入更多的变量、设计更多的函数。做出来的第一个版本,能实现加减乘除了,但还有一些问题。按下运算符时,数码管就会直接清零,不像真正计算器那样,按下运算符数码管上数值先不变,等下一数值输入时才变。还有不能实现连续运算的问题,最后还是修改好了。总的来说,这次设计的过程是很有挑战的,尤其对于我这种不善于编程的人来讲,遇到的问题,虽说比较麻烦,但还是车到山前必有路

    展开全文
  • 新手教程,基于51单片机的计算机例程,亲测有效,51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为...
  • 基于51单片机计算器程序,编程语言用的是C语言。要做好计算器,4KB的程序存储空间已经不够用了,所以这里没有用51单片机,这里用的是AT89S52,拥有8KB程序存储空间。 实现功能:  1、一定数值范围内的加减乘除、...
  • 设计是以51单片机为核心的计算器模拟系统设计,输入采用4×4矩阵键盘,可以进行加、减、乘、除4位带符号数字运算,并在LCD1602上显示操作过程。。 主要由51单片机+最小系统+LCD1602液晶显示模块+4*4矩阵按键电路;...

    一.硬件方案

    本设计是以51单片机为核心的计算器模拟系统设计,输入采用4×4矩阵键盘,可以进行加、减、乘、除4位带符号数字运算,并在LCD1602上显示操作过程。。
    主要由51单片机+最小系统+LCD1602液晶显示模块+4*4矩阵按键电路;如图:
    在这里插入图片描述

    二.设计功能

    (1)本设计基于STC89C51/52(与AT89S51/52、AT89C51/52通用)单片机。
    (2)矩阵按键输入、LCD1602液晶显示,构成一套可以运算两个数之间的加减乘除的设计。
    (3)最大运算是:9999*9999,可以运算负数;

    三.设计原理图

    (1)原理图主要采用AD软件进行设计,如图:
    在这里插入图片描述

    (2)Protues仿真图如下:
    在这里插入图片描述

    四.软件设计

    (1)程序流程图
    在这里插入图片描述

    (2)主程序源码

    void main()
    {
    	uchar   key=0xff;               //键值初始化
    	uchar   n=0;		 			//第1个数可以按1-4次
    	uchar   m=5; 					//第2个数可以按1-4次
    	uchar   x=0; 
    	data_a=0;                       //前一个数
    	data_b=0;                       //后一个数
    	data_c=0;                       //结果 
    	init_lcd();  					//1602液晶初始化
    	display_a();
        while(1)
    	  {
    	  	key=keycheckdown();			/*动态扫描键盘,返回按键对应值,赋给j        key=0到f */
    		if(0xff!=key)				/*若返回值有效,进入内部处理程序*/
    		{ 
    		  if(key<10)
    		  {
    	        if(n<4){data_a=data_a*10+key;m=5;display_a();}n++;  //首先输入第一个数
    		    if(m<4){data_b=data_b*10+key;n=5;display_b();}m++;  //必须按了+-*/才能输入第二个数		
    		  }
              else
              {	switch(key)		/*功能键选择*/
    					{
    						case 0xa:n=5;m=0;x=1;W_lcd(5,0,'+');break; //加  /* + S=1 */ /* 数值转换函数 */									
    						case 0xb:n=5;m=0;x=2;W_lcd(5,0,'-');break;		  /* - S=2 *///减
    						case 0xc:n=5;m=0;x=3;W_lcd(5,0,'*');break;		  /* * S=3 *///乘
    						case 0xd:n=5;m=0;x=4;W_lcd(5,0,'/');break;		  /* / S=4 *///除
    						case 0xe:n=5;m=5;eql(x);W_lcd(12,0,'=');display_c(x);break; 	  /* = */
    						case 0xf:n=0;x=0;m=5; data_a=0;data_b=0;data_c=0;LCD_Write_String(0,0,table);LCD_Write_String(0,1,table);W_lcd(0,0,'0');break; /*     C*/
    					}	  		  
    		  }
    			do{P1=0xf0;}while(P1!=0xf0);		/*等待按键松开*/
    	  	}//(0xff!=key)	  
    	  }//while
    }//main
    

    如需资料请关注公众号“单片机实例设计”,首页回复“计算器”获取资料;
    在这里插入图片描述

    展开全文
  • 单片机为核心的计算器模拟系统设计,输入采用矩阵键盘,可以进行加减乘除等十几种数字运算,同时支持括号的嵌套使用级浮点数的运算,并在上显示操作过程。
  • 基于51单片机实现的计算器,有对应的keil5程序、Altium designer原理图、PCB图。并且含有对应的综合课程设计报告。
  • 基于51单片机的简易计算器设计文件,包含源码和原理图
  • 包含全套资料原理图、仿真、源程序及论文等
  • 基于单片机的智能计算器!!!!!!!!!!!!!!!
  • 设计了一个以宏晶STC89C52RC为核心的8位整数运算的计算器。首先提出了设计要求,然后进行方案论证、器件选型及硬件原理图的设计,最后给出了8位整数的加、减、乘、除运算程序。
  • 题目要求: 1、根据开发板设计10以内的加法.../*根据题目要求,设计计算器51单片机矩阵按键的S4,S8,S12,S16分别代表着+,-,*,/;而S13键表示为清零;S1,S2,S3代表着1,2,3;S5,S6,S7代表着4,5,6;S9,S10,S1

    题目要求:

    1、根据开发板设计10以内的加法计算器,用LED数码管显示数字和计算结果。(必做)。

    2、根据开发板设计100以内的计算器,用LED数码管显示数字和计算结果,要求可实现加法、减法、乘法和除法的整型运算(选作)。

    备注:做了第2题可不做第1题

    选做第2题.功能实现如附件视频所示。

    /*根据题目要求,设计计算器,51单片机矩阵按键的S4,S8,S12,S16分别代表着+,-,*,/;而S13键表示为清零;S1,S2,S3代表着1,2,3;S5,S6,S7代表着4,5,6;S9,S10,S11代表着7,8,9。如下排列所示:

     

    1    2    3    +

    4  5    6    -

    7    8    9    *

    清零 0    =    /

    */

    #include<reg51.h>
    typedef unsigned char u8;         //对数据类型进行声明定义
    typedef unsigned int u16;
    
    sbit LSA=P2^2;  //74HC138译码器数码管位选
    sbit LSB=P2^3;
    sbit LSC=P2^4;
    
    #define GPIO_KEY P1
    #define GPIO_DIG P0
    
    u16 KeyValue;        //用来存放读取到的键值
    u16 keyflag,i;       //用来判断按下的数字还是运算符或清空键
    u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};  //显示0~F、负号‘-’
    
    u16 wei[8]={0};    //用来存放每一位数码管数字的数组
    
    void delay(u16 i)//延时函数
    {  
         while(i--);
    }
    
    void display()    //扫描显示动态数码管
    {    
         LSA=0; LSB=0; LSC=0; GPIO_DIG=smgduan[wei[7]];delay(50); GPIO_DIG=0x00; //消隐
         LSA=1; LSB=0; LSC=0; GPIO_DIG=smgduan[wei[6]];delay(50); GPIO_DIG=0x00;
         LSA=0; LSB=1; LSC=0; GPIO_DIG=smgduan[wei[5]];delay(50); GPIO_DIG=0x00; 
         LSA=1; LSB=1; LSC=0; GPIO_DIG=smgduan[wei[4]];delay(50); GPIO_DIG=0x00; 
    }
    /*
    1    2    3    +
    4	 5    6	   -
    7    8    9    *
    清零 0    =    /
    */
    
    void KeyDown(void)//检测有按键按下并读取键值
    {
        u16 a=0;
        GPIO_KEY=0x0f;
        if(GPIO_KEY!=0x0f)//读取按键是否按下
        {
            delay(1000);//延时10ms进行消抖
            if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
            {   
                //测试列
                GPIO_KEY=0x0f;
                switch(GPIO_KEY)//行列扫描法
                {
                    case(0X07): KeyValue=1;break;
                    case(0X0b): KeyValue=2;break;
                    case(0X0d): KeyValue=3;break;
                    case(0X0e): KeyValue=13;break;
                }
                //测试行
                GPIO_KEY=0xf0;
                switch(GPIO_KEY)
                {
                    case(0X70): KeyValue=KeyValue;break;
                    case(0Xb0): KeyValue=KeyValue+3;break;
                    case(0Xd0): KeyValue=KeyValue+6;break;
                    case(0Xe0): KeyValue=KeyValue+9;break;
                }
    			if(KeyValue==11)
    			{
    				KeyValue=0;
    			}
                if(KeyValue==0 || KeyValue==1 || KeyValue==2 || KeyValue==3 || KeyValue==4 || KeyValue==5 || KeyValue==6 || KeyValue==7 || KeyValue==8 || KeyValue==9)
       {
           keyflag=1;
       }
                while((a<50)&&(GPIO_KEY!=0xf0))  //检测按键松手检测
                {
                    delay(1000);
                    a++;
                }
            }
        }
    }
    void main()
    {  
       u16 a=0,b=0,c=0;
    
       while(1)
       {    
             display();                     /* 第一个数字输入*/
             KeyDown();               
             if(keyflag==1)  
             {                                 
                //输入一位,数字向左移动一位     
    			for(i = 4; i <7;i++)
    			{wei[i]=wei[i+1];}  
    			wei[7] = KeyValue;                      
                keyflag=0;                                  
             }
    
             else if(KeyValue==10)
             {
                  for(i=0;i<8;i++)
                      wei[i]=0;              //对数码管清零
        
                   display(); 
            }
    
            else if(KeyValue==13)//加法运算      
             {
                 a=wei[0]*10000000+wei[1]*1000000+wei[2]*100000+wei[3]*10000+wei[4]*1000+wei[5]*100+wei[6]*10+wei[7];   //计算a的值
                 for(i=0;i<8;i++)
                 wei[i]=0;
                 while(1)                               //输入第二个数
                 {
                         display();
                         KeyDown();
                         if(KeyValue==12) break;//当读到等于号,既,KeyValue=12时,停止输入
                         if(keyflag==1)
                         {  
                            for(i = 4; i <7;i++)
    						{wei[i]=wei[i+1];}  
    						wei[7] = KeyValue;                      
              				keyflag=0;
                         }
                  }
                  b=wei[0]*1000000+wei[1]*1000000+wei[2]*100000+wei[3]*10000+wei[4]*1000+wei[5]*100+wei[6]*10+wei[7];   //计算b的值
                 c=a+b;
                 wei[0]=c/10000000%10;               //计算C的各个位的数字
                 wei[1]=c/1000000%10;
                 wei[2]=c/100000%10;
                 wei[3]=c/10000%10;
                 wei[4]=c/1000%10;
                 wei[5]=c/100%10;
                 wei[6]=c/10%10;
                 wei[7]=c%10;
     
                 display();
            }
     
            else if(KeyValue==16)//减法运算      
             {
                 a=wei[0]*10000000+wei[1]*1000000+wei[2]*100000+wei[3]*10000+wei[4]*1000+wei[5]*100+wei[6]*10+wei[7];   //计算a的值
                 for(i=0;i<8;i++)
                 wei[i]=0;
                 while(1)                                //输入第二个数
                 {
                         display();
                         KeyDown();
                         if(KeyValue==12) break;//当读到等于号,既,KeyValue=12时,停止输入
                         if(keyflag==1)
                         {  
                            for(i = 4; i <7;i++)
    						{wei[i]=wei[i+1];}  
    						wei[7] = KeyValue;                      
              				keyflag=0;
                         }
                  }
                  b=wei[0]*1000000+wei[1]*1000000+wei[2]*100000+wei[3]*10000+wei[4]*1000+wei[5]*100+wei[6]*10+wei[7];   //计算b的值
                 c=a-b;
                 wei[0]=c/10000000%10;               //计算C的各个位的数字
                 wei[1]=c/1000000%10;
                 wei[2]=c/100000%10;
                 wei[3]=c/10000%10;
                 wei[4]=c/1000%10;
                 wei[5]=c/100%10;
                 wei[6]=c/10%10;
                 wei[7]=c%10;
     
                 display();
            }
              
    
            else if(KeyValue==19)//乘法运算      
             {
                 a=wei[0]*10000000+wei[1]*1000000+wei[2]*100000+wei[3]*10000+wei[4]*1000+wei[5]*100+wei[6]*10+wei[7];   //计算a的值
                 for(i=0;i<8;i++)
                 wei[i]=0;
                 while(1)                                //输入第二个数
                 {
                         display();
                         KeyDown();
                         if(KeyValue==12) break;//当读到等于号,既,KeyValue=12时,停止输入
                         if(keyflag==1)
                         {  
                            for(i = 4; i <7;i++)
    						{wei[i]=wei[i+1];}  
    						wei[7] = KeyValue;                      
              				keyflag=0;
                         }
                  }
                  b=wei[0]*1000000+wei[1]*1000000+wei[2]*100000+wei[3]*10000+wei[4]*1000+wei[5]*100+wei[6]*10+wei[7];   //计算b的值
                 c=a*b;
                 wei[0]=c/10000000%10;               //计算C的各个位的数字
                 wei[1]=c/1000000%10;
                 wei[2]=c/100000%10;
                 wei[3]=c/10000%10;
                 wei[4]=c/1000%10;
                 wei[5]=c/100%10;
                 wei[6]=c/10%10;
                 wei[7]=c%10;
     
                 display();
            }
    
            else if(KeyValue==21)//除法运算      
             {
                 a=wei[0]*10000000+wei[1]*1000000+wei[2]*100000+wei[3]*10000+wei[4]*1000+wei[5]*100+wei[6]*10+wei[7];   //计算a的值
                 for(i=0;i<8;i++)
                 wei[i]=0;
                 while(1)                                //输入第二个数
                 {
                         display();
                         KeyDown();
                         if(KeyValue==12) break;//当读到等于号,既,KeyValue=12时,停止输入
                         if(keyflag==1)
                         {  
                            for(i = 4; i <7;i++)
    						{wei[i]=wei[i+1];}  
    						wei[7] = KeyValue;                      
              				keyflag=0;
                         }
                  }
                  b=wei[0]*1000000+wei[1]*1000000+wei[2]*100000+wei[3]*10000+wei[4]*1000+wei[5]*100+wei[6]*10+wei[7];   //计算b的值
                 c=a/b;
                 wei[0]=c/10000000%10;               //计算C的各个位的数字
                 wei[1]=c/1000000%10;
                 wei[2]=c/100000%10;
                 wei[3]=c/10000%10;
                 wei[4]=c/1000%10;
                 wei[5]=c/100%10;
                 wei[6]=c/10%10;
                 wei[7]=c%10;
     
                 display();
            }
                         
       }
    }

     

    展开全文
  • 利用51单片机设计一个简单的计算器,能够实现简单的运算
  • 51实现智能计算器
  • 51单片机上实现的完整功能的计算器源代码 单片机 , 计算器 , 源代码
  • 基于AT89S51单片机简易计算器设计。这是基于AT89S51单片机简易计算器设计,下载附件包含对应c语言代码及项目工程资料。
  • LCD计算器设计 1.能实现加减乘除、幂次方、取根号等操作 2.数据结果能实现小数 3.使用LCD1602显示 4.个人代码还有bug 代码实现 #include"reg52.h" #include"math.h" /*********************************************...

    LCD计算器设计

    1.能实现加减乘除、幂次方、取根号等操作
    2.数据结果能实现小数
    3.使用LCD1602显示
    4.个人代码还有bug

    代码实现

    #include"reg52.h"
    #include"math.h"
    /*********************************************************
    lcd智能计算器
    矩阵键盘显示:
    1  2  3  4
    5  6  7  8
    9  0  *  /
    +  -  .  =
    独立键盘:
    ^  sin  ^1/2  clr
    ***********************************************************/
    typedef unsigned int u16;
    typedef unsigned char u8;
    //
    sbit lcd_wr=P2^5;
    sbit lcd_rs=P2^6;  
    sbit lcd_en=P2^7;
    sbit k1=P3^1;
    sbit k2=P3^0;
    sbit k3=P3^2;
    sbit k4=P3^3;
    u8 dat1[]={0,1,2,3,4,5,6,7,8,9,0x2b-0x30, 0x2d-0x30, 0x2a-0x30, 0,0x01-0x30,0x3d-0x30,0x2b-0x30 };
    u8 tab2[]="zhad"; //字符串形式是能---直接显示的
    #define dt P0
    #define key P1
    u8 keyvalue,flag,acc,dat[8],dds,k,fps;
    u16 z1;
    float x,y;
    double z,z2;
    void delay(int z){
    	int i,j;
    	for(i=z;i>0;i--){
    		for(j=110;j>0;j--){}
    	}
    }
    
    void write_com(u8 com){
    	lcd_wr=0;
    	lcd_rs=0;
    	lcd_en=0;
    	P0=com;
    	delay(5);
    	lcd_en=1;
    	delay(5);
    	lcd_en=0;
    }
    void write_data(u8 dta){
     	lcd_wr=0;
    	lcd_rs=1;
    	lcd_en=0;
    	P0=dta;
    	delay(5);
    	lcd_en=1;
    	delay(5);
    	lcd_en=0;
    }
    void lcd_init(){
    	write_com(0x38);	 //8位数据总线--显示两行
    	write_com(0x0c);	//开显示--不显示光标
    	write_com(0x06);	//屏幕不移动--光标右移
    	write_com(0x01);	//初始化清屏
    	flag=0;	   //符号标志位{计算符}---{是加数还是被加数}
    	x=0;
    	y=0;
    	z=0;
    	acc=0;	   //操作符标符标志位
    	dds=0;	   //小数点标志位
    
    	fps=1;		//小数点
    }
    void anjian(){
    	int i=0;
    	key=0x0f;
    	if(key!=0x0f){
    		delay(5);
    		key=0x0f;
    		if(key!=0x0f){
    			switch(key){
    				case(0x07):
    					keyvalue=1;break;
    				case(0x0b):
    					keyvalue=2;break;
    				case(0x0d):
    					keyvalue=3;break;
    				case(0x0e):
    					keyvalue=4;break;
    			
    			}
    
    			key=0xf0;
    			switch(key){
    				case(0x70):
    					keyvalue=keyvalue;break;
    				case(0xb0):
    					keyvalue=keyvalue+4;break;
    				case(0xd0):
    					keyvalue=keyvalue+8;break;
    				case(0xe0):
    					keyvalue=keyvalue+12;break;
    			}
    			if(keyvalue==1 ||keyvalue==2 || keyvalue==3 || keyvalue==4 || keyvalue==5 || keyvalue==6 || keyvalue==7 || keyvalue==8 || keyvalue==9){
    				if(dds==0){
    					if(flag==0){
    						x=x*10+dat1[keyvalue];	
    					}else{
    						y=y*10+dat1[keyvalue];
    					}
    				}else{
    					if(flag==0){
    						
    						x=x+dat1[keyvalue]*pow(0.1,k);
    						k++;
    						fps=fps*0.1;		
    						
    					}else{							 
    						fps=fps*0.1;
    						y=y+(fps*dat1[keyvalue]);
    					}
    				}	
    			 	write_data(0x30+dat1[keyvalue]);
    			}
    			if(keyvalue==10){
    				if(flag==0){
    					x=x*10+dat1[keyvalue];	
    				}else{
    					y=y*10+dat1[keyvalue];
    				
    				}	
    			 	write_data(0x30+dat1[0]);
    			}
    			if(keyvalue==13){		//+
    				acc=1;
    				flag=1;
    				dds=0;
    				write_data(0x2b);
    			}
    			if(keyvalue==14){		//-
    			 	acc=2;
    				flag=1;
    				dds=0;
    				write_data(0x2d);
    			}
    			if(keyvalue==11){	   //*
    			 	acc=3;
    				flag=1;
    				dds=0;
    				write_data(0x2a);
    			}
    			if(keyvalue==12){		//除
    				acc=4;
    				flag=1;
    				dds=0;
    				write_data(0x2f);
    			
    			}
    			if(keyvalue==15){		//.
    				k=1;
    				dds=1;
    				fps=0.1;
    				write_data(0xa5);
    			}
    			/*
    			if(keyvalue==15){
    				 write_com(0x01);
    				 flag=0;
    				 x=0;
    				 y=0;
    				 z=0;
    				 acc=0;
    			}
    			 */
    			if(keyvalue==16){
    				switch(acc){
    					case(1):
    						z=x+y;break;
    					case(2):
    						z=x-y;break;
    					case(3):
    						z=x*y;break;
    					case(4):
    						z=x/y;break;
    					case(5):
    						y=(int)y;
    						z=pow(x,y);
    						break;
    					case(6):
    						z=sin(x);//不能实现
    						break;
    					case(7):
    						z=sqrt(x);
    						break;
    					case(8):
    						break;
    				}
    				z1=z/1;
    				z2=z-z1;
    				write_data(0x3d);//=号
    				write_com(0x80+0x40);
    				write_com(0x06);
    				//write_com(0x04);
    				while(z1!=0)	 //一位一位显示
    				{	
    					 dat[i]=z1%10;
    					//write_data(0x30+z1%10);//显示结果的最后一位在0x4f的位置
    					z1=z1/10;//取前面的结果数据	
    					
    					i=i+1;
    				}  
    				i=i-1;
    				for(;i>-1;i--){
    					write_data(0x30+dat1[dat[i]]);
    				}
    				if(z2!=0){
    					write_data(0xa5);
    				}
    				while(z2!=0){
    					write_data(0x30+(int)(z2*10));
    					z2=(z2*10)-((int)(z2*10));
    				}
    				
    			}
    			
    		  while(key!=0xf0){
    		  	delay(10);
    		  }
    		
    		}
    	
    	}
    	
    	if(k1==0){			//^
    	   delay(10);
    	   if(k1==0){
    		flag=1;
    	   	acc=5;
    	   	write_data(0x5e);
    	   }   
    	   while(!k1);
    	}
    	if(k2==0){			  	//sin
    	   delay(10);
    	   if(k2==0){
    		 //flag=1;	  只有一个操作数不需要这个判断位
    	     acc=6;
    	     write_data(0x73);
    		 write_data(0x69);
    		 write_data(0x6e);
    	   }
    	   while(!k2); 
    	}
    	if(k3==0){				 //开方
    		delay(10);
    		if(k3==0){
    		
    			acc=7;
    			write_data(0xe8);	
    		}
    		while(!k3);
    	}
    	if(k4==0){				   //转二进制--符号无语义---仅作为标识
    		delay(10);
    		if(k4==0){
    			acc=8;
    			write_data(0x7e);	 
    			write_com(0x01);
    			flag=0;
    			x=0;
    			y=0;
    			z=0;
    			acc=0;
    			dds=0;
    			fps=1;
    		}
    		while(!k4);	//到按键释放才离开这里---不然在一秒钟多次扫描程序
    	}
    
    
    }
    
    void main(){
    	lcd_init();
    	write_com(0x80);
    	while(1){
    		anjian();
    	}
    
    }
    
    展开全文
  • 实现一简易的加减法计算器的功能,要求该计算器能够进行6位无符号数的加减计算(也可以乘除)
  • 本程序实现了完整版计算器,包括加减乘除、带小数点显示、带小数点输入、此外还有带时钟功能。当然也可以实现函数功能,只是东西太多了,放不开了。。就没有加上。以后在上传吧.带仿真文件的,一定要用Proteus7.8...
  • 基于c51单片机简单的计算器程序,简易计算器设计两位数加减运算 可实现三位数的加减乘除混合运算!将运算结果显示在数码管上!
  • 设计是以STC89C52单片机为核心的计算器模拟系统设计,输入采用4*5矩阵键盘,可以进行加、减、乘、除等十几种数字运算,同时支持括号的嵌套使用级浮点数的运算,并在LCD1602上显示操作过程。 附件包含相关代码
  • 具有记忆功能的简易计算器,支持加减乘除和括号运算,且可判断算式的正确性。
  • 基于51单片机的科学计算器,可实现加减乘除·,带括号运算,开根号,三角函数,对数函数,乘方。
  • 基于51单片机计算器

    万次阅读 2020-04-04 16:34:15
    继续写一下寒假做的51小项目,这一次是基于AT89C51计算器,带一个八位密码锁功能。 具体实现了计算器的加减乘除功能,并且自带八位密码锁,输入密码后按“=”确定,错误输入三次密码就会锁定,重启后解除锁定,...
  • 基于51单片机计算器Proteus仿真:资源包含原理图,源程序及文档。
  • 1、数字可处理10e-38~10e38 2、7位有效数字 3、精确到小数后六位 4、操作出错提醒
  • 基于STC89C51单片机的实用计算器设计.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 629
精华内容 251
关键字:

基于51单片机计算器设计