基于单片机(AT89C51)的进制转换及进制计算器

基于单片机(AT89C51)的进制转换及进制计算器

闲来无事,用手头51单片机做个进制计算器

成品功能:能实现十进制带负数、带小数点的加减乘除,不同进制之间的转换,同一进制之间的加减乘。


材料

  • AT89C51开发板要带4x4矩阵按键,再带8个独立按键才够用
  • 用LCD18650显示
  • 杜邦线
  • 用keil4进行开发

开始制作。

制作过程

思考过程

首先要考虑的就是按键数量了:

  1. 十进制的加减乘除带符号和小数需要:0~9十个按键 + 加减乘除四个按键 + 加小数点符号两个按键 = 共16个按键。
  2. 不同进制之间转换需要:0~F十六个按键 + 2 8 10 16进制四个按键 = 共20个按键
  3. 进制之间加减乘需要:0~F十六个按键 + 2 8 10 16进制四个按键+ 加减乘三个按键 = 共23个按键
    这些还不算上回撤键和模式选择等按键。所以设计的时候必须考虑好按键。

我就得出来如下方案:

  1. 用独立按键做为模式选择:三个按键,选择模式之后不能返回,如果要返回可以用复位键。这样几个功能之间相互不联系,没有影响,按键就够用了。
  2. 然后十进制的加减乘除带符号和小数:用4x4按键做出来键盘既789+ 456- 123* 退格0=/ 用两个独立按键做小数点和符号按键。
  3. 不同进制之间转换:4x4按键做0~F既0123 4567 89AB CDEF,独立按键四个做进制选择既 2 8 10 16进制。
  4. 进制之间加减乘 :4x4按键做0~F既0123 4567 89AB CDEF,独立按键四个做进制选择既 2 8 10 16进制,独立按键四个做加减乘。

硬件部分

直接放图基于单片机(AT89C51)的进制转换及进制计算器_第1张图片
如图所示连接P1接矩阵按键,P3接独立按键。

十进制的加减乘除带符号和小数

这里矩阵按键和独立按键怎么测值就不说了。

整数部分的加减乘除

  1. 将输入的数字连接起来,比如输入5、6,要连接成五十六,方法就是输入5存起来,再输入6,将存起来的数乘10再加上6存起来既五十加六,再输入7,再将存起来的数乘10再加上7存起来既五百六十加七。这样就将数字串起来了。
  2. 按符号之前和按符号之后分别存到不同的变量中。
  3. 当你按下等号之后,再去区别按下的符号是什么,让两次存的数做运算。

代码如下:

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);						
}

这里直接显示运算结果,就避免了运算过程中产生的小数(两数相除)等数据类型问题。

负数问题

  1. 负数问题分情况来分析
  2. 如果两个数相加,都是负号的话结果也有负号,都没有负号的话结果也没有负号;一正一负的话哪个数大结结果的符号就是哪个。
  3. 两个数相减类似两个数相加。
  4. 两个数相乘,看有奇数个还是偶数个负号,奇数个的话结果是负数,偶数个的话结果是正数。
  5. 两数相除类似两数相乘。

小数问题

有小数点的话,我解决的方法是按完小数点之后记录小数点之后有几位,计算结果之前,让存起来的数乘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);}

部分效果如图。
基于单片机(AT89C51)的进制转换及进制计算器_第2张图片
基于单片机(AT89C51)的进制转换及进制计算器_第3张图片
这样十进制的加减乘除带符号和小数的问题就基本解决完了。

进制转换

思想

  1. 先将输入的数转换成十进制存起来。
  2. 然后再按照要求输出不同进制的数。
  3. 不同进制转10进制按权取数,比如:八进制的76,既6x8^0 +7x8^1 = 62。
    例如二进制的代码:fhao_a = fhao_a*2 + k;
  4. 10进制转不同进制除进制取余,比如:十进制62转八进制,62除8=7余数6,7除8=0余7,结果反过来写就是76。
    例如二进制的代码:
    while(biao!=0) //一位一位显示
    {
    lcdwrd(0x30+biao%2);
    biao=biao/2;
    }
  5. http://c.biancheng.net/view/142.html 可以参考这个网址。
  6. 显示要将数倒过来显示,正好可以从右向左。
    部分效果如图:
    八进制转十六进制
    基于单片机(AT89C51)的进制转换及进制计算器_第4张图片
    八进制转二进制
    基于单片机(AT89C51)的进制转换及进制计算器_第5张图片
    十六进制转十进制
    基于单片机(AT89C51)的进制转换及进制计算器_第6张图片
    这样进制转换问题就基本解决完了。

同一进制之间加减乘

为啥不做除呐,因为按键不够。一除就会出现小数,没想明白怎么表示。

思想还是以十进制保存,然后再做运算,再转化为相应进制的数输出。按键不够用所以没法做不同进制之间的运算。

效果如图所示:
十六进制减
基于单片机(AT89C51)的进制转换及进制计算器_第7张图片
二进制加
基于单片机(AT89C51)的进制转换及进制计算器_第8张图片

最后附上完整的项目文件。自行下载。

这个项目到这里就算完了。
还有很多不足的地方,希望大佬可以指正。也希望和爱好者交流学习。

禁止转载!!!
QQ:2039723308
VX:Shiboven

你可能感兴趣的:(单片机,c++,进制计算器,单片机,计算器,进制转换)