在上一节,我们已经完成了单片机的键盘驱动,现在让我们实现最基础的运算:
+-*/ ^ √,下面是键盘
上面的小字是组合键,目前只有‘+’和第一列组合
程序点我下载
因为计算的数字和运算符是按照字符输入的
保存在了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(&a,str,0); symbol=str[n++]; change(&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>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<8;i++) { write_data_1602(table1[i]); }
因为我们用作显示屏的1602中没有开方的符号,于是我就自定义了一个,1602一共可以定义8个自定义字符,具体可以看1602的资料。
1602的液晶的一个字符是5*8,用来显示平方根的符号也有些勉强,就这样凑合用吧
good!
good,棒棒哒,博主的分享很不错哦