admin管理员组

文章数量:1794759

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

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

基于单片机(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; }
  • c.biancheng/view/142.html 可以参考这个网址。
  • 显示要将数倒过来显示,正好可以从右向左。 部分效果如图: 八进制转十六进制 八进制转二进制 十六进制转十进制 这样进制转换问题就基本解决完了。
  • 同一进制之间加减乘

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

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

    效果如图所示: 十六进制减 二进制加

    最后附上完整的项目文件。自行下载。 download.csdn/download/weixin_42320020/16593760

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


    大家有想法可以私信或者留言,博主有时间会帮大家做一些项目。

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

    本文标签: 单片机计算器