找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5696|回复: 1
收起左侧

基于C语言的简单计算器的加法程序

[复制链接]
ID:151228 发表于 2016-11-30 15:04 | 显示全部楼层 |阅读模式
做了个简单的计算器练手
单片机计算器仿真原理图:
[TLFM7]3TMQQ}KZT@7@H5@0.png

单片机源程序预览:
  1. #include<reg52.h>

  2. sbit in1 = P2^0;                   //按键P2.0输出
  3. sbit in2 = P2^1;
  4. sbit in3 = P2^2;
  5. sbit in4 = P2^3;

  6. sbit out1 = P2^4;                   //动态行变换
  7. sbit out2 = P2^5;                   //动态行变换
  8. sbit out3 = P2^6;                   //动态行变换
  9. sbit out4 = P2^7;                   //动态行变换

  10. unsigned char code LedChar[]={
  11.         0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  12.         0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  13.         };
  14. unsigned char KeySta[4][4] = {
  15.         {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
  16.         };
  17. unsigned char LedBuff[6] = {
  18.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  19.         };
  20. unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表
  21.     { 0x31, 0x32, 0x33, 0x26 }, //数字键1、数字键2、数字键3、向上键
  22.     { 0x34, 0x35, 0x36, 0x25 }, //数字键4、数字键5、数字键6、向左键
  23.     { 0x37, 0x38, 0x39, 0x28 }, //数字键7、数字键8、数字键9、向下键
  24.     { 0x30, 0x1B, 0x0D, 0x27 }  //数字键0、ESC键、  回车键、 向右键
  25.         };
  26. void  KeyDriver();
  27. void main()
  28. {
  29.     EA = 1;       //使能总中断
  30.     ET0  = 1;     //使能T0中断

  31.     TMOD = 0x01;  //设置T0为模式1
  32.     TH0 = 0xDC;
  33.         TL0 = 0x00;
  34.     TR0  = 1;     //启动T0

  35.         P1=0xFF;

  36.     LedBuff[0] = LedChar[0];  //上电显示0
  37.        
  38.     while (1)
  39.     {
  40.         KeyDriver();   //调用按键驱动函数
  41.     }
  42. }

  43. void ShowNumber(unsigned long num)
  44. {
  45.         signed char i;
  46.         unsigned char buf[6];

  47.         for(i=0; i<6; i++)
  48.         {
  49.                 buf[i] = num % 10;
  50.                 num = num / 10;
  51.         }

  52.         for(i=5; i>=1; i--)
  53.         {
  54.                 if(buf[i] == 0)
  55.                 {
  56.                         LedBuff[i] = 0xFF;
  57.                 }
  58.                 else
  59.                         break;
  60.         }
  61.        
  62.         for(; i>=0; i--)
  63.         {
  64.                 LedBuff[i] = LedChar[buf[i]];       
  65.         }

  66. }
  67. void KeyAction(unsigned char keycode)
  68. {
  69.         static unsigned long result = 0;
  70.         static unsigned long addend = 0;
  71.        
  72.         if((keycode >= 0x30) &&(keycode <= 0x39))
  73.         {
  74.                 addend = (addend *10) + (keycode - 0x30);   
  75.                 ShowNumber(addend);
  76.         }
  77.        
  78.         else if(keycode == 0x26)
  79.         {
  80.                 result += addend;
  81.                 addend = 0;
  82.                 ShowNumber(result);
  83.         }
  84.         else if(keycode == 0x0D)
  85.         {
  86.                 result += addend;
  87.                 addend = 0;
  88.                 ShowNumber(result);
  89.         }
  90.         else if(keycode == 0x1B)
  91.         {
  92.                 addend = 0;
  93.                 result = 0;
  94.                 ShowNumber(addend);        
  95.         }       
  96.          
  97. }
  98. void  KeyDriver()
  99. {
  100.         unsigned char i, j;
  101.         static        unsigned char backup [4][4] = {
  102.         {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
  103.         };

  104.         for(i=0; i<4; i++)
  105.                 {
  106.                         for(j=0; j<4; j++)
  107.                         {
  108.                                 if(backup[i][j] != KeySta[i][j])
  109.                                 {
  110.                                         if(backup[i][j] == 0)
  111.                                         {
  112.                                                 KeyAction(KeyCodeMap[i][j]);
  113.                                         }
  114.                                         backup[i][j] = KeySta[i][j];
  115.                                 }
  116.                         }       
  117.                 }

  118.        
  119. }

  120. /* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */
  121. void KeyScan()
  122. {
  123.     unsigned char i;
  124.     static unsigned char keyout = 0;   //矩阵按键扫描输出索引
  125.     static unsigned char keybuf[4][4] = {  //矩阵按键扫描缓冲区
  126.         {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF},
  127.         {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF}
  128.     };

  129.     //将一行的4个按键值移入缓冲区
  130.     keybuf[keyout][0] = (keybuf[keyout][0] << 1) | in1;
  131.     keybuf[keyout][1] = (keybuf[keyout][1] << 1) | in2;
  132.     keybuf[keyout][2] = (keybuf[keyout][2] << 1) | in3;
  133.     keybuf[keyout][3] = (keybuf[keyout][3] << 1) | in4;
  134.     //消抖后更新按键状态
  135.     for (i=0; i<4; i++)  //每行4个按键,所以循环4次
  136.     {
  137.         if ((keybuf[keyout][i] & 0x0F) == 0x00)
  138.         {   //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
  139.             KeySta[keyout][i] = 0;
  140.         }
  141.         else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
  142.         {   //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
  143.             KeySta[keyout][i] = 1;
  144.         }
  145.     }
  146.     //执行下一次的扫描输出
  147.     keyout++;                //输出索引递增
  148.     keyout = keyout & 0x03;  //索引值加到4即归零
  149.     switch (keyout)          //根据索引,释放当前输出引脚,拉低下次的输出引脚
  150.     {
  151.         case 0: out1 = 0; out2 = 1; out3 = 1;out4 = 1; ; break;         //当我按下第一行的按键,只有keyout==0时符合条件
  152.                 case 1: out1 = 1; out2 = 0; out3 = 1;out4 = 1; ; break;
  153.                 case 2: out1 = 1; out2 = 1; out3 = 0;out4 = 1; ; break;
  154.                 case 3: out1 = 1; out2 = 1; out3 = 1;out4 = 0; ; break;
  155.                 default: break;
  156.     }
  157. }
  158. /* 数码管动态扫描刷新函数,需在定时中断中调用 */
  159. void LedScan()
  160. {
  161.     static unsigned char i = 0;  //动态扫描的索引
  162.    
  163.     P0 = 0xFF;   //显示消隐
  164.     switch (i)
  165.     {
  166.         case 0:P1=0xFE; i++; P0=LedBuff[0];break;
  167.                 case 1:P1=0xFD; i++; P0=LedBuff[1];break;
  168.                 case 2:P1=0xFB; i++; P0=LedBuff[2];break;
  169.                 case 3:P1=0xF7; i++; P0=LedBuff[3];break;
  170.                 case 4:P1=0xEF; i++; P0=LedBuff[4];break;
  171.                 case 5:P1=0xDF; i=0; P0=LedBuff[5];break;
  172.                 default:break;
  173.     }
  174. }

  175. /* T0中断服务函数,用于数码管显示扫描与按键扫描 */
  176. void InterruptTimer0() interrupt 1
  177. {
  178.         TH0 = 0xDC;
  179.         TL0 = 0x00;
  180.         LedScan();
  181.         KeyScan();
  182. }
复制代码

0.png
所有资料打包下载:
简单的计算器加法程序.zip (79.82 KB, 下载次数: 21)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1 发表于 2016-12-3 23:45 | 显示全部楼层
51黑有你更精彩!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表