51单片机设计计算器

51单片机设计的计算器

参考了这个博主的代码写的觉得条理很清楚 ,代码的写法基本也是按照这位博主的,只改了一些
https://blog.csdn.net/liang507107/article/details/89453934

矩阵按键代表计算器中的值

可以实现连续的加减乘除 **P0 发送数据 P2实现动态数码管的片选 P1接矩阵按键**
+-*/
369清零
258=
1470

下面是代码

在这里插入代码片
	#include<reg51.h>
	#include<intrins.h>
	#define uc unsigned char
	#define ut unsigned int
	#define key_board P1	 //矩阵按键
	#define shu_ju P0       //给数码管数据
	#define pian_xuan P2 	 //控制动态数码管
     
   	 ut  sum1=0,sum2=0 ;//算结果的
     uc addflag=0;//加法标志
	 uc subflag=0; //减法标志
	 uc mulflag=0;	//乘法标志
	 uc divflag=0; //除法标志
	 uc qpflag=0; //在进行连加减乘除是 清空数码管
	uc code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					             0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值 共阴数码管
   static uc duanxuan[8]; 
	uc keyflag=0;//表示是否有按键的记录
	uc keyflag1=0; //在计算函数里控制
	uc keyvalue;
   void delay(ut t)
   {
	  uc i,j;
	  for(i=0;i<=t;i++)
	  {
		for(j=0;j<=120;j++); 

	  }

   }
 
	 void kaishi()
  {
	 uc t,i;
	 uc yiwei=0x7f;
	 for(i=0;i<8;i++)
	 {	  t=duanxuan[i];
	      t=smgduan[t];
		  shu_ju=0;
		  pian_xuan=yiwei;
		  shu_ju=t;
		 delay(5);
		 yiwei=_cror_(yiwei,1);
		 yiwei|=0x80;


	 }
  }
uc anjian( )	 //找出按键代表的值
   {   
       uc cc;
       uc aa=0;
	   key_board=0xf0;
	   if(key_board!=0xf0)
	   {
		   delay(10);		//消除前抖动
	   }
	   
	   if(key_board!=0xf0)	//再次检测
	   {
		     keyflag=1; //表示有按键按下  
			 cc=key_board;	  //记录行地址
	   }
	   key_board=0x0f;
	   cc=cc|key_board;	 //得出地址
	   while((aa<=50)&&(key_board!=0x0f))	//强制退出 
	   {			 delay(10);
					 aa++;
	   }
	     
		  return cc;

	   }
	  	 
		 	 
 void keyfenzhi(uc k)
 {
  
   switch(k){
     
	 case 0xe7:  keyvalue=1; break;

	 case 0xd7:	  keyvalue=2;break;

	 case 0xb7:   keyvalue=3;break;

	 case 0xeb:   keyvalue=4; break;

	 case 0xdb:	  keyvalue=5; break;

	 case 0xbb:	  keyvalue=6; break;

	 case 0xed:	  keyvalue=7; break;

	 case 0xdd:	  keyvalue=8; break;

	 case 0xbd:	  keyvalue=9; break;
	 case 0xee:   keyvalue=0; break;

	 case 0x77:	  keyvalue=10; break; //加法
	
	 case 0x7b:   keyvalue=11; break;// 减法
     
	 case 0x7d:	  keyvalue=12; break;//乘法

	 case 0x7e:	  keyvalue=13; break;//除法

	 case 0xde:	  keyvalue=14; break;//等于

	 case 0xbe:	  keyvalue=15; break;//归零
	 default :break;
   }
   keyflag1=1;
   }
    void K_K(ut yyy)
 {
     duanxuan[0]=yyy%10;
 	 duanxuan[1]=yyy/10%10;
	 duanxuan[2]=yyy/100%10;
	 duanxuan[3]=yyy/1000%10;
     duanxuan[4]=yyy/10000%10;
     duanxuan[5]=yyy/100000%10;
	 duanxuan[6]=yyy/1000000%10;
	 duanxuan[7]=yyy/10000000%10;
 
 }	
void jiafa()   //加法函数
{
 addflag++;  //进行加法 加法标志加1
 subflag=mulflag=divflag=0;
 qpflag=1;	
  if(addflag>1)
  {
	sum1=sum2+sum1;
	

  }
	 
	 sum2=sum1;
}
 void jianfa()	//减法函数
{
 subflag++;  //进行加法加法标志加1
 addflag=mulflag=divflag=0;
 qpflag=1;	
  if(subflag>1)
  {
	 sum1=sum2-sum1;
	

  }

 sum2=sum1;
}
 
 void chengfa()	   //乘法函数
{
 mulflag++;  //进行加法加法标志加1
 addflag=subflag=divflag=0;
 qpflag=1;	
  if(mulflag>1)
  {
	 sum1=sum2*sum1;
	 
  }

	 sum2=sum1;
}
 void chufa()	  //除法函数
{
 divflag++;  //进行加法加法标志加1
 subflag=mulflag=addflag=0;
 qpflag=1;	
  if(divflag>1)
  {
	 sum1=sum2/sum1;
	
  }

	 sum2=sum1;
}

void dengyu()
{


 
   if(addflag)                           
   {
   sum1=sum1+sum2;                    
   }
   if(subflag)
   {
   sum1=sum2-sum1;
   }
   if(mulflag)
   {
   sum1=sum2*sum1;
   }
   if(divflag)
   {
   sum1=sum2/sum1;
   }
   addflag=subflag=mulflag=divflag=0;// 运算完成一次所有标志清零
   K_K(sum1);	qpflag=1;
}





  void shujuyiwei(uc la)
  {	
             uc i;
        for(i=7;i>0;i--)
	 {
		duanxuan[i]=duanxuan[i-1];

	 }
	 	duanxuan[0]=la	;
   }
   
  

void shujuchuli()
{
	if(keyvalue==15)
	{
		 sum1=sum2=0;
		 K_K(sum1);

	}
    if(qpflag==1)
	{
	  sum1=0;
	  qpflag=0;
	  K_K(sum1);

	}

   if(keyvalue<10)
   {
	   	shujuyiwei(keyvalue);
		sum1=sum1*10+keyvalue;
   }


}
 
  void jisuan()
  {	
  
   if(keyflag1)
  { 
     keyflag1=0;
	 switch(keyvalue)
	 {
	  case 10:jiafa();K_K(sum1);break;	// 这里K_K()是在连续加的时候显示出计算结果 	     
	  case 11:jianfa();K_K(sum1);break;
	  case 12:chengfa();K_K(sum1);break;
	  case 13:chufa();K_K(sum1)	;break;
	  case 14:dengyu();break;
	  default:shujuchuli( );						  //其他则是数据
	 }
	 }
	 
  }
 

	          
  void main( )
  {	 
    uc y;
   while(1)
   {    
    y=anjian( ); //返回 按键值
  
	if(y!=0xff)	 //判断是否按键按下
	{
	  keyfenzhi(y);	  //按键对应的值
	 
	}
	 jisuan();
	 kaishi(); //在8位数码管显示数字
}
															
}












  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值