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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機的計算器編程

[復制鏈接]
跳轉到指定樓層
樓主
ID:788576 發表于 2020-6-27 09:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include <REGX51.H>
  2. #include<intrins.h>
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<math.h>
  6. sbit RS = P2^5;
  7. sbit RW = P2^6;
  8. sbit E  = P2^7;

  9. #define Data  P0//數據端口
  10. //全局變量
  11. float num1;//第一操作數num1     (初始為零)
  12. float num2;//第二操作數num2     (初始為零)
  13. char yun_flag='+';//運算符號 yun_flag    (默認為+ )
  14. char key_last;//上次按鍵狀態標志 key_last
  15. char sqrt_flag;//開方鍵按下標志   sqrt_flag
  16. unsigned long pos_flag=1;//小數位權pos_flag      (默認為1)
  17. char neg_flag;//正負標志 neg_flag
  18. char data c_num1[15]=" ";//c_num1 字符型第一操作數 (數組不定義大小與其他變量沖突)
  19. char data c_num2[15]=" ";//c_num2 字符型第二操作數
  20. char error;//運算法則錯誤;
  21. char len;//小數點后位數
  22. /*                    微秒延時函數                                */
  23. /******************************************************************/
  24. void DelayUs(unsigned char us)//delay us
  25. {
  26. unsigned char uscnt;
  27. uscnt=us>>1;        /*12MHz頻率*/
  28. while(--uscnt);
  29. }
  30. /******************************************************************/
  31. /*                    毫秒函數聲明                                */
  32. /******************************************************************/
  33. void DelayMs(unsigned char ms)
  34. {
  35. while(--ms)
  36.    {
  37.      DelayUs(250);
  38.      DelayUs(250);
  39.          DelayUs(250);
  40.          DelayUs(250);
  41.    }
  42. }
  43. /******************************************************************/
  44. /*                   寫入命令函數                                 */
  45. /******************************************************************/
  46. void WriteCommand(unsigned char c)
  47. {
  48. DelayMs(5);//操作前短暫延時,保證信號穩定
  49. E=0;
  50. RS=0;
  51. RW=0;
  52. _nop_();
  53. E=1;
  54. Data=c;
  55. E=0;
  56. }
  57. /******************************************************************/
  58. /*                   寫入數據函數                                 */
  59. /******************************************************************/
  60. void WriteData(unsigned char c)
  61. {
  62. DelayMs(5);  //操作前短暫延時,保證信號穩定
  63. E=0;
  64. RS=1;
  65. RW=0;
  66. _nop_();
  67. E=1;
  68. Data=c;
  69. E=0;
  70. RS=0;
  71. }
  72. /******************************************************************/
  73. /*                   寫入字節函數                                 */
  74. /******************************************************************/
  75. void ShowChar(unsigned char pos,unsigned char c)
  76. {
  77. unsigned char p;
  78. if (pos>=0x10)
  79.     p=pos+0xb0; //是第二行則命令代碼高4位為0xc
  80. else
  81.     p=pos+0x80; //是第二行則命令代碼高4位為0x8
  82. WriteCommand (p);//寫命令
  83. WriteData (c);   //寫數據
  84. }
  85. /******************************************************************/
  86. /*                   寫入字符串函數                               */
  87. /******************************************************************/
  88. void ShowString (unsigned char line,char *ptr)
  89. {
  90. unsigned char l,i;
  91. l=line<<4;
  92. for (i=0;*(ptr+i)!='\0';i++)
  93.   ShowChar (l++,*(ptr+i));//循環顯示16個字符
  94. }
  95. /******************************************************************/
  96. /*                   初始化函數                                   */
  97. /******************************************************************/
  98. void InitLcd()
  99. {
  100. DelayMs(15);
  101. WriteCommand(0x38); //display mode
  102. WriteCommand(0x38); //display mode
  103. WriteCommand(0x38); //display mode
  104. WriteCommand(0x06); //顯示光標移動位置
  105. WriteCommand(0x0c); //顯示開及光標設置
  106. WriteCommand(0x01); //顯示清屏

  107. }
  108. /*************按鍵掃描****************************/
  109. char scan()
  110. {

  111.   char h_data,l_data,i,key_num;
  112.   P2=P2&0XE0;//P2低5位送0
  113.   P1=P1|0X0F;//P1低4位送1
  114.   while((P1|0xf0)==0xff)//判斷P1低4位是否全為1
  115.   {
  116.    while((P1|0xf0)==0xff);
  117.    DelayMs(10);//延時10ms
  118.   }
  119.    l_data=~(P1|0xf0);//記入列標志
  120.    P2=P2|0X1F;//P2低五位送1
  121.    P1=P1&0XF0;//P1低四位送0
  122.    h_data=~(P2|0xe0);//記入行標志
  123.    for(i=0;i<=4;i++)//計算行號(0~4)
  124.             {
  125.            if(h_data==1)break;
  126.            h_data=h_data>>1;
  127.          }
  128. h_data=i;//行號
  129.   for(i=1;i<=4;i++)//計算列號(1~4)
  130.          {
  131.           if(l_data==1)break;
  132.           l_data=l_data>>1;
  133.         }
  134. l_data=i;//列號
  135.    key_num=h_data*4+l_data;        

  136.   P2=P2&0XE0;//P2低5位送0
  137.   P1=P1|0X0F;//P1低4位送1
  138.   while((P1|0xf0)!=0xff)//判斷P1低4位是否全為1
  139.   {
  140.    while((P1|0xf0)!=0xff);
  141.    DelayMs(10);//延時10ms
  142.   }
  143.   return key_num;
  144. }
  145. void float_to_char(float a,char* p)
  146. {
  147.   char i,flag,length;
  148.   flag=0;
  149.   sprintf(p,"%f",a);
  150.   length=strlen (p);
  151.   for(i=0;i<length;i++)
  152.   {
  153.     if(*(p+i)=='.')flag=1;
  154.   }
  155.   if(flag==1)
  156.   for(i=length-1;i>=0;i--)
  157.   {
  158.     if(*(p+i)=='.'){*(p+i)='\0';break;}
  159.     if(*(p+i)!='0'){*(p+i+1)='\0';break;}
  160.   }
  161. }
  162. /**********************更新液晶*************************/
  163. void refresh()//更新液晶
  164. {
  165.   char length,i,j;
  166.   char dot;
  167.   dot=0;
  168.          
  169.   float_to_char(num2,c_num2);//num2轉為字符型
  170.   length=strlen(c_num2);
  171.   for(i=0,j=0;i<length;i++)        
  172.   {
  173.     if(c_num2[i]=='.')
  174.         dot=1;
  175.         if(dot==1)
  176.     j++;
  177.   }
  178.   if(j<len)
  179.   {
  180.           if(dot==1)
  181.           {        
  182.             for(i=length;i<(length+len-j);i++)
  183.                  {
  184.                    c_num2[i]='0';
  185.         
  186.                  }
  187.                  c_num2[i]='\0';
  188.           }
  189.           else
  190.                 {
  191.                   
  192.                   c_num2[length]='.';
  193.                   if(len-j>1)
  194.                   {
  195.                     for(i=length+1;i<(length+len-j);i++)
  196.                          c_num2[i]='0';
  197.                   }
  198.                   c_num2[length+len-j]='\0';
  199.                 }  
  200.   }

  201.   if(neg_flag==1)//'+/-'按下首位加‘-’
  202.    {
  203.       length=strlen(c_num2);//計算c_num2長度         
  204.                     for(i=length-1;i>=0;i--)
  205.                   {
  206.                           c_num2[i+1]=c_num2[i];
  207.                   }
  208.                   c_num2[length+1]='\0';
  209.                   c_num2[0]='-';
  210.    }
  211.    
  212.    if(sqrt_flag==1)
  213.            {
  214.       length=strlen(c_num2);//計算c_num2長度
  215.              for(i=length-1;i>=0;i--)
  216.           {
  217.                   c_num2[i+1]=c_num2[i];
  218.           }
  219.           c_num2[length+1]='\0';
  220.           c_num2[0]=0xe8;//字符根號
  221.    }
  222.    
  223.    
  224.    if(error==0)
  225.    {
  226.            float_to_char(num1,c_num1);//num1轉為字符型
  227.            WriteCommand(0x01); //顯示清屏
  228.            ShowString(0,c_num1);
  229.            ShowString(1,c_num2);  
  230.            ShowChar(15,yun_flag);
  231.    }else
  232.    {
  233.        WriteCommand(0x01); //顯示清屏
  234.            ShowString(0,"error!!!");
  235.    }
  236. }
  237. //鍵值處理
  238. void operation1(char keynum)//按下 ’+、-、*、/處理
  239. {
  240.   if(key_last==1)//上次按鍵為 數字、小數點、+/-、sqrt
  241.    {
  242.      if(neg_flag==1)num2=-num2;//'+/-'按下
  243.          if(sqrt_flag==1)//sqrt按下
  244.          {
  245.          if(num2>=0)
  246.          num2=sqrt(num2);
  247.          else
  248.          error=1;
  249.          }
  250.          if(yun_flag=='+')num1=num1+num2; //按下的是‘+’
  251.          if(yun_flag=='-')num1=num1-num2;//按下的是‘-’
  252.          if(yun_flag=='*')num1=num1*num2;//按下的是‘*’
  253.          if(yun_flag=='/')//按下的是‘/’
  254.          {
  255.            if(num2!=0)
  256.            num1=num1/num2;
  257.            else
  258.            error=1;
  259.          }
  260.          num2=0;//num2清零
  261.          sqrt_flag=0;//sqrt_flag清零
  262.      neg_flag=0;//neg_flag清零
  263.          pos_flag=1;//pos_flag回1
  264.    }
  265.    if(keynum==4)yun_flag='+';//yun_flag更新
  266.    if(keynum==8)yun_flag='-';
  267.    if(keynum==12)yun_flag='*';
  268.    if(keynum==16)yun_flag='/';
  269.    len=0;
  270.    key_last=0;//key_last更新   
  271.    refresh();
  272. }
  273. //////////////////////////////////////////////////////
  274. void operation2(char keynum)//輸入數字
  275. {
  276.   float Data1;
  277.    
  278.   if(keynum==1)Data1=7;//分析輸入數字
  279.   if(keynum==2)Data1=8;
  280.   if(keynum==3)Data1=9;
  281.   if(keynum==5)Data1=4;
  282.   if(keynum==6)Data1=5;
  283.   if(keynum==7)Data1=6;
  284.   if(keynum==9)Data1=1;
  285.   if(keynum==10)Data1=2;
  286.   if(keynum==11)Data1=3;
  287.   if(keynum==13)Data1=0;
  288.   if(pos_flag==1)//更新num2
  289.   num2=num2*10+Data1;
  290.   else
  291.   {            
  292.     num2=num2+(Data1/pos_flag);
  293.         pos_flag=pos_flag*10;
  294.         len++;
  295.   }
  296.   key_last=1;//更新key_last        
  297.   refresh();
  298. }
  299. ////////////////////////////////////////////////////////////
  300. void operation3()//輸入小數點
  301. {
  302.   if(pos_flag==1)//首次出現小數點
  303.   {
  304.    pos_flag=pos_flag*10;//小數位權*10
  305.    len++;
  306.   }
  307.   key_last=1;//更新key_last
  308.   refresh();//更新液晶
  309. }
  310. /////////////////////////////////////////////////////
  311. void operation4()//輸入'='
  312. {
  313.      if(neg_flag==1)num2=-num2;//'+/-'按下
  314.          if(sqrt_flag==1)//sqrt按下
  315.          {
  316.          if(num2>=0)
  317.          num2=sqrt(num2);
  318.          else
  319.          error=1;
  320.          }
  321.          if(yun_flag=='+')num1=num1+num2; //按下的是‘+’
  322.          if(yun_flag=='-')num1=num1-num2;//按下的是‘-’
  323.          if(yun_flag=='*')num1=num1*num2;//按下的是‘*’
  324.          if(yun_flag=='/')//按下的是‘/’
  325.          {
  326.            if(num2!=0)
  327.            num1=num1/num2;
  328.            else
  329.            error=1;
  330.          }
  331.          num2=0;//num2清零
  332.          sqrt_flag=0;//sqrt_flag清零
  333.      neg_flag=0;//neg_flag清零
  334.          pos_flag=1;//pos_flag回1
  335.      yun_flag='+';//yun_flag更新
  336.          len=0;
  337.    key_last=0;//key_last更新   
  338.    refresh();
  339. }
  340. ////////////////////////////////////////////////////
  341. void operation5()//輸入clear all
  342. {

  343.    num1=0;// num1清零
  344.    num2=0;//num2清零
  345.    sqrt_flag=0;//清sqrt_flag
  346.    neg_flag=0;// 清neg_flag
  347.    pos_flag=1;// Pos_flag=1
  348.    yun_flag='+';// yun_flag(為'+')
  349.    error=0;//清error
  350.    len=0;
  351.    key_last=0;//更新key_flag
  352.    refresh();//更新液晶
  353. }
  354. ///////////////////////////////////////////////////////
  355. void operation6()//輸入'C'
  356. {
  357. num2=0;//num2清零
  358. sqrt_flag=0;//清sqrt_flag
  359. neg_flag=0;//清neg_flag
  360. pos_flag=1;//pos_flag=1
  361. len=0;
  362. key_last=0;//key_last
  363. refresh();//更新液晶
  364. }
  365. ////////////////////////////////////////////////////////////
  366. void operation7()//輸入'+/-'
  367. {
  368.   if(neg_flag==0)//neg_flag反轉
  369.   neg_flag=1;
  370.   else neg_flag=0;
  371.   key_last=1;//key_last
  372.   refresh();// 更新液晶
  373. }
  374. /////////////////////////////////////////////////////////////
  375. void operation8()//輸入'sqrt'
  376. {
  377. if(sqrt_flag==0)//sqrt_flag反轉
  378.   sqrt_flag=1;
  379. else sqrt_flag=0;
  380. key_last=1;//更新key_last
  381. refresh();//更新液晶
  382. }
  383. //鍵值分析
  384. void key(char keynum)
  385. {
  386.   switch(keynum)
  387.   {
  388.     case 4 :
  389.         case 8 :
  390.         case 12:
  391.         case 16://+、-、*、/
  392.                     {
  393.                          if(error==0)
  394.                  operation1(keynum);
  395.                  break;}
  396.                         
  397.         case 1  : //數字7
  398.         case 2  : //數字8
  399.         case 3  : //數字9
  400.         case 5  : //數字4
  401.         case 6  : //數字5
  402.         case 7  : //數字6
  403.         case 9  : //數字1
  404.         case 10 : //數字2
  405.         case 11 : //數字3
  406.         case 13 : //數字0
  407.                  {
  408.                          if(error==0)
  409.                          operation2(keynum);
  410.                          break;}
  411.                         
  412.         case 14 ://小數點                  
  413.                          {
  414.                            if(error==0)
  415.                            operation3();
  416.                            break;}
  417.                         
  418.         case 15 :// '='         
  419.                          {
  420.                            if(error==0)
  421.                            operation4();
  422.                            break;}
  423.                         
  424.         case 17 :// clear all  
  425.                          {
  426.                            operation5();
  427.                            break;}

  428.         case 18 :// 'C'  
  429.                          {
  430.                            if(error==0)
  431.                            operation6();
  432.                            break;}
  433.         case 19 :// '+/-'  
  434.                          {
  435.                            if(error==0)
  436.                            operation7();
  437.                            break;}
  438.         case 20 ://sqrt
  439.                          {
  440.                            if(error==0)
  441.                            operation8();
  442.                            break;}                                      
  443.                                                                        
  444.   }         
  445. }
  446. main()
  447. {

  448. InitLcd();         //初始化LCD
  449. DelayMs(15);       //延時保證信號穩定
  450. refresh();

  451.         //延時保證信號穩定
  452. while(1)
  453. {
  454. key(scan());
  455. }
復制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久人人爽人人爽 | 国产伦精品一区二区三区四区视频 | 999国产精品视频 | 成年人在线观看视频 | 亚洲精品久久久久久一区二区 | 亚洲视频中文字幕 | 欧美日韩在线视频一区 | 国产精品成人国产乱一区 | 久久久精品国产 | 日韩欧美在线视频观看 | 精品久久久久久中文字幕 | 国产精品久久久久久久久久久免费看 | 中文字幕国产 | 射久久| 国产探花在线精品一区二区 | 99re热这里只有精品视频 | 国产一区不卡 | 久久久久久久久久久久久久av | 日本免费一区二区三区四区 | 欧美精品欧美精品系列 | 新91视频网 | 国产精品1区2区3区 欧美 中文字幕 | 亚洲国产欧美一区二区三区久久 | 成人小视频在线免费观看 | 日本一区二区三区视频在线 | 亚洲欧洲精品一区 | 天天拍天天草 | 欧美一二三 | 久久剧场 | 国产精品中文 | 亚洲成人精品久久久 | 国内在线视频 | 亚洲精品68久久久一区 | 久久久精品一区二区三区 | 久久精品视频12 | 干干干操操操 | 一区二区三区欧美 | 亚洲国产专区 | 中文字幕国 | 亚洲欧美中文日韩在线v日本 | 91在线精品一区二区 |