基于51单片机的简单计算器

(仿真+程序+设计报告)

功能介绍

具体功能:

1.矩阵键盘输入数字和运算符号;

2.能进行结果为万以内的运算,不能小数;

3.单片机通过74LS138译码器驱动数码管显示;

添加图片注释,不超过 140 字(可选)

​演示视频:

基于51单片机简单计算器—数码管显示、计算到万位、矩阵键盘 

程序

/***微信公众号:木子单片机********/
#include"reg51.h"
#define GPIO_KEY P1	    	//宏定义
#define GPIO_DIG P0	    	//数码管
typedef unsigned char u8;    //无符号数字符    8位
typedef unsigned int u16;	 //无符号数整形    16位

sbit LSA=P2^2;   //74LS138位选
sbit LSB=P2^3;	 //74LS138位选
sbit LSC=P2^4;	 //74LS138位选


u16 KeyValue;   //存键值      
u16 KeySwitch;  //判断是否按下按键?  
u8 code duanxuan[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; 
//段选0-F 
u16 box[8]={0};  //用数组存放每一位段选得到的数字

u16 i;
void delay(u16 i)  //延时
{  
     while(i--);
}



void display()                    //动态显示
{    
     LSA=0; LSB=0; LSC=0;         //000	  第一位
	   GPIO_DIG=duanxuan[box[7]]; //显示0
	   delay(50); GPIO_DIG=0x00;  //消隐 
	
     LSA=1; LSB=0; LSC=0; 		  //100	     第二位
	   GPIO_DIG=duanxuan[box[6]]; //显示0
	   delay(50); GPIO_DIG=0x00;  //消隐 
	
     LSA=0; LSB=1; LSC=0;		  //010	    第三位
     GPIO_DIG=duanxuan[box[5]];	  //显示0
	   delay(50); GPIO_DIG=0x00;  //消隐 
	
     LSA=1; LSB=1; LSC=0;		   //110	 第四位
	   GPIO_DIG=duanxuan[box[4]];  //显示0
	   delay(50); GPIO_DIG=0x00;   //消隐 
	
     LSA=0; LSB=0; LSC=1; 		   //001	 第五位
	   GPIO_DIG=duanxuan[box[3]];  //显示0
     delay(50); GPIO_DIG=0x00; 	   //消隐 
	
     LSA=1; LSB=0; LSC=1; 		   //101	 第六位
	   GPIO_DIG=duanxuan[box[2]];  //显示0
	   delay(50); GPIO_DIG=0x00;   //消隐 
		 
     LSA=0; LSB=1; LSC=1; 		   //011	 第七位
     GPIO_DIG=duanxuan[box[1]];	   //显示0
     delay(50); GPIO_DIG=0x00; 	   //消隐 
		 
     LSA=1; LSB=1; LSC=1; 		   //111	 第八位
	 GPIO_DIG=duanxuan[box[0]];    //显示0
	 delay(50); GPIO_DIG=0x00;     //消隐 
}

void KeyDown(void)	 	 //矩阵键盘扫描
{
    u16 a=0;
    GPIO_KEY=0x0f;		 //0000 1111
    if(GPIO_KEY!=0x0f)	 //有按键按下
    {
        delay(1000);	 //延时判断
        if(GPIO_KEY!=0x0f)	 //确认有按键按下
        {   
           
            GPIO_KEY=0x0f;	   //0000 1111
            switch(GPIO_KEY)   //判断被按按键是在哪一列
            {
                case(0X07): KeyValue=0;break;	 //第一列
                case(0X0b): KeyValue=1;break;	 //第二列
                case(0X0d): KeyValue=2;break;	 //第三列
                case(0X0e): KeyValue=3;break;	 //第四列
            }
            
            GPIO_KEY=0xf0;	    //1111 0000 
            switch(GPIO_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==0 || KeyValue==1 || KeyValue==2 || KeyValue==3 || KeyValue==4 || KeyValue==5 || KeyValue==6 || KeyValue==7 || KeyValue==8 || KeyValue==9)	  //如果确认数字按键被按下
   {
       KeySwitch=1;		   //标志位置1
   }
            while((a<50)&&(GPIO_KEY!=0xf0)) //松手监测
            {
                delay(1000);		 //延时
                a++;
            }
        }
    }
}



void main()							//主函数
{  
   u16 a=0,b=0,c=0;	   				//用来计算的数

   while(1)
   {    
         display();    				//数码管全亮0               
         KeyDown();    				//按键检测           
         if(KeySwitch==1)  			//如果有按键被按下
         {                                 
            for(i=7;i>0;i--)        //数码管可以显示8个数      
            {box[i]=box[i-1];}      //输入一个数      
            box[0]=KeyValue;        //数字就向左移动一位                   
            KeySwitch=0;            //没有按键被按                      
         }

         else if(KeyValue==14)       //清零键
         { 
              for(i=0;i<8;i++)		 //数码管8个数  
                  box[i]=0;          //全部清零   
    
               display(); 			 //显示
        }

        else if(KeyValue==10)   	 //加号键
         {
             a=box[0]+box[1]*10+box[2]*100+box[3]*1000+box[4]*10000+box[5]*100000+box[6]*1000000+box[7]*10000000;   
             //计算第一个数的值存到a里
			 for(i=0;i<8;i++)	  //数码管8个数 
             box[i]=0;			  //清空值,准备取下一个数
					  
             while(1)             //循环                     
             {
                     display();	  //显示
                     KeyDown();	  //按键扫描
                    
                     if(KeySwitch==1)	       //如果有按键被按下
                     {  
                        for(i=7;i>0;i--)	   //数码管可以显示8个数 
                        {box[i]=box[i-1];}	   //输入一个数      
                        box[0]=KeyValue;	   //数字就向左移动一位 
                        KeySwitch=0;		   //没有按键被按       
                     }
										 
					if(KeyValue==15) break; //按等于号后结束循环
              }
							
              b=box[0]+box[1]*10+box[2]*100+box[3]*1000+box[4]*10000+box[5]*100000+box[6]*1000000+box[7]*10000000;  
              //计算第二个数的值存到b
							c=a+b;		 //计算结果存到C里
             box[0]=c%10;                //取个位          
             box[1]=c/10%10;			 //取十位
             box[2]=c/100%10;			 //取百位
             box[3]=c/1000%10;			 //取千位
             box[4]=c/10000%10;			 //取万位
             box[5]=c/100000%10;		 //取十万位
             box[6]=c/1000000%10;		 //取百万位
             box[7]=c/10000000%10;		 //取千万位
 
             display();					 //延时
        }
 

          else   if(KeyValue==12)        //按乘号
         {
             a=box[0]+box[1]*10+box[2]*100+box[3]*1000+box[4]*10000+box[5]*100000+box[6]*1000000+box[7]*10000000;
			                           		  //计算第一个数的值存到a里
             for(i=0;i<8;i++)	      		  //数码管8个数 
             box[i]=0; 			      	      //清空值,准备取下一个数
             while(1)
             {                                     
                     display();		  		  //显示
                     KeyDown();		  		  //按键扫描
                     
                     if(KeySwitch==1)		  //如果有按键被按下
                     {  					  
                        for(i=7;i>0;i--)	  //数码管可以显示8个数 
                        {box[i]=box[i-1];}	  //输入一个数      
                        box[0]=KeyValue;	  //数字就向左移动一位 
                        KeySwitch=0;		  //没有按键被按       
                     }
					if(KeyValue==15) break;	  //按等于号后结束循环
              }
              b=box[0]+box[1]*10+box[2]*100+box[3]*1000+box[4]*10000+box[5]*100000+box[6]*1000000+box[7]*10000000; 
			                             //计算第二个数的值存到b  
                            c=a*b;		 //计算结果存到C里
             box[0]=c%10;                //取个位    
             box[1]=c/10%10;			 //取十位
             box[2]=c/100%10;			 //取百位
             box[3]=c/1000%10;			 //取千位
             box[4]=c/10000%10;			 //取万位
             box[5]=c/100000%10;		 //取十万位
             box[6]=c/1000000%10;		 //取百万位
             box[7]=c/10000000%10;		 //取千万位
             display();
         }
				 
				 
    else    if(KeyValue==11)      		 //按减号
         {
             a=box[0]+box[1]*10+box[2]*100+box[3]*1000+box[4]*10000+box[5]*100000+box[6]*1000000+box[7]*10000000;
												//计算第一个数的值存到a里
             for(i=0;i<8;i++)					//数码管8个数 
             box[i]=0;							//清空值,准备取下一个数
             while(1)							
             {                                         
                     display();					//显示
                     KeyDown();					//按键扫描
                     							
                     if(KeySwitch==1)			//如果有按键被按下
                     {  						
                        for(i=7;i>0;i--)		//数码管可以显示8个数 
                        {box[i]=box[i-1];}		//输入一个数      
                        box[0]=KeyValue;		//数字就向左移动一位 
                        KeySwitch=0;			//没有按键被按       
                     }							
				if(KeyValue==15) break;			//按等于号后结束循环
             }
						 						 
             b=box[0]+box[1]*10+box[2]*100+box[3]*1000+box[4]*10000+box[5]*100000+box[6]*1000000+box[7]*10000000;   
            								    //计算第二个数的值存到b  
               c=a-b;						    //计算结果存到C里
               box[0]=c%10;                     //取个位    
               box[1]=c/10%10;				    //取十位
               box[2]=c/100%10;				    //取百位
               box[3]=c/1000%10;			    //取千位
               box[4]=c/10000%10;			    //取万位
               box[5]=c/100000%10;			    //取十万位
               box[6]=c/1000000%10;			    //取百万位
               box[7]=c/10000000%10;		    //取千万位
             
             
		          display();				  //显示
           }

					 			 
				 
         else  if(KeyValue==13)       		 //按除号
         {
             a=box[0]+box[1]*10+box[2]*100+box[3]*1000+box[4]*10000+box[5]*100000+box[6]*1000000+box[7]*10000000;
											   	//计算第一个数的值存到a里
             for(i=0;i<8;i++)				   	//数码管8个数 
             box[i]=0;						   	//清空值,准备取下一个数
             while(1)                          	      
             {								              
                     display();				   	//显示
                     KeyDown();				   	//按键扫描
                     if(KeySwitch==1)		   	//如果有按键被按下
                     {  					   	
                        for(i=7;i>0;i--)	   	//数码管可以显示8个数 
                        {box[i]=box[i-1];}	   	 //输入一个数      
                        box[0]=KeyValue;	   	 //数字就向左移动一位 
                        KeySwitch=0;		   	 //没有按键被按       
                     }						   	
					 if(KeyValue==15) break;   	//按等于号后结束循环
              }								   
              b=box[0]+box[1]*10+box[2]*100+box[3]*1000+box[4]*10000+box[5]*100000+box[6]*1000000+box[7]*10000000;    
												 //计算第二个数的值存到b 
             c=a/b;								 //计算结果存到C里
             box[0]=c%10;                  		 //取个位    
             box[1]=c/10%10;					 //取十位
             box[2]=c/100%10;					 //取百位
             box[3]=c/1000%10;					 //取千位
             box[4]=c/10000%10;					 //取万位
             box[5]=c/100000%10;				 //取十万位
             box[6]=c/1000000%10;				 //取百万位
             box[7]=c/10000000%10;				 //取千万位
             display();               
         }
                     
   }
}

       
                     
   

硬件设计

使用元器件:

单片机:AT89C51;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

添加图片注释,不超过 140 字(可选)

流程图:

添加图片注释,不超过 140 字(可选)

设计资料

01仿真图

本设计使用proteus8.9版本设计!具体如图!

添加图片注释,不超过 140 字(可选)

02程序

本设计使用Keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

03设计报告

八千字设计报告,具体如下!

04设计资料

        资料获取请关注同名公众号,全部资料包括程序(含注释)、仿真源文件 、设计报告、流程图等。具体内容如下,全网最全! !

添加图片注释,不超过 140 字(可选)

资料获取请观看前面演示视频!

点赞分享一起学习成长。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐