久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 15494|回復: 23
打印 上一主題 下一主題
收起左側

基于89c52的簡易計算器設計(仿真與源程序)

  [復制鏈接]
跳轉到指定樓層
樓主
最近在學習單片機,把自己的資料分享給有需要的童鞋。




源碼:(部分預覽 完整代碼請下載附件): 計算器設計.7z (384.54 KB, 下載次數: 410)
  1. #include<reg52.h>
  2. #include<math.h>
  3. #include "lcd1602_8.h"
  4. uint temp,num;//鍵盤掃描數值
  5. uchar keynum1=0,keynum2=0,sign=0,i=0,j=0; //按鍵計數,符號標示
  6. uchar num1[8]={0},num2[8]={0};         //按鍵存儲數組
  7. float ans1=0,ans2=0,ans=0,point=0; //運算數據
  8. bit conflag=0;         //繼續運算標志位
  9. bit newcalc=0;        //新運算標志
  10. bit ac=0;                //清零標志,1為清零
  11. bit beepflag=0;         //蜂鳴器標志位
  12. bit sqrtflag1=0;        //開方1標志位
  13. bit sqrtflag2=0;        //開方2標志位
  14. bit        powflag=0;
  15. sbit keybeep=P3^3;//蜂鳴器開關按鍵
  16. sbit beep=P2^3;         //蜂鳴器控制口
  17. sbit keysqrt=P3^4;//開方按鍵
  18. sbit keypow=P3^5;//任意次方按鍵
  19. uchar keyscan();
  20. void maininit(void);
  21. /****主程序***/
  22. void main(void)
  23. {
  24.         maininit();//初始化
  25.         while(1)        //整個系統大循環,讓計算器一直處于工作狀態
  26.         {
  27.                 while(1)        //第一運算數掃描
  28.                 {
  29.                         if(ac==1)
  30.                                 break;         //若清零,則退出輸入
  31.                         if((keyscan()!='N')&&((num>=0&&num<=9)||num=='.')) //記錄按下的數字
  32.                         {
  33.                                 if(newcalc==1)          //新一次運算開始
  34.                                 {
  35.                                         lcdwrite_com(0x01);//清屏
  36.                                         newcalc=0;
  37.                                         lcd_setxy(0,0);
  38.                                 }
  39.                                 if(keynum1<=7)           //限制輸入位數
  40.                                 {                        
  41.                                         if(num=='.')
  42.                                         {        
  43.                                                 lcdwrite_data('.');        //顯示小數點
  44.                                         }
  45.                                         else
  46.                                                 lcdwrite_num1(num);
  47.                                         num1[keynum1]=num;
  48.                                         keynum1++;
  49.                                 }
  50.                         }
  51.                         else if(num=='+'||num=='-'||num=='*'||num=='/'||num=='='||num=='^'||keysqrt==0)  
  52.                         {
  53.                                 if(keynum1==0&&num1[0]==0)          //若直接輸入運算符而沒有輸入數字則執行連續運算
  54.                                 {        
  55.                         here:        ans1=ans;
  56.                                         sign=num;
  57.                                         lcdwrite_com(0x01);
  58.                                         delayms(5);
  59.                                         lcd_setxy(0,0);
  60.                                         lcdwrite_float(ans1);
  61.                                         if(sqrtflag2!=1&&num!='N')
  62.                                                 lcdwrite_data(num);
  63.                                         break;
  64.                                 }
  65.                                 for(i=0;keynum1>0;i++)           //計算按下的數字的大小
  66.                                 {
  67.                                         if(num1[i]!='.')
  68.                                                 ans1=ans1*10+num1[i];
  69.                                         else if(num1[i]=='.')
  70.                                                 break;
  71.                                         keynum1--;
  72.                                 }
  73.                                 for(keynum1--,i++,j=0;keynum1>0;j++,i++,keynum1--)
  74.                                         point=point*10+num1[i];
  75.                                 for(;j>0;j--)
  76.                                         point*=0.1;
  77.                                 ans1=ans1+point;
  78.                                 sqrtflag1=0; //清除開方標志
  79.                                 sqrtflag2=0;//清除開方標志
  80.                                 if(keysqrt==0)                  //計算開方
  81.                                 {
  82.                                         delayms(5);
  83.                                                 if(keysqrt==0)
  84.                                                 {
  85.                                                         if(beepflag==1) //若開聲音則每一次按鍵均鳴叫
  86.                                                         {
  87.                                                                 beep=0;
  88.                                                                 delayms(100);
  89.                                                                 beep=1;
  90.                                                         }
  91.                                                         ans=sqrt(ans1);
  92.                                                         sqrtflag1=1;
  93.                                                         lcdwrite_data(0xe8);
  94.                                                         while(keysqrt==0);
  95.                                                         delayms(10);
  96.                                                         while(keysqrt==0);
  97.                                                         break;
  98.                                                 }
  99.                                 }
  100.                                 sign=num;                 //記住運算符號
  101.                                 lcdwrite_data(num);
  102.                                 break;                   //輸入運算符號則退出第一運算數的輸入
  103.                         }               
  104.                 }
  105.                 while(1)
  106.                 {
  107.                         if(ac==1)
  108.                                 break;          //若清零,則退出輸入
  109.                         if(sqrtflag1==1)  //若第一次按鍵為開方,則直接顯示結果
  110.                         {
  111.                                 break;
  112.                         }
  113.                         if((keyscan()!='N')&&((num>=0&&num<=9)||num=='.'))         //記錄按下的數字
  114.                         {
  115.                                 if(keynum2<=7)
  116.                                 {
  117.                                         if(num=='.')
  118.                                         {
  119.                                                 lcdwrite_data('.');        //顯示小數點
  120.                                         }
  121.                                         else
  122.                                                 lcdwrite_num1(num);
  123.                                         num2[keynum2]=num;
  124.                                         keynum2++;
  125.                                 }
  126.                         }
  127.                         else if(num=='='||keysqrt==0)
  128.                         {
  129.                                 sqrtflag2=0;//清除開方標志
  130.                                 if(keysqrt==0)         //進入開方
  131.                                 {
  132.                                         delayms(5);
  133.                                         if(keysqrt==0)
  134.                                         {
  135.                                                 sqrtflag2=1;   //開方標志
  136.                                                 lcdwrite_data(0xe8);  //寫開方符號
  137.                                                 if(beepflag==1)        //若開聲音則每一次按鍵均鳴叫
  138.                                                 {
  139.                                                         beep=0;
  140.                                                         delayms(100);
  141.                                                         beep=1;
  142.                                                 }
  143.                                                 while(keysqrt==0);
  144.                                                 delayms(10);
  145.                                                 while(keysqrt==0);
  146.                                         }
  147.                                 }
  148.                                 point=0;
  149.                                 for(i=0;keynum2>0;i++)   //計算按下的數字的大小
  150.                                 {
  151.                                         if(num2[i]!='.')
  152.                                                 ans2=ans2*10+num2[i];
  153.                                         else if(num2[i]=='.')
  154.                                                 break;
  155.                                         keynum2--;
  156.                                 }
  157.                                 for(keynum2--,i++,j=0;keynum2>0;j++,i++,keynum2--)
  158.                                         point=point*10+num2[i];
  159.                                 for(;j>0;j--)
  160.                                         point*=0.1;
  161.                                 if(sqrtflag2!=1)
  162.                                         lcdwrite_data(num);
  163.                                 ans2=ans2+point;
  164.                                 break;                //輸入等于號則退出第二運算數的輸入
  165.                         }
  166.                         else if(num=='+'||num=='-'||num=='*'||num=='/'||num=='^')
  167.                         {
  168.                                 point=0;
  169.                                 for(i=0;keynum2>0;i++)          //計算按下的數字的大小
  170.                                 {
  171.                                         if(num2[i]!='.')
  172.                                                 ans2=ans2*10+num2[i];
  173.                                         else if(num2[i]=='.')
  174.                                                 break;
  175.                                         keynum2--;
  176.                                 }
  177.                                 for(keynum2--,i++,j=0;keynum2>0;j++,i++,keynum2--)
  178.                                         point=point*10+num2[i];
  179.                                 for(;j>0;j--)
  180.                                         point*=0.1;
  181.                                 lcdwrite_data(num);
  182.                                 ans2=ans2+point;
  183.                                 conflag=1;
  184.                                 break;                         //進行連續計算
  185.                         }
  186.                 }
  187.                 if(ac==1)
  188.                 {        
  189.                         ac=0;
  190.                         continue; //清零后進行下一次運算
  191.                 }        
  192.                 if(sign=='+')       //計算結果
  193.                         ans=ans1+ans2;
  194.                 if(sign=='-')
  195.                         ans=ans1-ans2;
  196.                 if(sign=='*')
  197.                         ans=ans1*ans2;
  198.                 if(sign=='/')
  199.                         ans=ans1/ans2;
  200.                 if(sign=='^')         //計算多次方
  201.                         ans=pow(ans1,ans2);         
  202.                 if(sqrtflag2==1)        //計算開方
  203.                         ans=sqrt(ans1);
  204.                 lcd_setxy(1,0);
  205.                 if((ans2==0&&sign=='/')||(ans1<0&&sqrtflag2==1))
  206.                         lcdwrite_string("math error");//ans2=0或被開方數小于0時提示錯誤           
  207.                 else lcdwrite_float(ans);                //顯示結果
  208.                 sqrtflag1=0,newcalc=1;                  //為新的一次運算準備
  209.                 ans1=0;
  210.                 ans2=0;
  211.                 for(i=0;i<8;i++)        //清除按鍵緩存
  212.                         num1[i]=0;
  213.                 for(i=0;i<8;i++)
  214.                         num2[i]=0;
  215.                 if(conflag==1)
  216.                 {
  217.                         conflag=0;
  218.                         goto here;           //跳轉到連續運算
  219.                 }
  220.         }
  221. }
  222. /*****初始化程序*****/
  223. void maininit(void)        
  224. {
  225.         delayms(100); //等待液晶初始化
  226.         lcd_init();
  227.         lcd_setxy(0,0);
  228.         lcdwrite_data('0');
  229.         lcd_setxy(0,0);
  230.         IT0=1;//下降沿觸發
  231.         EX0=1;//開外部中斷0
  232.         IT1=1;//下降沿觸發
  233.         EX1=1;//開外部中斷1
  234.         EA=1; //開中斷
  235. }
  236. /***清零中斷程序******/
  237. void EX0_int() interrupt 0
  238. {
  239.         if(beepflag==1)        //若開聲音則每一次按鍵均鳴叫
  240.         {
  241.                 beep=0;
  242.                 delayms(500);
  243.                 beep=1;
  244.         }
  245.         lcdwrite_com(0x01); //顯示清屏
  246.         lcd_setxy(0,0);
  247.         lcdwrite_data('0');
  248.         lcd_setxy(0,0);
  249.         num='N';                          //數字初始化
  250.         keynum1=0,keynum2=0,sign=0;
  251.     ans1=0,ans2=0,ans=0,point=0;
  252.         conflag=0,newcalc=0;
  253.         ac=1;
  254. }
  255. /***聲音中斷程序******/
  256. void EX1_int() interrupt 2
  257. {
  258.         beepflag=~beepflag;
  259.         if(beepflag==1)  //若開聲音則每一次按鍵均鳴叫
  260.                 {
  261.                 beep=0;
  262.                 delayms(500);
  263.                 beep=1;
  264.         }
  265. }
  266. /*****鍵盤掃描程序*****/
  267. uchar keyscan()
  268. {        
  269.     num='N';        //若沒有按下任何按鍵,則返回'N'
  270.     P1=0xfe;        //掃描第一行
  271.     temp=P1;
  272.     temp=temp&0xf0;
  273.     while(temp!=0xf0) //掃描列
  274.     {
  275.         delayms(10);
  276.         temp=P1;
  277.         temp=temp&0xf0;
  278.         while(temp!=0xf0)
  279.         {
  280.             temp=P1;                        
  281.             switch(temp)
  282.             {
  283.                 case 0xee:num=7;
  284.                     break;                                       
  285.                 case 0xde:num=8;
  286.                     break;                                                
  287.                 case 0xbe:num=9;
  288.                     break;
  289.                 case 0x7e:num='/';
  290.                     break;
  291.             }                                                        
  292.             while(temp!=0xf0)         //等待松手
  293.             {
  294.                 temp=P1;
  295.                 temp=temp&0xf0;
  296.             }
  297.         }
  298.     }
  299.     P1=0xfd;                //掃描第二行         
  300.         temp=P1;
  301.         temp=temp&0xf0;
  302.         while(temp!=0xf0) //掃描列
  303.         {
  304.                 delayms(10);
  305.                 temp=P1;
  306.                 temp=temp&0xf0;
  307.                 while(temp!=0xf0)
  308.                 {
  309.                         temp=P1;                        
  310.                         switch(temp)
  311.                         {
  312.                                 case 0xed:num=4;
  313.                                         break;                                       
  314.                                 case 0xdd:num=5;
  315.                                         break;                                                
  316.                                 case 0xbd:num=6;
  317.                                         break;
  318.                                 case 0x7d:num='*';
  319.                                         break;
  320.                         }
  321.                      while(temp!=0xf0)
  322.                         {
  323.                                 temp=P1;
  324.                                 temp=temp&0xf0;                 //等待松手
  325.                         }
  326.                 }
  327.         }
  328.          P1=0xfb;         //掃描第三行
  329.         temp=P1;
  330.         temp=temp&0xf0;
  331.         while(temp!=0xf0) //掃描列
  332.         {
  333.                 delayms(10);
  334.                 temp=P1;
  335.                 temp=temp&0xf0;
  336.                 while(temp!=0xf0)
  337.                 {
  338.                         temp=P1;                        
  339.                         switch(temp)
  340.                         {
  341.                                 case 0xeb:num=1;
  342.                                         break;                                       
  343.                                 case 0xdb:num=2;
  344.                                         break;                                                
  345.                                 case 0xbb:num=3;
  346.                                         break;
  347.                                 case 0x7b:num='-';
  348.                                         break;
  349.                         }
  350.                      while(temp!=0xf0)        //等待松手
  351.                         {
  352.                                 temp=P1;
  353.                                 temp=temp&0xf0;
  354.                         }
  355.                 }
  356.         }
  357.          P1=0xf7;          //掃描第四行
  358.         temp=P1;
  359.         temp=temp&0xf0;
  360.         while(temp!=0xf0) //掃描列
  361.         {
  362.                 delayms(10);
  363.                 temp=P1;
  364.                 temp=temp&0xf0;
  365.                 while(temp!=0xf0)
  366.                 {
  367.                         temp=P1;                        
  368.                         switch(temp)
  369.                         {
  370.                                 case 0xe7:num=0;
  371.                                         break;                                       
  372.                                 case 0xd7:num='.';
  373.                                         break;                                                
  374.                                 case 0xb7:num='=';
  375.                                         break;
  376.                                 case 0x77:num='+';
  377.                                         break;
  378.                         }
  379.                      while(temp!=0xf0)
  380.                         {
  381.                                 temp=P1;
  382.                                 temp=temp&0xf0;                 //等待松手
  383.                         }
  384.                  }
  385.         }
  386.         if(keypow==0)
  387.         {
  388.                 delayms(5);
  389.                 if(keypow==0)
  390.                 {
  391.                         powflag=1;
  392.                         num='^';
  393.                 }
  394.                 while(keypow==0); //掃描多次方按鍵
  395.                 delayms(5);
  396.                 while(keypow==0);
  397.         }
  398.         if(beepflag==1&&num!='N')  //若開聲音則每一次按鍵均鳴叫
  399.         {
  400.                 beep=0;
  401.                 delayms(100);
  402.                 beep=1;
  403.         }
  404.     return num;
  405. }
復制代碼


評分

參與人數 4黑幣 +61 收起 理由
安山有狐貍 + 1 贊一個!
妖行 + 5 很給力!
ZHANGJINGYU + 5 回帖助人的獎勵!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏12 分享淘帖 頂4 踩
回復

使用道具 舉報

沙發
ID:161497 發表于 2017-6-2 22:41 | 只看該作者
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

板凳
ID:103952 發表于 2017-6-14 15:03 | 只看該作者

下載地址就在上面哦
回復

使用道具 舉報

地板
ID:214665 發表于 2017-6-26 10:47 | 只看該作者
很厲害啊
回復

使用道具 舉報

5#
ID:245246 發表于 2017-11-2 11:23 | 只看該作者
下載了可以用嗎
回復

使用道具 舉報

6#
ID:247636 發表于 2017-11-10 09:21 來自手機 | 只看該作者
我想弄這個,試試看
回復

使用道具 舉報

7#
ID:294062 發表于 2018-3-19 15:43 | 只看該作者
看著很不錯,學習一下
回復

使用道具 舉報

8#
ID:339591 發表于 2018-5-28 10:44 | 只看該作者
看起來很厲害,參考一下
回復

使用道具 舉報

9#
ID:341778 發表于 2018-6-11 15:21 | 只看該作者
很棒很不錯
回復

使用道具 舉報

10#
ID:350401 發表于 2018-6-13 10:21 | 只看該作者
nice,最近在做課程設計,學到了
回復

使用道具 舉報

11#
ID:350967 發表于 2018-6-13 11:35 | 只看該作者
厲害了
回復

使用道具 舉報

12#
ID:354047 發表于 2018-6-21 18:13 來自手機 | 只看該作者
里面有沒有工程
回復

使用道具 舉報

13#
ID:162514 發表于 2018-9-19 08:55 | 只看該作者
下來玩玩!
回復

使用道具 舉報

14#
ID:530642 發表于 2019-5-9 16:09 | 只看該作者
在哪里下載?
回復

使用道具 舉報

15#
ID:258520 發表于 2019-5-16 17:21 | 只看該作者
能輸入小數點嗎   
回復

使用道具 舉報

16#
ID:553254 發表于 2019-6-2 21:09 | 只看該作者
感謝分享
回復

使用道具 舉報

17#
ID:655531 發表于 2019-12-3 22:19 | 只看該作者
感謝分享
回復

使用道具 舉報

18#
ID:498685 發表于 2019-12-8 10:35 | 只看該作者
感謝分享,值得學習,謝謝樓主
回復

使用道具 舉報

19#
ID:639069 發表于 2019-12-19 14:50 來自手機 | 只看該作者
那個lc1602_8.h沒有包含怎么辦
回復

使用道具 舉報

20#
ID:669432 發表于 2019-12-21 18:01 | 只看該作者
已經下載了,謝謝大佬
回復

使用道具 舉報

21#
ID:681485 發表于 2020-1-5 19:40 | 只看該作者
這個的按鍵具體是哪些?要怎么用
回復

使用道具 舉報

22#
ID:771836 發表于 2020-6-7 13:19 | 只看該作者
感謝大佬
回復

使用道具 舉報

23#
ID:838120 發表于 2020-11-8 19:16 | 只看該作者
你這個能進行8*8位的運算嗎
回復

使用道具 舉報

24#
ID:834848 發表于 2020-12-27 13:19 來自手機 | 只看該作者
感謝感謝分享   值得學習
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美色图综合网 | 黄色网址大全在线观看 | 亚洲成人第一页 | 不用播放器看的av | 成人精品国产一区二区4080 | 涩爱av一区二区三区 | 一区二区三区久久久 | 欧美精品一区二区三区在线播放 | 国产毛片在线看 | 精品欧美一区二区三区久久久 | 国产精品久久网 | 午夜影院污 | 久久亚洲欧美日韩精品专区 | 国产精品久久久久久久免费大片 | 成人影院在线观看 | 久久久久久久久淑女av国产精品 | 一本一道久久a久久精品综合 | 黑人精品欧美一区二区蜜桃 | 国产丝袜一区二区三区免费视频 | 亚洲精品av在线 | 在线观看免费av网站 | 麻豆一区二区三区 | 精品国产99 | 91亚洲国产成人久久精品网站 | 精品视频亚洲 | 日本在线免费 | 91精品国产色综合久久 | 2021狠狠干 | 欧美中文字幕 | 国产综合久久久久久鬼色 | 亚洲成人av一区二区 | 亚洲理论在线观看电影 | 精品在线一区 | 午夜成人在线视频 | www.亚洲一区二区三区 | 中文字幕一区二区三区在线观看 | 亚洲精品久久久蜜桃 | 国产精品欧美精品日韩精品 | 欧美在线a | 欧美成人一区二区三区 | 欧美成人性生活 |