51单片机实现计算器程序

最近在学习单片机,在学习了动态数码管和矩阵按键后自己突然想实现一个简易的计算器程序。

按键的设置:按顺序设置下来4x4的矩阵按键,前两排设置成数字0-7,第三排按键前两个是数字8,9,后两个是'+'、'-'符号,最后一排是前两个设置成'*'、'/'符号,第三个是'='符号,最后一个暂未设置,可以进行数值较小的数字的运算,后续再慢慢进行优化

定义的变量的说明:数组用于保存按下的数字按键用于数码管动态显示,标志位tag0代表加运算,1代表减运算,2代表乘运算,3代表除运算,临时变量temp默认为0用于保存按下的数字后面用于计算,nexttag用于当按下符号按键后,下一次按下数字按键的话就会对数组进行清空进行第二次数字的输入。

大概思路就是单片机接通电源后,会一直进行检测有没有按键按下,如果有按键按下的话会进行判断,如果检测是按下数字按键的话会保存在一个数组里,temp变量进行*10+数字按键的计算保存按下的数字,如果检测到按下的是符号的话,这时会将临时变量保存到一个新的变量上后面用于运算,并将nexttag置为1,temp置为0,下一次进行数字按键输入的话就会清空数组,进行重新显示第二个数字,最后按下等于号的话就会将此时temp变量存储的值赋给第二个变量,通过判断tag进行对应的运算。

最后是源代码的分享,仅供参考哦,希望各位大神多多指教

#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define GPIO_DIG P0
#define GPIO_KEY P1
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
u8 keyvalue;
u8 keyvalue1;
u8 array[16]={0};
int count=0;
u8 tag;
int temp=0;
int one=0;
int two=0;
int total;
u8 nexttag=0;
void cleararray()
{
	u8 i;
	for(i=0;i<count;i++)
	{
		array[i]=0;
	}
	count=0;
}
void delay(int i)
{
	while(i--);
}
void gettotal()
{
	u8 temp1;
	u8 i;
	u8 temp2;
	while(total)
	{
		temp1=total%10;
		array[count++]=temp1;
		total=total/10;
	}
	for(i=0;i<count/2;i++)
	{
		temp2=array[i];
		array[i]=array[count-1-i];
		array[count-1-i]=temp2;
	}	
}
void KeyDown()
{
	char a=0;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)
	{
		delay(1000);
		if(GPIO_KEY!=0x0f)
		{
			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;
			switch(GPIO_KEY)
			{
				case(0x70):
				{
					if(keyvalue==0)
					{
						keyvalue1=0;	
					}else if(keyvalue==1)
					{
						keyvalue1=1;
					}else if(keyvalue==2)
					{
						keyvalue1=2;
					}else 
					{
						keyvalue1=3;
					}
				}break;
				case(0xb0):
				{
					if(keyvalue==0)
					{
						keyvalue1=4;	
					}else if(keyvalue==1)
					{
						keyvalue1=5;
					}else if(keyvalue==2)
					{
						keyvalue1=6;
					}else 
					{
						keyvalue1=7;
					}
				}break;
				case(0xd0):
				{
					if(keyvalue==0)
					{
						keyvalue1=8;	
					}else if(keyvalue==1)
					{
						keyvalue1=9;
					}else if(keyvalue==2)
					{
						keyvalue1=10;
					}else 
					{
						keyvalue1=11;
					}
				}break;
				case(0xe0):
				{
					if(keyvalue==0)
					{
						keyvalue1=12;	
					}else if(keyvalue==1)
					{
						keyvalue1=13;
					}else if(keyvalue==2)
					{
						keyvalue1=14;
					}else 
					{
						keyvalue1=15;
					}
				}break;
			}
			if(keyvalue1>=0&&keyvalue1<=9)
			{
				if(nexttag==0)
				{
				    array[count++]=	keyvalue1;
					temp=temp*10+keyvalue1;
				}else
				{
					cleararray();
					array[count++]=	keyvalue1;
					temp=temp*10+keyvalue1;
					nexttag=0;	
				}

			}else if(keyvalue1==10)	 //加法
			{
				tag=0;
				one=temp;
				temp=0;
				nexttag=1;
			}else if(keyvalue1==11)	//减法
			{
			   	tag=1;
				one=temp;
				temp=0;
				nexttag=1;
			}else if(keyvalue1==12)	 //乘法
			{
				tag=2;
				one=temp;
				temp=0;
				nexttag=1;
			}else if(keyvalue1==13)	 //除法
			{
				tag=3;
				one=temp;
				temp=0;
				nexttag=1;
			}else if(keyvalue1==14)
			{
				two=temp;
				cleararray();
				switch(tag)
				{
				case 0:
				{
					total=one+two;
					gettotal();
				}
				break;
				case 1:
				{
					total=one-two;
					gettotal();
				}
				break;
				case 2:
				{
					total=one*two;
					gettotal();
				}
				break;
				case 3:
				{
					total=one/two;
					gettotal();
				}
				break;
				}
			}
			while((a<50)&&(GPIO_KEY!=0xf0))
			{
				delay(1000);
				a++;
			}

		}
	}
}
void main()
{
	int i;
	while(1)
	{
		KeyDown();
		for(i=0;i<count;i++)
		{
			switch(i)
			{
			case 0:
				LSA=1;LSB=1;LSC=1;break;
			case 1:
				LSA=0;LSB=1;LSC=1;break;
			case 2:
				LSA=1;LSB=0;LSC=1;break;
			case 3:
				LSA=0;LSB=0;LSC=1;break;
			case 4:
				LSA=1;LSB=1;LSC=0;break;
			case 5:
				LSA=0;LSB=1;LSC=0;break;
			case 6:
				LSA=1;LSB=0;LSC=0;break;
			case 7:
				LSA=0;LSB=0;LSC=0;break;
			}
			GPIO_DIG=smgduan[array[i]];
			delay(100);
			GPIO_DIG=0x00;
		}
		
	}
}

  • 13
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值