您的位置:首页 > 其它

51单片机基于 Proteus 制作 10 以内加减的计算器

2016-01-25 12:12 357 查看
近来,看到好几个要求用 51 单片机和数码管来设计计算器的题目:

http://zhidao.baidu.com/question/2075214728949956868.html

http://zhidao.baidu.com/question/1894871697092659740.html

……

51 单片机,本质上是微控制器,以逻辑运算见长。
用它来设计计算器 ?
不知道谁想出来的这样的题目,思路明显就是跑偏了,呵呵

特别是后一个的题目,不仅要求能加减乘除,竟然还要求选用数码管来显示。
如果是选用 LCD1602 液晶屏来显示,勉强还算对路。
数码管,只能显示出来减号,让它显示加号、乘号、除号,都是不可能的。

一些网友为这个题目提供了答案,可是没有一个像样的,呵呵
提问者也明显不满意,又反复提问了好几次。

前一个设计计算器的题目,提问者提供了部分程序和电路,要求如下:

老师要求只要3个数码管,完成10以内加减。
第一个数码管表示第1个数字,
第二个数码管表示符号(+或-,用A-F任意表示),
第三个数码管表示第2个数字。
按下等号(等号也用A-F任意表示)三个数码管熄灯,第一个数码管显示答案。

因为提问者给出的资料较多,要求也非常简明,故此做而论道针对这个题目,给出了一个答案。
(另外一个题目,就不回答了。)

做而论道设计的计算器电路,和提问者给定的,稍有不同。

仿真运行后的画面如下:



图片:http://xiangce.baidu.com/picture/detail/3e030be4be33ec2bebcd56569dee061f50d6848d
题目:http://zhidao.baidu.com/question/2075214728949956868.html

这是在输入了 1+8 时的截图,其中的+,数码管显示不出来,只好用【-1】冒充了一下。

做而论道的设计,有几个特点:

1.具有光标显示功能。

在等待用户按键时,光标会在指定的位置上闪动。
当输入一个数字后,光标自动向右移动一位,继续闪烁。

2.选用了计算器的标准键盘。

由于自定义的 4×4 键盘不好看,而且电路复杂,不如用 PROTEUS 带来的标准键盘。
只是这样弄,键盘的编码表就要重新编写了,这也是一般人难以胜任的工作。

3.具有无效键排除功能。

在不同的位置只能输入特定的按键,比如在输入数字时,只能输入0~9,按下其它的按键,
本系统不予理会。
同样,在需要输入等号=时,按下数字键,本系统也不予理会。

4.可以显示大于两位数的结果。

题目仅仅要求显示一位数字的结果。而本系统最大可以显示 18,即 9 + 9 的结果。

5.可以显示负数。

题目对此没有要求。本系统则可以显示负号和绝对值,比如,输入 4 - 9 =,
本系统就能显示出来:-5。

6.可以循环工作。

题目对此也没有要求。本系统则在显示结果之后,再按下 ON/C,即可清除显示屏,重新开始工作。

还有一些有特色的地方,就不多说了,请大家自己发掘。

全部程序如下:

//一位数的加减计算器

#include<reg51.h>

//------------------------------------
char led_mod[] = {
    0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,0x58,0x5e,0x79,0x71,0x46,0x40};
//------------------------------------
char key_buf[] = {
    0xd7,0xeb,0xdb,0xbb, 0xed,0xdd,0xbd,0xee, 
    0xde,0xbe,0xe7,0xb7, 0x77,0x7b,0x7d,0x7e};
//------------------------------------
void delay(char i)
{
    unsigned  char  j, k;
    for(j = i; j > 0; j--)  for(k = 125; k > 0; k--);
}
//------------------------------------
char getKey(void)
{
    char key_scan[] = {0xef, 0xdf, 0xbf, 0x7f};
    char i, j;
    for(i = 0; i < 4; i++){
      P2 = key_scan[i];
      if((P2 & 0x0f) != 0x0f) 
        for(j = 0; j < 16; j++)
          if(key_buf[j] == P2)
            return j;      
    }
    return -1;
}
//------------------------------------
//以上,基本上都是提问者给出的资料
//------------------------------------
char FlashKey(char p, char d)
{
    unsigned  char  i, k;
    while(1) {
      for(i = 100; i > 0; i--)  {
        delay(10);
        k = getKey();
        if (k < 16)  return k;  
      }
      if (p == 0)  P0 = d;
      if (p == 1)  P1 = d;
      if (p == 3)  P3 = d;
      for(i = 100; i > 0; i--)  {
        delay(10);
        k = getKey();
        if (k < 16)  return k;  
      }
      if (p == 0)  P0 = 255;
      if (p == 1)  P1 = 255;
      if (p == 3)  P3 = 255;
    }
}
//------------------------------------
void main(void)
{
    char  key, aa, ff, bb, cc;
    while(1) {
//-------------------------------
      key = FlashKey(0, 0xf7);
      while (key > 9)  key = FlashKey(0, 0xf7);
      P0 = ~led_mod[key]; aa = key; //0~9
      while (getKey() != -1);    //等待释放
//-------------------------------
      key = FlashKey(1, 0xf7);
      while ((key != 12) && (key != 13))  key = FlashKey(1, 0xf7);
      P1 = ~led_mod[key + 4]; ff = key; //加减运算
      while (getKey() != -1);    //等待释放
//-------------------------------
      key = FlashKey(3, 0xf7);
      while (key > 9)  key = FlashKey(3, 0xf7);
      P3 = ~led_mod[key]; bb = key; //0~9
      while (getKey() != -1);    //等待释放
//-------------------------------
      while (getKey() != 11);    //等号
      if(ff == 12)  cc = aa + bb;     //进行计算
      if(ff == 13)  cc = aa - bb;
      P0 = 255;  P1 = 255;  P3 = 255; //清屏
      if   (cc < 0) {P1 = 0xbf;  P3 = ~led_mod[-cc];}
      else if (cc > 9) {P1 = ~led_mod[cc / 10]; P3 = ~led_mod[cc % 10];}
      else  P3 = ~led_mod[cc];
      while (getKey() != -1);    //等待释放
//-------------------------------
      while (getKey() != 10);    //ON/C
      P0 = 255;  P1 = 255;  P3 = 255; //清屏
      while (getKey() != -1);    //等待释放
//-------------------------------
    }
}
//------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: