基于单片机(AT89C51)的进制转换及进制计算器
闲来无事,用手头51单片机做个进制计算器
成品功能:能实现十进制带负数、带小数点的加减乘除,不同进制之间的转换,同一进制之间的加减乘。
材料
- AT89C51开发板要带4x4矩阵按键,再带8个独立按键才够用
- 用LCD18650显示
- 杜邦线
- 用keil4进行开发
开始制作。
制作过程
思考过程
首先要考虑的就是按键数量了:
- 十进制的加减乘除带符号和小数需要:0~9十个按键 + 加减乘除四个按键 + 加小数点符号两个按键 = 共16个按键。
- 不同进制之间转换需要:0~F十六个按键 + 2 8 10 16进制四个按键 = 共20个按键
- 进制之间加减乘需要:0~F十六个按键 + 2 8 10 16进制四个按键+ 加减乘三个按键 = 共23个按键
这些还不算上回撤键和模式选择等按键。所以设计的时候必须考虑好按键。
我就得出来如下方案:
- 用独立按键做为模式选择:三个按键,选择模式之后不能返回,如果要返回可以用复位键。这样几个功能之间相互不联系,没有影响,按键就够用了。
- 然后十进制的加减乘除带符号和小数:用4x4按键做出来键盘既789+ 456- 123* 退格0=/ 用两个独立按键做小数点和符号按键。
- 不同进制之间转换:4x4按键做0~F既0123 4567 89AB CDEF,独立按键四个做进制选择既 2 8 10 16进制。
- 进制之间加减乘 :4x4按键做0~F既0123 4567 89AB CDEF,独立按键四个做进制选择既 2 8 10 16进制,独立按键四个做加减乘。
硬件部分
直接放图
如图所示连接P1接矩阵按键,P3接独立按键。
十进制的加减乘除带符号和小数
这里矩阵按键和独立按键怎么测值就不说了。
整数部分的加减乘除
- 将输入的数字连接起来,比如输入5、6,要连接成五十六,方法就是输入5存起来,再输入6,将存起来的数乘10再加上6存起来既五十加六,再输入7,再将存起来的数乘10再加上7存起来既五百六十加七。这样就将数字串起来了。
- 按符号之前和按符号之后分别存到不同的变量中。
- 当你按下等号之后,再去区别按下的符号是什么,让两次存的数做运算。
代码如下:
if(fuhao==1)//加
{
sprintf(Disp,"%-6.3f",a_l+b_l); //将结果存在数组中方便显示
//spintf将右边的字符串到左边数组中
//%-6.3f为占位符既(1)表示靠左6位保留三位小数的浮点数
lcdwrd_string(Disp,6); //显示
}
if(fuhao==2)//减
{
sprintf(Disp,"%-6.3f",a_l-b_l);
lcdwrd_string(Disp,6);
}
if(fuhao==3)//乘
{
sprintf(Disp,"%-9.4f",a_l*b_l);
lcdwrd_string(Disp,9);
}
if(fuhao==4)//除
{
sprintf(Disp,"%-9.4f",a_l/b_l);
lcdwrd_string(Disp,9);
}
这里直接显示运算结果,就避免了运算过程中产生的小数(两数相除)等数据类型问题。
负数问题
- 负数问题分情况来分析
- 如果两个数相加,都是负号的话结果也有负号,都没有负号的话结果也没有负号;一正一负的话哪个数大结结果的符号就是哪个。
- 两个数相减类似两个数相加。
- 两个数相乘,看有奇数个还是偶数个负号,奇数个的话结果是负数,偶数个的话结果是正数。
- 两数相除类似两数相乘。
小数问题
有小数点的话,我解决的方法是按完小数点之后记录小数点之后有几位,计算结果之前,让存起来的数乘0.1的多少次方。比如输入的3.1415,小数点之后有四位,存起来的数就是31415再四个0.1。
代码如下:
if(fhao_a==1){a_l = a*pow(0.1,a_wei)*(-1);} //将结果保存到double精度的数中
//有几位小数的话要乘0.1的几次方
//负数的话要成-1
else {a_l = a*pow(0.1,a_wei);}
if(fhao_b==1){b_l = b*pow(0.1,b_wei)*(-1);}
else {b_l = b*pow(0.1,b_wei);}
部分效果如图。
这样十进制的加减乘除带符号和小数的问题就基本解决完了。
进制转换
思想
- 先将输入的数转换成十进制存起来。
- 然后再按照要求输出不同进制的数。
- 不同进制转10进制按权取数,比如:八进制的76,既6x8^0 +7x8^1 = 62。
例如二进制的代码:fhao_a = fhao_a*2 + k;
- 10进制转不同进制除进制取余,比如:十进制62转八进制,62除8=7余数6,7除8=0余7,结果反过来写就是76。
例如二进制的代码:while(biao!=0) //一位一位显示
{
lcdwrd(0x30+biao%2);
biao=biao/2;
}
- http://c.biancheng.net/view/142.html 可以参考这个网址。
- 显示要将数倒过来显示,正好可以从右向左。
部分效果如图:
八进制转十六进制
八进制转二进制
十六进制转十进制
这样进制转换问题就基本解决完了。
同一进制之间加减乘
为啥不做除呐,因为按键不够。一除就会出现小数,没想明白怎么表示。
思想还是以十进制保存,然后再做运算,再转化为相应进制的数输出。按键不够用所以没法做不同进制之间的运算。
效果如图所示:
十六进制减
二进制加
最后附上完整的项目文件。自行下载。
这个项目到这里就算完了。
还有很多不足的地方,希望大佬可以指正。也希望和爱好者交流学习。
禁止转载!!!
QQ:2039723308
VX:Shiboven