基于STC89C51的计算器的实现

基于STC89C51的计算器的实现

实验器件:STC89C51单片机一个,lcd1602显示屏一个,杜邦线若干

话不多说直接上图

proteus仿真图如下:
在这里插入图片描述依据仿真图实现的实物图如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述看完效果图,接下来就是项目源代码

#include<reg51.h>

#define uchar unsigned char
#define uint unsigned int

uchar code table[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};
uchar code table1[]={7,8,9,0x2f-0x30,4,5,6,0x2a-0x30,1,2,3,0x2d-0x30,0x01,0,0x3d-0x30,0x2b-0x30};
uchar code table2[]="Prog is written ";
uchar code table3[]="by dx171-djw&cyl";
uchar table4[16];

char i,j,temp,num;
long a,b,c,d;
uchar flag,fuhao,fuhao_next,k,x,y,m,n;

sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;

void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}

void write_com(uchar com)
{
	RS=0;
	EN=0;
	P0=com;
	delay(1);
	EN=1;
	delay(1);
	EN=0;
}

void write_data(uchar da)
{
	RS=1;
	EN=0;
	P0=da;
	delay(1);
	EN=1;
	delay(1);
	EN=0;
}

void init()
{
	uchar num;
	num=-1;
	RW=0;
	EN=0;
	write_com(0x38);
	write_com(0x0c);
	write_com(0x06);
	write_com(0x01);
	for(num=0;num<16;num++)
	{
		write_data(table2[num]);
		delay(5);
	}
	write_com(0x80+0x40);
	for(num=0;num<16;num++)
	{
		write_data(table3[num]);
		delay(5);
	}
	delay(5000);
	write_com(0x01);
	i=0;
	j=0;
	a=0;
	b=0;
	c=0;
	d=0;
	flag=0;
	fuhao=0;
	fuhao_next=0;
	m=0;
	n=0;
	x=0;
	y=0;
}

void keyscan()
{
	P3=0xfe;								//扫描
	if(P3!=0xfe)
	{
		delay(10);							//延时,去除按键抖动
		if(P3!=0xfe)
		{
			temp=P3&0xf0;
			switch(temp)					//判断按键
			{
				case 0xe0:num=0; break;		//"7"
				case 0xd0:num=1; break;		//"8"
				case 0xb0:num=2; break;		//"9"
				case 0x70:num=3; break;		//"÷"
			}
		}
		while(P3!=0xfe);
		if(num==0|num==1|num==2)			//数字
		{
			if(j==1)						//计算完成(按过"="号)
			{
				write_com(0x01);			//清屏
				j=0;						//等号标志位清零
			}
			if(flag==0)						//没有按过符号
			{
				a=a*10+table[num];			//连续存储数字
				m=1;						//数字输入数量+1
			}
			else if(flag==1)				//按过一次符号
			{
				b=b*10+table[num];
				if(m>=n)					//当符号和数字数量比正确时
					m=2;					//数字输入数量+1
				else
					m=0;					//否则清零,
			}
			else if(flag==2)				//按过两次符号
			{
				c=c*10+table[num];
				if(m>=n)						
					m=3;					//数字输入数量+1
				else
					m=0;						
			}
		}
		else								//符号
		{
			if(j==1)						//
			{
				write_com(0x01);			//
				j=0;						//
			}
			flag++;							//每按一次符号,符号标志位+1
			n++;							//每按一次符号,符号比较标志位+1
			if(flag==1)						//第一次按符号
				fuhao=4;					//符号计算标志位1等于每个符号的对应数字(1"+" 2"-" 3"×" 4"÷")
			if(flag==2)						//第二次按符号
				fuhao_next=4;				//符号计算标志位2同样赋值
		}
		i=table1[num];						//把数组中键盘输入对应的值赋给i
		write_data(0x30+i);					//打印键盘输入的数字或符号
	}
	P3=0xfd;
	if(P3!=0xfd)
	{
		delay(10);
		if(P3!=0xfd)
		{
			temp=P3&0xf0;
			switch(temp)
			{
				case 0xe0:num=4; break;
				case 0xd0:num=5; break;
				case 0xb0:num=6; break;
				case 0x70:num=7; break;
			}
		}
		while(P3!=0xfd);
		if(num==4|num==5|num==6)
		{
			if(j==1)
			{
				write_com(0x01);
				j=0;
			}
			if(flag==0)
			{
				a=a*10+table[num];
				m=1;
			}
			else if(flag==1)
			{
				b=b*10+table[num];
				if(m>=n)
					m=2;
				else
					m=0;
			}
			else if(flag==2)
			{
				c=c*10+table[num];
				if(m>=n)
					m=3;
				else
					m=0;
			}
		}
		else
		{
			if(j==1)
			{
				write_com(0x01);
				j=0;
			}
			flag++;
			n++;
			if(flag==1)
				fuhao=3;
			if(flag==2)
				fuhao_next=3;
		}
		i=table1[num];
		write_data(0x30+i);
	}
	P3=0xfb;
	if(P3!=0xfb)
	{
		delay(10);
		if(P3!=0xfb)
		{
			temp=P3&0xf0;
			switch(temp)
			{
				case 0xe0:num=8; break;
				case 0xd0:num=9; break;
				case 0xb0:num=10; break;
				case 0x70:num=11; break;
			}
		}
		while(P3!=0xfb);
		if(num==8|num==9|num==10)
		{
			if(j==1)
			{
				write_com(0x01);
				j=0;
			}
			if(flag==0)
			{
				a=a*10+table[num];
				m=1;
			}
			else if(flag==1)
			{
				b=b*10+table[num];
				if(m>=n)
					m=2;
				else
					m=0;
			}
			else if(flag==2)
			{
				c=c*10+table[num];
				if(m>=n)
					m=3;
				else
					m=0;
			}
		}
		else
		{
			if(j==1)
			{
				write_com(0x01);
				j=0;
			}
			flag++;
			n++;
			if(flag==1)
				fuhao=2;
			if(flag==2)
				fuhao_next=2;
		}
		i=table1[num];
		write_data(0x30+i);
	}
	P3=0xf7;
	if(P3!=0xf7)
	{
		delay(10);
		if(P3!=0xf7)
		{
			temp=P3&0xf0;
			switch(temp)
			{
				case 0xe0:num=12; break;
				case 0xd0:num=13; break;
				case 0xb0:num=14; break;
				case 0x70:num=15; break;
			}
		}
		while(P3!=0xf7);
		switch(num)
		{
			case 12:
			{
				write_com(0x01);
				a=0;
				b=0;
				c=0;
				flag=0;
				fuhao=0;
				fuhao_next=0;
				k=0;
				x=0;
				y=0;
				m=0;
				n=0;
			}
			break;
			case 13:
			{
				if(j==1)
				{
					write_com(0x01);
					j=0;
				}
				if(flag==0)
				{
					a=a*10;
					write_data(0x30);
					m=1;
				}
				if(flag==1)
				{
					b=b*10;
					write_data(0x30);
					if(m>=n)
						m=2;
					else
						m=0;
				}
				if(flag==2)
				{
					c=c*10;
					write_data(0x30);
					if(m>=n)
						m=3;
					else
						m=0;
				}
			}
			break;
			case 14:
			{
				j=1;		//等号标志位置1
				if(m<=n)	//当数字数量少于或等于符号时,做出错误提示
				{
					write_com(0x01);  		//清屏
					write_com(0x80+0x4f);	//移动到LCD1602第二行末尾
					write_com(0x04);		//倒序书写
					write_data('!');write_data('R');write_data('O');	//显示ERROR!
					write_data('R');write_data('R');write_data('E');	//
					a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;	//所有变量及标志位清零
				}
				if(fuhao==1)
				{
					write_com(0x80+0x4f);
					write_com(0x04);
					if(((fuhao_next==4)&&(c==0))==0)
					{
						d=a+b;
						if(fuhao_next==1)
							d=a+b+c;
						else if(fuhao_next==2)
						{
							if(a+b-c>=0)
								d=a+b-c;
							else
							{
								d=c-a-b;
								k=1;
							}
						}
						else if(fuhao_next==3)
							d=a+b*c;
						else if(fuhao_next==4)
						{
							i=0;
							d=(long)((a+(float)b/c)*1000);
							if((long float)d/1000<1&(long float)d/1000>0)
								y=1;
						}
						if(d==0|y==1)
							x=1;
						while(d!=0)
						{
							write_data(0x30+d%10);
							d=d/10;
							if(fuhao_next==4)
							{
								i++;
								if(i==3)
									write_data(0x2e);
							}
						}
						if(x)
							write_data(0x30);
						if(k)
							write_data(0x2d);
						write_data(0x3d);
						a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;
					}
					else
					{
						write_com(0x01);
						write_com(0x80+0x4f);
						write_com(0x04);
						write_data('!');write_data('R');write_data('O');
						write_data('R');write_data('R');write_data('E');
						a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;
					}
				}
				else if(fuhao==2)
				{
					write_com(0x80+0x4f);
					write_com(0x04);
					if(((fuhao_next==4)&&(c==0))==0)
					{
						if(a-b>=0)
							d=a-b;
						else
						{
							d=b-a;
							k=1;
						}
						if(fuhao_next==1)
						{
							k=0;
							if(a-b+c>=0)
								d=a-b+c;
							else
							{
								d=b-a-c;
								k=1;
							}
						}
						else if(fuhao_next==2)
						{
							k=0;
							if(a-b-c>=0)
								d=a-b-c;
							else
							{
								d=b+c-a;
								k=1;
							}
						}
						else if(fuhao_next==3)
						{
							k=0;
							if(a-b*c>=0)
								d=a-b*c;
							else
							{	
								d=b*c-a;
								k=1;
							}
						}
						else if(fuhao_next==4)
						{
							k=0;
							i=0;
							if((long)((a-(float)b/c)*1000)>=0)
								d=(long)((a-(float)b/c)*1000);
							else
							{
								d=(long)(((float)b/c-a)*1000);
								k=1;
							}
							if((long float)d/1000<1&(long float)d/1000>0)
								y=1;
						}
						if(d==0|y==1)
							x=1;
						while(d!=0)
						{
							write_data(0x30+d%10);
							d=d/10;
							if(fuhao_next==4)
							{
								i++;
								if(i==3)
									write_data(0x2e);
							}
						}
						if(x)
							write_data(0x30);
						if(k)
							write_data(0x2d);
						write_data(0x3d);
						a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;
					}
					else
					{
						write_com(0x01);
						write_com(0x80+0x4f);
						write_com(0x04);
						write_data('!');write_data('R');write_data('O');
						write_data('R');write_data('R');write_data('E');
						a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;
					}
				}
				else if(fuhao==3)
				{
					write_com(0x80+0x4f);
					write_com(0x04);
					if(((fuhao_next==4)&&(c==0))==0)
					{
						d=a*b;
						if(fuhao_next==1)
							d=a*b+c;
						else if(fuhao_next==2)
						{
							if(a*b-c>=0)
								d=a*b-c;
							else
							{
								d=c-a*b;
								k=1;
							}
						}
						else if(fuhao_next==3)
							d=a*b*c;
						else if(fuhao_next==4)
						{
							i=0;
							d=(long)(((float)a*b/c)*1000);
							if((long float)d/1000<1&(long float)d/1000>0)
								y=1;
						}
						if(d==0|y==1)
							x=1;
						while(d!=0)
						{
							write_data(0x30+d%10);
							d=d/10;
							if(fuhao_next==4)
							{
								i++;
								if(i==3)
									write_data(0x2e);
							}
						}
						if(x)
							write_data(0x30);
						if(k)
							write_data(0x2d);
						write_data(0x3d);
						a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;
					}
					else
					{
						write_com(0x01);
						write_com(0x80+0x4f);
						write_com(0x04);
						write_data('!');write_data('R');write_data('O');
						write_data('R');write_data('R');write_data('E');
						a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;
					}
				}
				else if(fuhao==4)								//当第一个符号为除号时
				{
					write_com(0x80+0x4f);						//移动到LCD1602第二行末尾
					write_com(0x04);							//倒序书写
					if(b!=0&(((fuhao_next==4)&&(c==0))==0))		//当第二个数不为0,且不同时满足第二个符号为除号和第三个数为0时
					{
						i=0;									//小数点保留变量
						d=(long)(((float)a/b)*1000);			//先将小数点后三位取整
						if(fuhao_next==1)						//第二个符号为加号
							d=(long)(((float)a/b+c)*1000);
						else if(fuhao_next==2)					//第二个符号为减号
						{
							if((long)(((float)a/b-c)*1000)>=0)	//差为正
								d=(long)(((float)a/b-c)*1000);
							else								//差为负
							{
								d=(long)((c-(float)a/b)*1000);
								k=1;							//符号标志位置1
							}
						}
						else if(fuhao_next==3)					//第二个符号为乘号
							d=(long)(((float)a/b*c)*1000);
						else if(fuhao_next==4)					//第二个符号为除号
							d=(long)(((float)a/b/c)*1000);
						if(d==0|(long float)d/1000<1)			//如果运算结果为0或者在0和1之间
							x=1;								//0显示标志位置1
						while(d!=0)								//运算结果不为0
						{
							write_data(0x30+d%10);				//从小数点最后一位倒序书写
							d=d/10;								//
							i++;
							if(i==3)							//保留3位
								write_data(0x2e);				//书写小数点
						}
						if(x)									//输出0
							write_data(0x30);
						if(k)									//输出负号
							write_data(0x2d);
						write_data(0x3d);						//输出"="
						a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;	//所以变量及标志位清零
					}
					else										//错误提示
					{
						write_com(0x01);
						write_com(0x80+0x4f);
						write_com(0x04);
						write_data('!');write_data('R');write_data('O');
						write_data('R');write_data('R');write_data('E');
						a=0;b=0;c=0;flag=0;fuhao=0,fuhao_next=0,k=0,x=0,y=0,m=0,n=0;
					}
				}

			}
			break;
			case 15:
			{
				if(j==1)
				{
					write_com(0x01);
					j=0;
				}
				flag++;
				n++;
				if(flag==1)
					fuhao=1;
				if(flag==2)
					fuhao_next=1;
				write_data(0x30+table1[num]);
			}
			break;
		}
	}
}

main()
{
	init();
	while(1)
	{
		keyscan();
	}
}
  • 2
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值