2018-6-12 15:05 上傳
點擊文件名下載附件
單片機課程設計
設計課題 基于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)排針若干,杜邦線若干
單片機源程序如下:
- #include <REGX51.H>
- #include<intrins.h>
- #include<stdio.h>
- #include<string.h>
- #include<math.h>
- sbit RS = P2^5;
- sbit RW = P2^6;
- sbit E = P2^7;
- #define Data P0//數據端口
- //全局變量
- float num1;//第一操作數num1 (初始為零)
- float num2;//第二操作數num2 (初始為零)
- char yun_flag='+';//運算符號 yun_flag (默認為+ )
- char key_last;//上次按鍵狀態標志 key_last
- char sqrt_flag;//開方鍵按下標志 sqrt_flag
- unsigned long pos_flag=1;//小數位權pos_flag (默認為1)
- char neg_flag;//正負標志 neg_flag
- char data c_num1[15]=" ";//c_num1 字符型第一操作數 (數組不定義大小與其他變量沖突)
- char data c_num2[15]=" ";//c_num2 字符型第二操作數
- char error;//運算法則錯誤;
- char len;//小數點后位數
- /* 微秒延時函數 */
- /******************************************************************/
- void DelayUs(unsigned char us)//delay us
- {
- unsigned char uscnt;
- uscnt=us>>1; /*12MHz頻率*/
- while(--uscnt);
- }
- /******************************************************************/
- /* 毫秒函數聲明 */
- /******************************************************************/
- void DelayMs(unsigned char ms)
- {
- while(--ms)
- {
- DelayUs(250);
- DelayUs(250);
- DelayUs(250);
- DelayUs(250);
- }
- }
- /******************************************************************/
- /* 寫入命令函數 */
- /******************************************************************/
- void WriteCommand(unsigned char c)
- {
- DelayMs(5);//操作前短暫延時,保證信號穩定
- E=0;
- RS=0;
- RW=0;
- _nop_();
- E=1;
- Data=c;
- E=0;
- }
- /******************************************************************/
- /* 寫入數據函數 */
- /******************************************************************/
- void WriteData(unsigned char c)
- {
- DelayMs(5); //操作前短暫延時,保證信號穩定
- E=0;
- RS=1;
- RW=0;
- _nop_();
- E=1;
- Data=c;
- E=0;
- RS=0;
- }
- /******************************************************************/
- /* 寫入字節函數 */
- /******************************************************************/
- void ShowChar(unsigned char pos,unsigned char c)
- {
- unsigned char p;
- if (pos>=0x10)
- p=pos+0xb0; //是第二行則命令代碼高4位為0xc
- else
- p=pos+0x80; //是第二行則命令代碼高4位為0x8
- WriteCommand (p);//寫命令
- WriteData (c); //寫數據
- }
- /******************************************************************/
- /* 寫入字符串函數 */
- /******************************************************************/
- void ShowString (unsigned char line,char *ptr)
- {
- unsigned char l,i;
- l=line<<4;
- for (i=0;*(ptr+i)!='\0';i++)
- ShowChar (l++,*(ptr+i));//循環顯示16個字符
- }
- /******************************************************************/
- /* 初始化函數 */
- /******************************************************************/
- void InitLcd()
- {
- DelayMs(15);
- WriteCommand(0x38); //display mode
- WriteCommand(0x38); //display mode
- WriteCommand(0x38); //display mode
- WriteCommand(0x06); //顯示光標移動位置
- WriteCommand(0x0c); //顯示開及光標設置
- WriteCommand(0x01); //顯示清屏
- }
- /*************按鍵掃描****************************/
- char scan()
- {
- char h_data,l_data,i,key_num;
- P2=P2&0XE0;//P2低5位送0
- P1=P1|0X0F;//P1低4位送1
- while((P1|0xf0)==0xff)//判斷P1低4位是否全為1
- {
- while((P1|0xf0)==0xff);
- DelayMs(10);//延時10ms
- }
- l_data=~(P1|0xf0);//記入列標志
- P2=P2|0X1F;//P2低五位送1
- P1=P1&0XF0;//P1低四位送0
- h_data=~(P2|0xe0);//記入行標志
- for(i=0;i<=4;i++)//計算行號(0~4)
- {
- if(h_data==1)break;
- h_data=h_data>>1;
- }
- h_data=i;//行號
- for(i=1;i<=4;i++)//計算列號(1~4)
- {
- if(l_data==1)break;
- l_data=l_data>>1;
- }
- l_data=i;//列號
- key_num=h_data*4+l_data;
-
- P2=P2&0XE0;//P2低5位送0
- P1=P1|0X0F;//P1低4位送1
- while((P1|0xf0)!=0xff)//判斷P1低4位是否全為1
- {
- while((P1|0xf0)!=0xff);
- DelayMs(10);//延時10ms
- }
- return key_num;
- }
- void float_to_char(float a,char* p)
- {
- char i,flag,length;
- flag=0;
- sprintf(p,"%f",a);
- length=strlen (p);
- for(i=0;i<length;i++)
- {
- if(*(p+i)=='.')flag=1;
- }
- if(flag==1)
- for(i=length-1;i>=0;i--)
- {
- if(*(p+i)=='.'){*(p+i)='\0';break;}
- if(*(p+i)!='0'){*(p+i+1)='\0';break;}
- }
- }
- /**********************更新液晶*************************/
- void refresh()//更新液晶
- {
- char length,i,j;
- char dot;
- dot=0;
-
- float_to_char(num2,c_num2);//num2轉為字符型
- length=strlen(c_num2);
- for(i=0,j=0;i<length;i++)
- {
- if(c_num2[i]=='.')
- dot=1;
- if(dot==1)
- j++;
- }
- if(j<len)
- {
- if(dot==1)
- {
- for(i=length;i<(length+len-j);i++)
- {
- c_num2[i]='0';
-
- }
- c_num2[i]='\0';
- }
- else
- {
-
- c_num2[length]='.';
- if(len-j>1)
- {
- for(i=length+1;i<(length+len-j);i++)
- c_num2[i]='0';
- }
- c_num2[length+len-j]='\0';
- }
- }
- if(neg_flag==1)//'+/-'按下首位加‘-’
- {
- length=strlen(c_num2);//計算c_num2長度
- for(i=length-1;i>=0;i--)
- {
- c_num2[i+1]=c_num2[i];
- }
- c_num2[length+1]='\0';
- c_num2[0]='-';
- }
-
- if(sqrt_flag==1)
- {
- length=strlen(c_num2);//計算c_num2長度
- for(i=length-1;i>=0;i--)
- {
- c_num2[i+1]=c_num2[i];
- }
- c_num2[length+1]='\0';
- c_num2[0]=0xe8;//字符根號
- }
-
-
- if(error==0)
- {
- float_to_char(num1,c_num1);//num1轉為字符型
- WriteCommand(0x01); //顯示清屏
- ShowString(0,c_num1);
- ShowString(1,c_num2);
- ShowChar(15,yun_flag);
- }else
- {
- WriteCommand(0x01); //顯示清屏
- ShowString(0,"error!!!");
- }
- }
- //鍵值處理
- void operation1(char keynum)//按下 ’+、-、*、/處理
- {
- if(key_last==1)//上次按鍵為 數字、小數點、+/-、sqrt
- {
- if(neg_flag==1)num2=-num2;//'+/-'按下
- if(sqrt_flag==1)//sqrt按下
- {
- if(num2>=0)
- num2=sqrt(num2);
- else
- error=1;
- }
- if(yun_flag=='+')num1=num1+num2; //按下的是‘+’
- if(yun_flag=='-')num1=num1-num2;//按下的是‘-’
- if(yun_flag=='*')num1=num1*num2;//按下的是‘*’
- if(yun_flag=='/')//按下的是‘/’
- {
- if(num2!=0)
- num1=num1/num2;
- else
- error=1;
- }
- num2=0;//num2清零
- sqrt_flag=0;//sqrt_flag清零
- neg_flag=0;//neg_flag清零
- pos_flag=1;//pos_flag回1
- }
- if(keynum==4)yun_flag='+';//yun_flag更新
- if(keynum==8)yun_flag='-';
- if(keynum==12)yun_flag='*';
- if(keynum==16)yun_flag='/';
- len=0;
- key_last=0;//key_last更新
- refresh();
- }
- //////////////////////////////////////////////////////
- void operation2(char keynum)//輸入數字
- {
- float Data1;
-
- if(keynum==1)Data1=7;//分析輸入數字
- if(keynum==2)Data1=8;
- if(keynum==3)Data1=9;
- if(keynum==5)Data1=4;
- if(keynum==6)Data1=5;
- if(keynum==7)Data1=6;
- if(keynum==9)Data1=1;
- if(keynum==10)Data1=2;
- if(keynum==11)Data1=3;
- if(keynum==13)Data1=0;
- if(pos_flag==1)//更新num2
- num2=num2*10+Data1;
- else
- {
- num2=num2+(Data1/pos_flag);
- pos_flag=pos_flag*10;
- len++;
- }
- key_last=1;//更新key_last
- refresh();
- }
- ////////////////////////////////////////////////////////////
- void operation3()//輸入小數點
- {
- if(pos_flag==1)//首次出現小數點
- {
- pos_flag=pos_flag*10;//小數位權*10
- len++;
- }
- key_last=1;//更新key_last
- refresh();//更新液晶
- }
- /////////////////////////////////////////////////////
- void operation4()//輸入'='
- {
- if(neg_flag==1)num2=-num2;//'+/-'按下
- if(sqrt_flag==1)//sqrt按下
- {
- if(num2>=0)
- num2=sqrt(num2);
- else
- error=1;
- }
- if(yun_flag=='+')num1=num1+num2; //按下的是‘+’
- if(yun_flag=='-')num1=num1-num2;//按下的是‘-’
- if(yun_flag=='*')num1=num1*num2;//按下的是‘*’
- if(yun_flag=='/')//按下的是‘/’
- {
- if(num2!=0)
- num1=num1/num2;
- else
- error=1;
- }
- num2=0;//num2清零
- sqrt_flag=0;//sqrt_flag清零
- neg_flag=0;//neg_flag清零
- pos_flag=1;//pos_flag回1
- yun_flag='+';//yun_flag更新
- len=0;
- key_last=0;//key_last更新
- refresh();
- }
- ////////////////////////////////////////////////////
- void operation5()//輸入clear all
- {
- num1=0;// num1清零
- num2=0;//num2清零
- sqrt_flag=0;//清sqrt_flag
- neg_flag=0;// 清neg_flag
- pos_flag=1;// Pos_flag=1
- yun_flag='+';// yun_flag(為'+')
- error=0;//清error
- len=0;
- key_last=0;//更新key_flag
- refresh();//更新液晶
- }
- ///////////////////////////////////////////////////////
- void operation6()//輸入'C'
- {
- num2=0;//num2清零
- sqrt_flag=0;//清sqrt_flag
- neg_flag=0;//清neg_flag
- pos_flag=1;//pos_flag=1
- len=0;
- key_last=0;//key_last
- refresh();//更新液晶
- }
- ////////////////////////////////////////////////////////////
- void operation7()//輸入'+/-'
- {
- if(neg_flag==0)//neg_flag反轉
- neg_flag=1;
- else neg_flag=0;
- key_last=1;//key_last
- refresh();// 更新液晶
- }
- /////////////////////////////////////////////////////////////
- void operation8()//輸入'sqrt'
- {
- if(sqrt_flag==0)//sqrt_flag反轉
- sqrt_flag=1;
- else sqrt_flag=0;
- key_last=1;//更新key_last
- refresh();//更新液晶
- }
- //鍵值分析
- void key(char keynum)
- {
- switch(keynum)
- {
- case 4 :
- case 8 :
- case 12:
- case 16://+、-、*、/
- {
- if(error==0)
- operation1(keynum);
- break;}
-
- case 1 : //數字7
- case 2 : //數字8
- case 3 : //數字9
- case 5 : //數字4
- case 6 : //數字5
- case 7 : //數字6
- case 9 : //數字1
- case 10 : //數字2
- case 11 : //數字3
- case 13 : //數字0
- {
- if(error==0)
- operation2(keynum);
- …………
- …………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼