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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 12732|回復: 17
收起左側

基于51單片機的多功能計算器全套設計資料下載(PCB+源碼+仿真+論文)

  [復制鏈接]
ID:350292 發表于 2018-6-12 15:06 | 顯示全部樓層 |閱讀模式
lcd1602 51單片機計算器 5*4鍵盤掃描,下面是制作出來的實物圖:

圖3.2 浮點數運算



0.png

全部資料51hei下載地址:
計算器 5乘4.zip (5.75 MB, 下載次數: 640)




單片機課程設計
設計課題     基于51單片機的多功能計算器設計
【摘要】 當今社會,隨著人們物質生活的不斷提高,電子產品已經走進了家家戶戶,無論是生活或學習,還是娛樂和消遣幾乎樣樣都離不開電子產品,大型復雜的計算能力是人腦所不能勝任的,而且人腦比較容易出錯。計算器作為一種快速通用的計算工具方便了用戶的使用。計算器可謂是我們最親密的電子伙伴之一。本設計著重在于分析計算器設計開發過程中的環節和步驟,并從實踐經驗出發對計算器設計做了詳細的分析和研究。
本設計是以STC89C52單片機為核心的計算器模擬系統設計,輸入采用5×8矩陣鍵盤,可以進行加、減、乘、除等十幾種數字運算,同時支持括號的嵌套使用級浮點數的運算,并在LCD1602上顯示操作過程。
本次設計注重設計方法及流程,首先根據原理設計電路,利用keil編程,借助實驗開發平臺進行仿真實驗,進而利用altium designer 制作PCB,最后到焊接元器件,直至調試成功。在設計的同時,特別注重keil軟件和altium designer軟件的使用方法和技巧以及常用的LCD顯示器和矩陣鍵盤的設計和使用方法。

目錄
1  系統方案設計
1.1 設計目的及要求
1.1.1 設計目的
1.1.2 設計要求
1.2 方案論證及選擇
1.2.1 方案一 采用FPGA控制
1.2.2 方案二 采用STC89C52
1.2.3 方案比較及選擇
2  單元電路設計
2.1  工作原理
2.2  硬件電路設計
2.2.1  單片機電路設計
2.2.2  鍵盤模塊電路
2.2.3  蜂鳴器提示電路
2.2.4  液晶顯示電路
2.3 軟件設計
2.3.1 鍵盤掃描
2.3.2 表達式的處理
2.4  altium designer 原理圖設計及PCB制作
2.4.1  原理圖設計
2.4.2              PCB制作
2.4.3              設計結果
3系統測試
3.1 整數運算
3.2 浮點數運算
3.3 輸入出錯的情況
4  結論與心得體會
5  參考文獻
附錄1  元器件清單
附錄2  程序清單

1  系統方案設計
1.1 設計目的及要求
1.1.1 設計目的

通過本次課題設計,應用《單片機應用基礎》、《數據結構》等所學相關知識及查閱資料,完成實用計算器的設計,以達到理論與實踐更好的結合、進一步提高綜合運用所學知識和設計的能力的目的。

通過本次設計的訓練,可以使我在基本思路和基本方法上對基于MCS-51單片機的嵌入式系統設計有一個比較感性的認識,并具備一定程度的設計能力。

1.1.2 設計要求

在本次課程設計中,主要完成如下方面的設計要求:

1、掌握MCS-51系列某種產品(例如8051)的最小電路及外圍擴展電路的設計方法;

2、計算器能實現加、減、乘、除、平方、開方、N次方、開N次方、正弦函數、                                  余弦函數、正切函數、反正弦、反余弦、反正切、對數運算、階乘(N<=34)、排列、                 組合、累加等十九種功能。

3、支持浮點數運算;

4、較為友好的界面顯示,對輸入實時顯示,對計算結果輸出顯示;

5、能夠具備比較完善的報錯系統

1.2 方案論證及選擇

基于設計要求,笨設計考慮了兩種設計方案,他們均可以實現計算器的功能,但基于設計目的及微控制器的廣泛運用,比較兩種方案的優劣,最終選擇基于51單片機的計算器設計。

1.2.1 方案一 采用FPGA控制
FPGA是一種高密度的可編程邏輯器件,自從Xilinx公司1985年推出第一片FPGA以來,FPGA的集成密度和性能提高很快,其集成密度最高達500萬門/片以上,系統性能可達200MHz。由于FPGA器件集成度高,方便易用,開發和上市周期短,在數字設計和電子生產中得到迅速普及和應用,并一度在高密度的可編程邏輯器件領域中獨占鰲頭。
但是而基于 SRAM編程的FPGA,其編程信息需存放在外部存儲器上 ,需外部存儲器芯片 ,且使用方法復雜 ,保密性差,而其對于一個簡單的計算器而言,實用FPGA有點大材小用,成本太高。

1.2.2 方案二 采用STC89C52
單片機是單片微型機的簡稱,故又稱為微控制器MCU(Micro Control Unit)。通常由單塊集成電路芯片組成,內部包含有計算機的基本功能部件:中央處理器CPU,存儲器和I/O接口電路等。因此,單片機只要和適當的軟件及外部設備相結合,便可成為一個單片機控制系統。單片機廣泛用于智能產品,智能儀表,測控技術,智能接口等,具有操作簡單,實用方便,價格便宜等優點,而其中AT89S52以MCS-51為內核,是單片機中最典型的代表,應用于各種控制領域。
1.2.3 方案比較及選擇
通過以上兩種方案論證和比較,從設計的實用性,方便性和成本出發,選擇了以STC89C52單片機作為中央處理單元進行計算器的設計,這樣設計能夠實現對六位浮點數的加減和三位浮點數的乘除運算。


2  單元電路設計

2.1  工作原理

利用矩陣鍵盤進行按鍵的輸入,通過對矩陣鍵盤的掃描,獲取用戶的輸入,并實時的顯示在1602液晶上,每次獲取到輸入時,根據軟件設計的相應方法對輸入進行處理、運算,輸入結束后(以“=“為標志),將最終的運算結果輸出的液晶上。

系統組成及整體框圖如圖2.1所示。

圖2.1 系統組成及總體框圖(見附件)


2.2  硬件電路設計
2.2.1  單片機電路設計

為使單片機正常工作,除電源供電部分外,還需提供晶振電路和復位電路。具體電路如下:

圖2.2 單片機工作電路

由圖2.2可知,9腳外接的是按鍵復位電路,18,19腳外接的是晶振電路,這樣,就構成了單片機正常工作的必備電路。同時,為使P0口正常工作,并增加其帶負載能力,P0口需接了上拉電阻。圖中EA為外部訪問允許,欲使CPU僅訪問外部程序存儲器(地址為0000H-FFFFH),EA端必須保持低電平(接地)。在這里,STC89C52單片機8k的程序存儲器已經夠本設計使用,無需外部程序儲存器,故EA直接接高電平。


2.2.2  鍵盤模塊電路

圖2.3是鍵盤電路,共20個按鍵,用來實現人機交互和運算表達式的輸入,S0~S3、S5~S8、S10~S13、S15~S18共16個按鍵組成一組4*4的矩陣鍵盤,行線第一行到第四行分別接在P3.0~P3.3口,列線第一列到第四列分別接在P3.4~P3.7口,這樣P3口就完成了對4*4的矩陣鍵盤的接線。同時,注意到按鍵數量還達不到要求,故增加了四個獨立按鍵S4,S9,S14,S19。他們依次接在P20~P23口。可見,矩陣鍵盤相對來講更節省I/O口,但本著學習的目的,加之本設計并不需要太多的I/O口,故為充分學習和利用資源,在這里也設計了4個這樣的獨立按鍵。

圖2.3  鍵盤模塊電路

2.2.3  蜂鳴器提示電路

蜂鳴器主要用于按鍵時發出聲音,提示當前的按鍵操作,電路如圖2.5所示,三極管主要用于驅動蜂鳴器,因為單片機I/O的驅動能力有限。同時單片機I/O口還在這里還起到開關作用,為‘0’時打開蜂鳴器通道,使蜂鳴器發聲。

圖2.4  蜂鳴器提示電路

2.2.4  液晶顯示電路

LCD也是本次設計的重要組成部分之一,主要用于顯示輸入和輸出。電路如圖2.5所示,LCD數據端與單片機P0口相連,控制端與P24~P26連接,電位器用于調節對比度。


圖2.5  LCD顯示電路


至此,整個電容測量儀的硬件設計部分就基本設計完成,接下來,需要的就是與之相匹配的軟件支持了。


2.3 軟件設計

軟件編程平臺選擇最常用的keil軟件。由于該程序并未涉及到底層的驅動問題,因此選擇方便快捷的C語言編程。在編程中,將該程序分為四個模塊:延時模塊、1602顯示模塊、用于處理計算表達式的對戰模塊及主函數模塊。采用模塊化設計,方便調試與理解。具體程序見附錄二。在這里重點介紹軟件核心的表達式處理程序算法。

2.3.1 鍵盤掃描

獨立鍵盤很好實現,只需不停的檢測即可,出現低電平即出現按鍵,在經過一定的延時消抖,再確認判斷即可。

矩陣鍵盤掃描程序,首先讀出P3的低四位,然后讀出P3口的高四位。然后確定鍵值并顯示緩存,最終將按鍵的值通過一個預先定義好的數組轉換為相應的ASCII碼值送給LCD顯示和與表達式相應的堆棧進行處理,讀鍵程序使用的是反轉法讀鍵,不管鍵盤矩陣的規模大小,均進行兩次讀鍵。第一次所有行線均輸出高電平,從P3口的值讀入鍵盤信息(行信息);第二次所有列線均輸出高電平,從P3口的值讀入鍵盤信息(列信息)。

2.3.2 表達式的處理

表達式包含加、減、乘、除、括號等,必須按照相應的優先級運算,才可能得出正確的結果。在這兒采用棧結構,可以有效的進行表達式的處理。

棧結構具有“后進先出”的固有屬性,借助這個屬性我們可以隨時對剛輸入的元素進行操作,從而實現邊輸入邊計算。

為了實現算符優先算法。可以使用兩個工作棧。一個稱為OPTR,用以寄存運算符,另一個稱做OPND,用以寄存操作數或運算結果。

1.首先置操作數棧為空棧,表達式起始符”#”為運算符棧的棧底元素;

2.依次讀入表達式,若是操作符即進OPND棧,若是運算符則和OPTR棧的棧頂運算符比較優先權后作相應的操作,直至整個表達式求值完畢(即OPTR棧的棧頂元素和當前讀入的字符均為”#”)。

在這里,相應的處理指的是,如果當前符號的優先級比棧頂優先級低,則將該符號繼續壓入堆棧,不做其它操作;如果當前符號的優先級比棧頂優先級高,則依次取出操作數棧的棧頂兩個數據和符號棧的棧頂符號進行這兩個數的運算,運算結果數據再壓入操作數棧中。若優先級相等,則彈出符號棧棧頂符號。算符間的優先關系如下(‘#‘表示開始和結束):


+

-

*

/

(

)

#

+

>

<

<

<

<

>

>

-

>

>

<

<

<

>

>

*

>

>

>

>

<

>

>

/

>

>

>

>

<

>

>

(

<

<

<

<

<

=


)

>

>

>

>


>

>

#

<

<

<

<

<


=

表2.1 運算符優先級表


2.4  altium designer 原理圖設計及PCB制作
2.4.1  原理圖設計

圖2.6 原理圖設計(1)——單片機部分

圖2.7 原理圖設計(2)——鍵盤、蜂鳴器部分

2.4.2          PCB制作

圖2.8 PCB設計(1)——單片機部分

圖2.9 原理圖設計(2)——鍵盤、蜂鳴器部分

注:在此并沒有布雙層板,紅色的線僅僅只是為了標志出跳線或者本質上實物已經連接上了。


2.4.3          設計結果

圖2.10   設計結果實物圖


如圖所示,各個按鍵功能如圖中文字說明,電源為5V直流電源。


3系統測試

測試主要測試其運算是否正確,及檢錯能力。

3.1 整數運算

在此以整數運算為例,介紹計算器的使用方法即流程。首先打開電源,看到LCD打開顯示,說明運行正常,接著,輸入表達式:12*(56+23)*2,其結果本身應為1896。

輸入結束后,點“=”按鍵,即可在第二行顯示出運算結果,由圖可見運算完全正確。在使用時,可以通過聲音開關按鈕控制按鍵音的打開和關閉,在LCD上也有顯示,如果再第二行第一個位置沒有顯示,則沒有打開聲音,可以通過按鈕打開。若有顯示,則聲音已經打開,可以通過按鈕關閉聲音。如圖3.1所示,此時已經打開聲音。

圖3.1  整數運算




3.2 浮點數運算

由圖可以看出,可以進行浮點數運算,還可以從第二行第一個字符,蜂鳴器處于關閉狀態。


3.3 輸入出錯的情況

輸入一個錯誤的表達式,如圖3.3所示。

圖3.3 輸入錯誤的情況下


再按“=”號,將會出現出錯畫面。如圖3.4所示。

圖3.4 輸入錯誤的顯示


由以上測試可知,整個設計運行正常,能夠正確的進行運算和出錯提示。由此可得,整個設計是成功的。




4  結論與心得體會

總之,通過一系列仿真和設計,基于單片機的計算器設計還是比較成功的做出來了。一路下來還是比較坎坷,從原理到實物,從調試到調試成功,遇到了很多問題,特別是在軟件編程時,開始以為既然單片機具有數據處理與運算的能力,那么用它來做一個計算器應該很簡單了,可是,后面實際操作才知道,當計算表達式時,優先級問題非常重要,一開始用了很多if語句來實現,程序繁瑣復雜,且效果不是很好,很容易出錯,最后通過查閱相關資料,了解到利用數據結構中棧的思想來解決這一問題就很方便。但在實際寫程序時也遇到了很多問題,但最終還是克服難關,將整個軟件比較完善的實現了。

在硬件的原理圖及PCB設計中,也遇到了很多問題,先做模塊后做主板,導致我后面的布線就很麻煩,這也教會了我一些經驗,在PCB分模塊設計中,模塊與模塊之間的連接也是必須考慮到的,從左端連接還是從右端連接,都直接影響到整個PCB板的設計。

總之,通過這次設計也收獲了很多,知識層面上,學得了很多新知識,解決問題的新方法,思考問題的新方向。實踐方面,提高了動手能力,提高了解決實際問題的能力等等。在思想上,更加明白的堅持不懈的重要性,學習探索的重要性,實踐動手的重要性。


5  參考文獻

【1】  《單片機基礎》第三版 李廣弟 朱月秀 冷祖祁 編著 北京航天大學出版社,2007

【2】 《數據結構》嚴蔚敏 編著  清華大學出版社


附錄1  元器件清單

(1)晶振12M一個

(2)stc89c52芯片一片

(3)30pf 2個;10uf 1個;

(4)40腳活動底座一個

(5)LCD液晶一個

(6)按鍵21個

(7)發光二極管1個

(8)9引腳排阻 1個

(9)680Ω 1個;10k 2個;1k  1個;10k滑動變阻器 1個; 10Ω 1個;

(10) 開關1個

(11) 5V有源蜂鳴器1個

(12) 三極管S8550一個

(13)排針若干,杜邦線若干


單片機源程序如下:


  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. …………
  411. …………
  412. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼


評分

參與人數 3黑幣 +61 收起 理由
DREAK + 5 很給力!
胡來的饅頭 + 6 很給力!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:342386 發表于 2018-6-13 19:10 | 顯示全部樓層
非常感謝 很有幫助!
回復

使用道具 舉報

ID:314053 發表于 2018-12-25 21:14 | 顯示全部樓層
牛人啊,大神啊。。。。厲害,膜拜
回復

使用道具 舉報

ID:450548 發表于 2018-12-26 08:37 | 顯示全部樓層
非常有用,感謝樓主!!
回復

使用道具 舉報

ID:450548 發表于 2018-12-26 10:05 | 顯示全部樓層
大神啊,寫的真詳細,里邊還有具體的說明。小白進階專用啊!!!
回復

使用道具 舉報

ID:404045 發表于 2018-12-27 12:39 | 顯示全部樓層
很強  感謝分享

回復

使用道具 舉報

ID:461954 發表于 2019-1-4 22:07 來自觸屏版 | 顯示全部樓層
這里邊的程序沒有蜂鳴的
回復

使用道具 舉報

ID:481555 發表于 2019-3-1 20:44 | 顯示全部樓層
寫的真詳細,里邊還有具體的說明。小白進階專用啊!!!
回復

使用道具 舉報

ID:262632 發表于 2019-3-20 19:15 | 顯示全部樓層
感謝樓主,給樓主點贊
回復

使用道具 舉報

ID:679940 發表于 2020-1-4 10:53 | 顯示全部樓層
xbdbox 發表于 2018-12-26 10:05
大神啊,寫的真詳細,里邊還有具體的說明。小白進階專用啊!!!

那他這個到底怎么連接啊,我用的單片機開發儀,不顯示東西啊
回復

使用道具 舉報

ID:374009 發表于 2020-4-8 12:44 | 顯示全部樓層
感謝感謝,好想學習
回復

使用道具 舉報

ID:281879 發表于 2020-4-8 14:34 | 顯示全部樓層
牛啊 很詳細 學習了
回復

使用道具 舉報

ID:743480 發表于 2020-5-3 18:03 | 顯示全部樓層
這個可以燒進89C51嗎?
回復

使用道具 舉報

ID:677756 發表于 2020-5-23 18:54 | 顯示全部樓層
感謝,幫助很大,就是發現的太晚了
回復

使用道具 舉報

ID:763852 發表于 2020-5-28 22:57 | 顯示全部樓層
謝謝樓主分享,幫助很大
回復

使用道具 舉報

ID:704379 發表于 2020-6-2 11:47 | 顯示全部樓層
寫的真的太好了,一直想找的內容
回復

使用道具 舉報

ID:701252 發表于 2020-10-17 09:20 | 顯示全部樓層
高手呀!!!
正在學習中!!!我一直想學習一下計算器的編程呢!謝謝樓主分享!
回復

使用道具 舉報

ID:861681 發表于 2020-12-19 13:59 來自觸屏版 | 顯示全部樓層
程序里沒有括號()啊,怎么混合四則運算
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 自拍 亚洲 欧美 老师 丝袜 | 欧美福利 | 亚洲国产aⅴ成人精品无吗 欧美激情欧美激情在线五月 | 欧美一二精品 | 综合久久久 | 日本免费在线 | 欧洲视频一区 | 亚洲一区二区三区免费视频 | 久久精品国产久精国产 | 在线免费观看黄色网址 | 亚洲乱码一区二区三区在线观看 | 国产高清美女一级a毛片久久w | 美日韩精品 | 中文字幕啪啪 | 黄色片免费 | 久久久激情视频 | 欧美一区二区在线观看 | 在线欧美a | 久久免费精品视频 | 国产免费人成xvideos视频 | 国产精品久久久久久久久久久久久久 | 欧美精品一区二区三区在线播放 | 一区二区三区免费 | 亚洲日本中文字幕在线 | 成人在线免费观看 | 精品国产一区探花在线观看 | 国产区高清 | 精品国产乱码久久久久久牛牛 | av网址在线| 一区二区三区精品视频 | 伊人免费在线 | 国产成人精品久久 | 国产精品一卡 | 国产分类视频 | 亚洲超碰在线观看 | 久久九九影视 | 国产在线一区观看 | 岛国午夜| 欧美性极品xxxx做受 | 小h片免费观看久久久久 | 在线国产一区二区 |