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

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();
	}

}
  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值