基于51单片机的计算器 v0.3 基本运算的实现

By | 2014年8月22日

在上一节,我们已经完成了单片机的键盘驱动,现在让我们实现最基础的运算:

+-*/ ^ √,下面是键盘

上面的小字是组合键,目前只有‘+’和第一列组合

程序点我下载

因为计算的数字和运算符是按照字符输入的

保存在了str这个字符数组中,所以我们在计算前需要先把数字和运算符都提取出来。其实有相关的转换函数,但是无法达到我的要求,于是我就写了一个change函数

[/c]uchar change(float *number ,char *str,uchar n)
{
uchar a=1;
for(;str[n]>=’0’&&str[n]<=’9′;n++)
{
*number=*number*10+str[n]-‘0′;
}
if(str[n]==’.’)
{
for(n++;str[n]>=’0’&&str[n]<=’9′;n++,a++)
*number=*number+(str[n]-‘0’)/pow(10,a);
}
return n;
}
[/c]

第一个for把小数点前的数字提取出来,第二个for处理小数点后的数据
数字转换完了,就该应该开始处理计算了

void calculate(uchar *str)
{
	char symbol;
	uchar n;
	float a=0,b=0;
	n=change(&amp;a,str,0);
	symbol=str[n++];
	change(&amp;b,str,n);
	switch(symbol)
	{//为了省一个float变量的空间,这里用a保存计算结果
		case '+':a+=b;break;
		case '-':a-=b;break;
		case '*':a*=b;break;				
		case '/':	
		if(b==0)            //不能除0
		symbol=-1;
		else
		a/=b;
		break;
		
			
		case  1 :			//开方
		if(a&gt;0)
		a=pow(b,1/a);
		else if(a==0)
		a=1;
		else
		symbol=-1;	
		break;

		case '^':a=pow(a,b);break;
		case '%':a=(int)a%(int)b;break;

		case '=':break;
	default:symbol=-1;//symbol这里用于保存计算的错误信息,负数代表出错
	}
	if(symbol==-1)
	sprintf(str,"syntax error");
	else 
	sprintf(str,"%g",a);
}

为了省内存,变量a最后用来保存结果

这个函数的逻辑并不复杂,这里也就不多讲了

有一点要说的是,在开始计算前,有这么一段

write_order_1602(0x48);
for(i=0;i&lt;8;i++)
{
write_data_1602(table1[i]);
}

因为我们用作显示屏的1602中没有开方的符号,于是我就自定义了一个,1602一共可以定义8个自定义字符,具体可以看1602的资料。

1602的液晶的一个字符是5*8,用来显示平方根的符号也有些勉强,就这样凑合用吧

IMAG0097

 

IMAG0101

IMAG0100

IMAG0098

IMAG0102

 

2 thoughts on “基于51单片机的计算器 v0.3 基本运算的实现

发表评论

邮箱地址不会被公开。 必填项已用*标注