找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2586|回复: 0
收起左侧

51单片机4位数加法计算器仿真程序设计

[复制链接]
ID:586643 发表于 2021-5-24 00:16 | 显示全部楼层 |阅读模式
性能指标
4位数加法计算,功能键能清零;超出位数声报警;违规操作声报警光报警提
51hei.gif
加法计算器.png

单片机源程序如下:
  1. #include<reg52.h> //头文件
  2. #include<intrins.h>//头文件
  3. #include<math.h>
  4. #define uint unsigned int //宏定义
  5. #define uchar unsigned char//宏定义
  6. sbit int0=P3^2;          //外部中断0
  7. long x=0,y=0,num=0;                                  //变量
  8. int operators,input,iny=0;                  //变量
  9. char key,k;                                                 //变量
  10. char error[5]="error";
  11. char overflow[8]="overflow";        //变量数组
  12. sbit EN=P2^7;                                //液晶选择,使能信号
  13. sbit R_W=P2^5;                                        //液晶读/写选择端
  14. sbit RS=P2^6;                                        //液晶数据/命令选择端
  15. sbit led=P3^6;                                        //灯
  16. sbit beep=P3^7;                                        //蜂鸣器


  17. void delay(uint xms)  //延时
  18. {
  19.         uint xx,yy;
  20.         for (xx=xms;xx>0;xx--)
  21.                 for(yy=110;yy>0;yy--);
  22. }

  23. /************LCD检查忙碌函数***********/
  24. void check_BF()
  25. {
  26. char i,x=0x80;
  27. P0=0xff;
  28. while(x&0x80)
  29. {
  30. RS=0;
  31. R_W=1;
  32. EN=1;
  33. x=P0;
  34. EN=0;
  35. for (i=0;i<10;i++);
  36. }
  37. EN=0;//关闭使能信号
  38. }       

  39. void write_com(char command)
  40. {               
  41. RS=0;/*写指令*/
  42. R_W=0;                       
  43. EN=1;/*使能信号开*/
  44. P0=command;/*将数据送入p1口*/
  45. EN=0;/*使能信号关*/
  46. check_BF();
  47. }

  48. void write_data(char ddata)         //液晶数据
  49. {       
  50. RS=1;/*写指令*/
  51. R_W=0;                       
  52. EN=1;/*使能信号开*/
  53. P0=ddata;/*将数据送入p0口*/
  54. EN=0;/*使能信号关*/
  55. check_BF();
  56. }
  57. void init_LCM()                  //初始化
  58. {  
  59. write_com(0x30);
  60. write_com(0x30);
  61. write_com(0x30);
  62. write_com(0x38);
  63. write_com(0x08);
  64. write_com(0x01);
  65. write_com(0x06);
  66. write_com(0x0e);  
  67. }

  68. /**********LCD清屏函数**********/
  69. void clearLCD()
  70. {
  71. write_com(0x01);
  72. }

  73. /**********LCD显示函数**********/
  74. void display(long a)
  75. {
  76. long temp,b,c=-1;
  77. int lenth=1,i,j;
  78. clearLCD();
  79. if(a<0)                                                 //计算值小于0
  80. {
  81. a=a*c;
  82. write_data('-');                          //显示负号
  83. }         
  84. temp=a;
  85. while((temp=temp/10)!=0)
  86. {
  87. lenth++;
  88. }
  89. for(i=lenth;i>0;i--)
  90. {
  91. b=1;
  92. for(j=0;j<i-1;j++)
  93. {
  94. b=b*10;
  95. }
  96. write_data(0x30+a/b);
  97. a=a%b;
  98. }
  99. }

  100. /*********数值溢出处理函数**********/
  101. void dataoverflow()                           //结果超出范围
  102. {
  103. int i=0;
  104. clearLCD();
  105. for(i=0;i<8;i++)
  106. write_data(overflow[i]);
  107. }

  108. void dataoverflow1()                        //输入超出范围,违规操作
  109. {
  110. int i=0;
  111. clearLCD();
  112. for(i=0;i<5;i++)
  113. write_data(error[i]);
  114. }



  115. /**********算术运算函数*************/
  116. void arithmetic()
  117. {
  118. if (iny)
  119. {
  120. switch(operators)
  121. {
  122. case 1:                                                  //加法运算
  123. x=x+y;
  124. num=x;
  125. if(num<=9999&&num>=-9999)                //在计算范围内
  126. {
  127. display(num);                                                //液晶显示
  128. }
  129. else
  130. {
  131.   dataoverflow();                                                //超过范围
  132.   led=0;                                                                //指示灯亮
  133. }
  134. break;
  135. }
  136. }        
  137. }

  138. /***********外部中断0处理函数*************/
  139. void INT_0(void) interrupt 0 using 0
  140. {
  141. if(key<=9&&key>=0)      //判断按下的键是否为数值
  142. {
  143. num=num*10+(key-0);
  144. if (operators>0)
  145. {
  146. y=num;
  147. iny=1;
  148. }
  149. else
  150. x=num;
  151. if(num<=9999&&num>=-9999)    //当前数值是否超出限定范围
  152. {       
  153. display(num);
  154. }
  155. else
  156.   {
  157.    dataoverflow1();                //错误提示
  158.    beep=0;                          //报警
  159.   }
  160. }
  161. else
  162. {
  163. switch(key)                                                //按键值判断
  164. {
  165. case 'c':                                                   //删除按键
  166.                         x=0;
  167.                         y=0;
  168.                         num=0;
  169.                         iny=0;
  170.                         operators=0;
  171.                         led=1;
  172.                         beep=1;
  173.                         display(num);
  174.                         break;
  175. case '=':                                                         //等于按键
  176.                         arithmetic();
  177.                         iny=0;
  178.                         operators=0;
  179.                         num=0;
  180.                         break;
  181. case '+':                                                          //加号按键
  182.                     if (operators)
  183.                         arithmetic();
  184.                         operators=1;
  185.                         num=0;
  186.                         break;
  187. }
  188. }
  189. }

  190. void keyscan()                                                 //按键函数
  191. {
  192.   uchar temp;
  193.   P1=0xfe;
  194.   temp=P1;
  195.   temp=temp&0xf0;
  196.   if(temp!=0xf0)                                        //如果按键被按下
  197.   {
  198.     delay(10);                                                //延时消抖
  199.         temp=P1;
  200.     temp=temp&0xf0;
  201.         if(temp!=0xf0)
  202.         {
  203.           temp=P1;
  204.           switch(temp)
  205.           {
  206.             case 0xee:
  207.                      key='+';                                   //加
  208.                      break;
  209.           }
  210.           int0=0;                                //外部中断0电平触发
  211.           while(temp!=0xf0)
  212.           {
  213.         temp=P1;
  214.         temp=temp&0xf0;
  215.           }
  216.           int0=1;

  217.         }
  218.   }
  219.   P1=0xfd;
  220.   temp=P1;
  221.   temp=temp&0xf0;
  222.   if(temp!=0xf0)
  223.   {
  224.     delay(10);
  225.         temp=P1;
  226.     temp=temp&0xf0;
  227.         if(temp!=0xf0)
  228.         {
  229.           temp=P1;
  230.           switch(temp)
  231.           {
  232.             case 0xed:
  233.                      key='=';                                        //等于
  234.                      break;
  235.             case 0xdd:
  236.                      key=3;                                                //3
  237.                      break;
  238.             case 0xbd:                                           //6
  239.                      key=6;
  240.                      break;
  241.             case 0x7d:
  242.                      key=9;
  243.                      break;
  244.           }
  245.           int0=0;
  246.           while(temp!=0xf0)
  247.           {
  248.         temp=P1;
  249.         temp=temp&0xf0;
  250.           }
  251.                           int0=1;
  252.         }
  253.   }
  254.   P1=0xfb;
  255.   temp=P1;
  256.   temp=temp&0xf0;
  257.   if(temp!=0xf0)
  258.   {
  259.     delay(10);
  260.         temp=P1;
  261.     temp=temp&0xf0;
  262.         if(temp!=0xf0)
  263.         {
  264.           temp=P1;
  265.           switch(temp)
  266.           {
  267.             case 0xeb:
  268.                      key=0;
  269.                      break;
  270.             case 0xdb:
  271.                      key=2;
  272.                      break;
  273.             case 0xbb:
  274.                      key=5;
  275.                      break;
  276.             case 0x7b:
  277.                      key=8;
  278.                      break;
  279.           }
  280.                     int0=0;
  281.           while(temp!=0xf0)
  282.           {
  283.         temp=P1;
  284.                 int0=0;
  285.         temp=temp&0xf0;
  286.           }
  287.                           int0=1;

  288.         }
  289.   }
  290.   P1=0xf7;
  291.   temp=P1;
  292.   temp=temp&0xf0;
  293.   if(temp!=0xf0)
  294.   {
  295.     delay(10);
  296.         temp=P1;
  297.     temp=temp&0xf0;
  298.         if(temp!=0xf0)
  299.         {
  300.           temp=P1;
  301.           switch(temp)
  302.           {
  303.             case 0xe7:
  304.                      key='c';
  305.                      break;
  306.             case 0xd7:
  307.                      key=1;
  308.                      break;
  309.             case 0xb7:
  310.                      key=4;
  311.                      break;
  312.             case 0x77:
  313.                      key=7;
  314.                      break;
  315.           }
  316.           int0=0;
  317.           while(temp!=0xf0)
  318.           {
  319.         temp=P1;
  320.         temp=temp&0xf0;
  321.           }
  322.                   int0=1;

  323.         }
  324.   }
  325. }

  326. void main()                                                 //主函数
  327. {
  328. EA=1;                                                          //打开总中断
  329. EX0=1;                                                           //外部中断
  330. IT0=1;
  331. P1=0xff;
  332. display(0);
  333. init_LCM();
  334. write_data(0x30);

  335. while(1)                                                  //大循环
  336.                 {
  337.                   keyscan();                          //按键函数
  338.                 }
  339. }
复制代码

所有资料51hei提供下载:
加法计算器.zip (102.52 KB, 下载次数: 28)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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