欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 30755|回復: 14
收起左側

基于51單片機計算器設計文檔

  [復制鏈接]
ID:3721 發表于 2016-6-12 23:46 | 顯示全部樓層 |閱讀模式
電氣工程項目綜合設計
設計文檔

1.1課題簡介
1.2設計目的
1.3設計任務
1.4 章節安排說明
2.1 單片機發展現狀
2.2 計算器系統現狀
2.3 簡易計算器系統簡介
3.1  MCS-51系列單片機簡介
3.2 其它器件簡介
3.2.1數碼管顯示
3.2.2矩陣按鍵
4.1 計算器硬件電路設計
4.2計算器程序設計
4.2.1存儲單元分配
4.2.2主程序設計
4.2.3數碼管顯示數據轉換子程序
4.2.4數碼管動態顯示子程序
4-3圖 系統總框圖:
4.4程序源代碼:
4.5硬件連線圖:
心得
參考文獻
附件:


1.1課題簡介
單片機由于其微小的體積和極低的成本,廣泛的應用于家用電器、工業控制等領域中。在工業生產中。單片機微型計算機是微型計算機的一個重要分支,也是頗具生命力的機種。單片機微型計算機簡稱單片機,特別適用于控制領域,故又稱為微控制器。
本系統就是充分利用了8051芯片的I/O引腳。系統統采用MSC-51系列單片機Intel8051為中心器件來設計計算器控制器,實現了能根據實際輸入值顯示并存儲,計算程序則是參照教材。至于位數和功能,如果有需要可以設計擴充原系統來實現 。
1.2設計目的
通過本次工程實踐,運用《智能化測量控制儀表原理與設計》、《MCS-51系列單片微型計算機及其應用》所學知識及查閱相關資料,完成簡易計算器的設計,達到理論知識與實踐更好結合、提高綜合運用所學知識和設計能力的目的。
通過本次設計訓練,可以使我們在基本思路和基本方法上對基于MCS-51單片機的嵌入式系統設計有一個比較感性的認識,并具備一定程度的設計能力。
1.3設計任務
在本次工程實踐中,主要完成如下方面的設計任務:
1)簡要綜述單片機技術發展的國內外現狀及數碼管動態顯示和矩陣鍵盤基本原理;
2)掌握MCS-51系列某種產品(例如8051)的最小電路及外圍擴展電路的設計方法;
3)了解單片機數據轉換功能及工作過程;
4)完成主要功能模塊的硬件電路設計及必要的參數確定;
5)用protues軟件完成原理電路的繪制;
6)完成系統設計說明書。
1.4 章節安排說
整個設計總共分為四個章節,第一章是前言部分,主要介紹了設計基于單片機簡易計算器的意義、目的及主要內容;第二章簡要介紹了單片機發展的國內外現狀及鍵盤掃描,數據轉換,和動態顯示原理進行了簡要的說明。第三章是器件簡介,這一部分主要介紹了系統的所用主要器件的選擇。第四章是系統詳細設計階段,分為硬件設計和程序設計。按照程序設計的各部分實現的功能不同,將整個軟件系統分成了三個塊,并對每一個功能塊所采用的元器件進行了詳細介紹。此外還編寫了主要功能模塊的基本程序,詳盡闡述了各模塊的工作過程。還有總流程圖,源代碼,硬器件鋪線圖。

2.1 單片機發展現狀
單片機的發展趨勢:低功耗CMOS化;微型單片化;主流與多品種共存;單片機從8位、16位到32位,數不勝數,應有盡有,有與主流C51系列兼容的,也有不兼容的,但它們各具特色,互成互補,為單片機的應用提供廣闊的天地。
縱觀單片機的發展過程,可以預示單片機的發展趨勢,大致有:
1)低功耗CMOS化
    MCS-51系列的8051推出時的功耗達630mW,而現在的單片機普遍都在100mW左右,隨著對單片機功耗要求越來越低,現在的各個單片機制造商基本都采用了CMOS(互補金屬氧化物半導體工藝)。象80C51就采用了HMOS(即高密度金屬氧化物半導體工藝)和CHMOS(互補高密度金屬氧化物半導體工藝)。CMOS雖然功耗較低,但由于其物理特征決定其工作速度不夠高,而CHMOS則具備了高速和低功耗的特點,這些特征,更適合于在要求低功耗象電池供電的應用場合。所以這種工藝將是今后一段時期單片機發展的主要途徑。
2)微型單片化
    現在常規的單片機普遍都是將中央處理器(CPU)、隨機存取數據存儲(RAM)、只讀程序存儲器(ROM)、并行和串行通信接口,中斷系統、定時電路、時鐘電路集成在一塊單一的芯片上,增強型的單片機集成了如A/D轉換器、PMW(脈寬調制電路)、WDT(看門狗)、有些單片機將LCD(液晶)驅動電路都集成在單一的芯片上,這樣單片機包含的單元電路就更多,功能就越強大。甚至單片機廠商還可以根據用戶的要求量身定做,制造出具有自己特色的單片機芯片。
    此外,現在的產品普遍要求體積小、重量輕,這就要求單片機除了功能強和功耗低外,還要求其體積要小。現在的許多單片機都具有多種封裝形式,其中SMD(表面封裝)越來越受歡迎,使得由單片機構成的系統正朝微型化方向發展。
3)主流與多品種共存
    現在雖然單片機的品種繁多,各具特色,但仍以80C51為核心的單片機占主流,兼容其結構和指令系統的有PHILIPS公司的產品
2.2 計算器系統現狀
計算器一般由運算器、控制器、存儲器、鍵盤、顯示器、電源和一些可選外圍設備及電子配件通過人工或機器設備組成。低檔計算器的運算器、控制器由數字邏輯電路實現簡單的串行運算,其隨機存儲器只有一、二個單元,供累加存儲用。高檔計算器由微處理器和只讀存儲器實現各種復雜的運算程序,有較多的隨機存儲單元以存放輸入程序和數據。鍵盤是計算器的輸入部件,一般采用接觸式或傳感式。為減小計算器的尺寸,一鍵常常有多種功能。顯示器是計算器的輸出部件,有發光二極管顯示器或液晶顯示器等。除顯示計算結果外,還常有溢出指示、錯誤指示等。計算器電源采用交流轉換器或電池,電池可用交流轉換器或太陽能轉換器再充電。為節省電能,計算器都采用CMOS工藝制作的大規模集成電路(見互補金屬-氧化物-半導體集成電路),并在內部裝有定時不操作自動斷電電路。計算器可選用的外圍設備有微型打印機、盒式磁帶機和磁卡機等。
2.3 簡易計算器系統簡介
本計算器是以MCS-51系列8051單片機為核心構成的簡易計算器系統。該系統通過單片機控制,實現對4*4鍵盤掃描進行實時的按鍵檢測,并把檢測數據存儲下來。整個計算器系統的工作過程為:首先存儲單元初始化,顯示初始值和鍵盤掃描,判斷按鍵位置,查表得出按鍵值,單片機則對數據進行儲存與相應處理轉換,之后送入數碼管動態顯示。整個系統可分為三個主要功能模塊:功能模塊一,實時鍵盤掃描;功能模塊二,數據轉換為了數碼管顯示;功能模塊三,數碼管動態顯示。
3.1  MCS-51系列單片機簡介
8051是MCS-51系列單片機的典型產品,以這一代表性的機型進行系統的講解。
   8051單片機包含中央處理器、程序存儲器(ROM)、數據存儲器(RAM)、定時/計數器、并行接口、串行接口和中斷系統等幾大單元及數據總線、地址總線和控制總線等三大總線,現在我們分別加以說明:
·中央處理器
中央處理器(CPU)是整個單片機的核心部件,是8位數據寬度的處理器,能處理8位二進制數據或代碼,CPU負責控制、指揮和調度整個單元系統協調的工作,完成運算和控制輸入輸出功能等操作。
·數據存儲器(RAM)
8051內部有128個8位用戶數據存儲單元和128個專用寄存器單元,它們是統一編址的,專用寄存器只能用于存放控制指令數據,用戶只能訪問,而不能用于存放用戶數據,所以,用戶能使用的RAM只有128個,可存放讀寫的數據,運算的中間結果或用戶定義的字型表。            
1.001.jpg
圖3-1 8051內部結構圖
·程序存儲器(ROM)
8051共有4096個8位掩膜ROM,用于存放用戶程序,原始數據或表格。
·定時/計數器(ROM)
8051有兩個16位的可編程定時/計數器,以實現定時或計數產生中斷用于控制程序轉向。
·并行輸入輸出(I/O)口:
8051共有4組8位I/O口(P0、 P1、P2或P3),用于對外部數據的傳輸。
·全雙工串行口
8051內置一個全雙工串行通信口,用于與其它設備間的串行數據傳送,該串行口既可以用作異步通信收發器,也可以當同步移位器使用。
·中斷系統:
8051具備較完善的中斷功能,有兩個外中斷、兩個定時/計數器中斷和一個串行中斷,可滿足不同的控制要求,并具有2級的優先級別選擇。
·時鐘電路:
8051內置最高頻率達12MHz的時鐘電路,用于產生整個單片機運行的脈沖時序,但8051單片機需外置振蕩電容。
單片機的結構有兩種類型,一種是程序存儲器和數據存儲器分開的形式,即哈佛(Harvard)結構,另一種是采用通用計算機廣泛使用的程序存儲器與數據存儲器合二為一的結構,即普林斯頓(Princeton)結構。INTEL的MCS-51系列單片機采用的是哈佛結構的形式,而后續產品16位的MCS-96系列單片機則采用普林斯頓結構。
下圖是MCS-51系列單片機的內部結構示意圖3-2。
1.002.jpg

圖3-2 MCS-51結構圖
MCS-51的引腳說明:
MCS-51系列單片機中的8031、8051及8751均采用40Pin封裝的雙列直接DIP結構,右圖是它們的引腳配置,40個引腳中,正電源和地線兩根,外置石英振蕩器的時鐘線兩根,4組8位共32個I/O口,中斷口線與P3口線復用。現在我們對這些引腳的功能加以說明:
MCS-51的引腳說明:
MCS-51系列單片機中的8031、8051及8751均采用40Pin封裝的雙列直接DIP結構,右圖是它們的引腳配置,40個引腳中,正電源和地線兩根,外置石英振蕩器的時鐘線兩根,4組8位共32個I/O口,中斷口線與P3口線復用。現在我們對這些引腳的功能加以說明:如圖3-3
1.003.jpg                                              
圖3-3雙列直插式封裝引腳圖
Pin9:RESET/Vpd復位信號復用腳,當8051通電,時鐘電路開始工作,在RESET引腳上出現24個時鐘周期以上的高電平,系統即初始復位。初始化后,程序計數器PC指向0000H,P0-P3輸出口全部為高電平,堆棧指針寫入07H,其它專用寄存器被清“0”。RESET由高電平下降為低電平后,系統即從0000H地址開始執行程序。然而,初始復位不改變RAM(包括工作寄存器R0-R7)的狀態,8051的初始態。
8051的復位方式可以是自動復位,也可以是手動復位。此外,RESET/Vpd還是一復用腳,Vcc掉電其間,此腳可接上備用電源,以保證單片機內部RAM的數據不丟失。見下圖3-4為兩種復位方式和兩種時鐘方式:
1.004.jpg 1.005.jpg

·Pin30:ALE/ 1.006.jpg 當訪問外部程序器時,ALE(地址鎖存)的輸出用于鎖存地址的低位字節。而訪問內部程序存儲器時,ALE端將有一個1/6時鐘頻率的正脈沖信號,這個信號可以用于識別單片機是否工作,也可以當作一個時鐘向外輸出。更有一個特點,當訪問外部程序存儲器,ALE會跳過一個脈沖。
如果單片機是EPROM,在編程其間,將用于輸入編程脈沖。            
·Pin29: 1.007.jpg 當訪問外部程序存儲器時,此腳輸出負脈沖選通信號,PC的16位地址數據將出現在P0和P2口上,外部程序存儲器則把指令數據放到P0口上,由CPU讀入并執行。
·Pin31:EA/Vpp程序存儲器的內外部選通線,8051和8751單片機,內置有4kB的程序存儲器,當EA為高電平并且程序地址小于4kB時,讀取內部程序存儲器指令數據,而超過4kB地址則讀取外部指令數據。如EA為低電平,則不管地址大小,一律讀取外部程序存儲器指令。顯然,對內部無程序存儲器的8031,EA端必須接地。
在編程時,EA/Vpp腳還需加上21V的編程電壓。
3.2 其它器件簡介3.2.1數碼管顯示
在本任務中用4位數碼管顯示當前數值的千,百,十,個,由于數碼管個數多,如采用靜態顯示方式,則占用單片機的I/O口線太多,如果用定時器/計數器的串行移位寄存器工作方式及外接串入并出移位寄存器74LS164的方式,則電路復雜。所以,在數碼管個數較多時,常采用動態顯示方式。
4位數碼管的相同段并聯在一起,由一個8位I/O(P1口)輸出字形碼控制顯示某一字形,每個數碼管的公共端由另外一個I/O口(P0口)輸出的字位碼控制,即數碼管顯示的字形是由單片機I/O口輸出的字形碼確定,而哪個數碼管點亮是由單片機I/O口輸出的字位碼確定的。4個數碼管分時輪流循環點亮,在同一時刻只有1個數碼管點亮,但由于數碼管具有余輝特性及人眼具有視覺暫留特性,所以適當地選取循環掃描頻率,看上去所有數碼管是同時點亮的,察覺不出閃爍現象。動態顯示方式所接數碼管不能太多,否則會因每個數碼管所分配的實際導通時間太少,使得數碼管的亮度不足。在本任務中,為了簡便,字形碼和字位碼都沒由加驅動電路,在實際應用中應加驅動電路。數碼管有共陰極和共陽極兩種,對于共陽數碼管,字形驅動輸出0有效,字位驅動輸出1有效;而對于共陰數碼管則相反,即:字形驅動輸出1有效,字位驅動輸出0有效。
3.2.2矩陣按鍵
鍵盤是單片機系統中最常用的人機對話輸入設備,用戶通過鍵盤向單片機輸入數據或指令。鍵盤控制程序需完成的任務有:監測是否有鍵按下,有鍵按下時,在無硬件去抖的動電路時,應用軟件延時方法消除按鍵抖動影響;當有多個鍵同時按下時,只處理一個按鍵,不管一次按鍵持續多長時間,僅執行一次按鍵功能程序。
矩陣按鍵掃描程序是一種節省IO口的方法,按鍵數目越多節省IO口就越可觀,思路:先判斷某一列(行)是否有按鍵按下,再判斷該行(列)是那一只鍵按下。但是,在程序的寫法上,采用了最簡單的方法,使得程序效率最高。本程序中,如果檢測到某鍵按下了,就不再檢測其它的按鍵,這完全能滿足絕大多數需要,又能節省大量的CPU時間。
本鍵盤掃描程序的優點在于:不用專門的按鍵延時程序,提高了CPU效率,也不用中斷來掃描鍵盤,節省了硬件資源。另外,本鍵盤掃描程序,每次掃描占用CPU時最短,不論有鍵按下或者無鍵按下都可以在很短的時間完成一次掃描。
本鍵盤掃描子程序名叫key,每次要掃描時用lcall key調用即可.

4.1 計算器硬件電路設計
8051單片機一片,4*4鍵盤一個,4位共陽極的七段數碼管一個,連線和電阻和開關若干。8051單片機的P2口作鍵盤口,其中P2.4-P2.7為鍵盤掃描輸出線,P2.0-P2.3為鍵盤掃描輸入線。鍵盤由4*4共16個按鍵組成,10個數字鍵(由0-9組成)5個運算符號(加減乘除等于)組成,1個清除鍵(作用相當于整體復位)。4個數碼管用于顯示當前數值的千,百,十,個,采用動態顯示方式,P1口接4個數碼管的七段,P0口分別接4個數碼管的公共端,P1口輸出數碼管的字形碼,P0口輸出數碼管的字位碼。
4.2計算器程序設計4.2.1存儲單元分配
30H單元:數值個位顯示單元;31H單元:數值十位顯示單元;32H單元:數值百位顯示單元;33H單元:數值千位顯示單元;23H單元:第一操作數存儲單元;24H單元:第二操作數存儲單元;25H單元:鍵值暫存單元;27H單元:清除鍵狀態;34H-37H單元:結果數據轉換暫存單元;38H-39H單元:結果高低8位暫存單元;R5單元:操作數計數單元;R4單元:操作數數值位數計數單元;R3單元:運算符號存儲單元。
4.2.2主程序設計
主程序進行程序中用到的一些存儲單元的初始化,數值顯示和4*4鍵盤掃描。首先,進行存儲單元初始化,給數碼管顯示單元30H-33H賦予“0000”字形數據,將數值計數單元,存儲單元,23H-25H,34H-37H,38H,39H,3AH,3BH,3CH,賦予初值零。之后,調用鍵盤掃描子程序,和數碼管顯示數據轉換程序,數碼管動態顯示子程序。主程序不斷進行鍵盤掃描,數碼管顯示數據轉換子程序和動態顯示子程序。
4.2.3數碼管顯示數據轉換子程序
由于數值單元存放的是二進制數,而用戶熟悉的是十進制數,所以應將數值單元中的二進制轉換為十進制數,即BCD碼。要通過數碼管顯示出當前數值,還必須將BCD碼進一步轉換為七段碼,轉換的最終結果數據存放于顯示緩沖區30H-33H單元中,其中30H單元存放數值的個位七段碼,31H單元存放數值的十位七段碼,32H單元存放數值的百位七段碼,33H單元存放數值的千位七段碼。
4.2.4數碼管動態顯示子程序
本任務由P1口輸出字形碼,P0口輸出字位碼。先將存放于30H單元的數值個位七段碼由P1口輸出,同時P0口輸出使數值個位顯示數碼管點亮的字位碼。由于采用的是共陽數碼管,所以只有該位數碼管對應的P0.0為1,其他位P0.1-P0.3位0,點亮延時10MS。然后P1口輸出數值十位七段碼,P0.1位1,數值十位數碼管點亮,延時10MS。接著P1口輸出數值百位七段碼,P0.2為1,數值百位數碼管點亮,延時10MS。最后P1口輸出數值千位七段碼,P0.3為1,數值千位數碼管點亮,延時10MS。
1.008.jpg
                                  4-3系統總框圖:
4.4程序源代碼
1.009.jpg
                                            圖4-4 程序輸入導出hex文件


4.5硬件連線圖
1.010.jpg
心得
設計是培養學生綜合運用所學知識,發現,提出,分析和解決實際問題,鍛煉實踐能力的重要環節,是對學生實際工作能力的具體訓練和考察過程.隨著科學技術發展的日新日異,單片機已經成為當今計算機應用中空前活躍的領域, 在生活中可以說得是無處不在。因此作為二十一世紀的大學來說掌握單片機的開發技術是十分重要的。
回顧起此次單片機設計,我仍感慨頗多,的確,從選題到定稿,從理論到實踐,可以說得是苦多于甜,但是可以學到很多很多的的東西。通過這次設計使我懂得了理論與實際相結合是很重要的,只有理論知識是遠遠不夠的,只有把所學的理論知識與實踐相結合起來,從理論中得出結論,才能真正為社會服務,從而提高自己的實際動手能力和獨立思考的能力。通過這次設計使我得到了一次用專業知識、專業技能分析和解決問題全面系統的鍛煉。使我們在單片機的基本原理、單片機應用系統開發過程,以及在常用編程設計思路技巧的掌握方面都能向前邁了一大步,為日后成為合格的應用型人才打下良好的基礎。
參考文獻
[1] 徐愛鈞 .智能化測量控制儀表原理與設計(第二版).北京航天航空大學出版社,2004.9
[2] 孫育才等.MCS-51系列單片微型計算機及其應用(第4版).東南大學出版社,2004,3
[3] 李萍 等.智能儀器實驗指導書.大連交通大學,2007.9

[4]王明亮等. 廣播.電視調頻發送技術,上、下冊. 北京: 中國廣播電視出版社,1993

[5]梁延貴. 遙控電路可控硅觸發電路語音電路分冊 北京: 科學技術文獻出版社,2002

[6] 李華. MCS-51系列單片機實用接口技術. 北京: 航天航空大學出版社,1999

[7] 邱關源.電路.高等教育出版社.1989.第三版.

[8] 焦李成.電流模式信號處理的進展與展望.電子學報.1992.20(7):87-92

[9] 張肅文,陸兆文. 高頻電子電路.高等教育出版社.1993.第三版.

[10] 康光華,陳大欽. 電子技術基礎(模擬部分).高等教育出版社.1999.6.第四版.

[11] 陳汝全.  電子技術常用器件手冊.北京:機械工業出版社,1994

[12] 魯兵,楊楚民. 基于單片機系統的顯示接口.機械與電子出版社,1992

評閱人:
   年   月   日


  1. #include   //頭文件
  2. #define uint unsigned int //
  3. #define uchar unsigned char

  4. sbit lcden=P2^3; //定義引腳
  5. sbit rs=P2^4;
  6. sbit rw=P2^0;
  7. sbit busy=P0^7;

  8. char i,j,temp,num,num_1;
  9. long a,b,c;     //a,第一個數 b,第二個數 c,得數
  10. float a_c,b_c;
  11. uchar flag,fuhao;//flag表示是否有符號鍵按下,fuhao表征按下的是哪個符號

  12. uchar code table[]={
  13. 7,8,9,0,
  14. 4,5,6,0,
  15. 1,2,3,0,
  16. 0,0,0,0};
  17. uchar code table1[]={
  18. 7,8,9,0x2f-0x30,
  19. 4,5,6,0x2a-0x30,
  20. 1,2,3,0x2d-0x30,
  21. 0x01-0x30,0,0x3d-0x30,0x2b-0x30};

  22. void delay(uchar z) // 延遲函數
  23. {
  24. uchar y;
  25. for(z;z>0;z--)
  26.    for(y=0;y<110;y++);
  27. }

  28. void check() // 判斷忙或空閑
  29. {
  30. do{
  31.     P0=0xFF;
  32.     rs=0;     //指令
  33.     rw=1;     //讀
  34.     lcden=0;     //禁止讀寫
  35.     delay(1); //等待,液晶顯示器處理數據
  36.     lcden=1;     //允許讀寫
  37.     }while(busy==1); //判斷是否為空閑,1為忙,0為空閑
  38. }
  39. void write_com(uchar com) // 寫指令函數
  40. {
  41. P0=com;    //com指令付給P0口
  42. rs=0;
  43. rw=0;
  44. lcden=0;
  45. check();
  46. lcden=1;
  47. }

  48. void write_date(uchar date) // 寫數據函數
  49. {
  50.     P0=date;
  51. rs=1;
  52. rw=0;
  53. lcden=0;
  54. check();
  55. lcden=1;
  56. }

  57. void init() //初始化
  58. {
  59.     num=-1;
  60. lcden=1; //使能信號為高電平
  61. write_com(0x38); //8位,2行
  62. write_com(0x0c); //顯示開,光標關,不閃爍*/
  63. write_com(0x06); //增量方式不移位 顯竟獗暌貧 柚?
  64. write_com(0x80); //檢測忙信號
  65. write_com(0x01); //顯示開,光標關,不閃爍
  66. num_1=0;
  67. i=0;
  68. j=0;
  69. a=0;     //第一個參與運算的數
  70. b=0;     //第二個參與運算的數
  71. c=0;
  72. flag=0; //flag表示是否有符號鍵按下,
  73. fuhao=0; // fuhao表征按下的是哪個符號
  74. }
  75. void keyscan() // 鍵盤掃描程序
  76. {

  77. P3=0xfe;
  78. if(P3!=0xfe)
  79. {
  80.    delay(20); 延遲20ms
  81.    if(P3!=0xfe)
  82.    {
  83.     temp=P3&0xf0;
  84.     switch(temp)
  85.     {
  86.      case 0xe0:num=0;
  87.        break;
  88.      case 0xd0:num=1;
  89.        break;
  90.      case 0xb0:num=2;
  91.        break;
  92.      case 0x70:num=3;
  93.        break;
  94.     }
  95.    }
  96.    while(P3!=0xfe);
  97.    if(num==0||num==1||num==2)//如果按下的是'7','8'或'9
  98.    {
  99.        if(j!=0)
  100.         {
  101.           write_com(0x01);
  102.           j=0;
  103.          }
  104.        if(flag==0)//沒有按過符號鍵
  105.     {
  106.      a=a*10+table[num];
  107.     }
  108.     else//如果按過符號鍵
  109.     {
  110.      b=b*10+table[num];
  111.     }
  112.    }
  113.    else//如果按下的是'/'
  114.    {
  115.     flag=1;
  116.     fuhao=4;//4表示除號已按
  117.    }
  118.    i=table1[num];
  119.    write_date(0x30+i);
  120. }

  121. P3=0xfd;
  122. if(P3!=0xfd)
  123. {
  124.    delay(5);
  125.    if(P3!=0xfd)
  126.    {
  127.     temp=P3&0xf0;
  128.     switch(temp)
  129.     {
  130.      case 0xe0:num=4;
  131.          break;
  132.       
  133.      case 0xd0:num=5;
  134.          break;
  135.       
  136.      case 0xb0:num=6;
  137.          break;
  138.       
  139.      case 0x70:num=7;
  140.          break;
  141.     }
  142.    }
  143.    while(P3!=0xfd);
  144.    if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
  145.    {
  146.     if(j!=0)
  147.         {
  148.           write_com(0x01);
  149.           j=0;
  150.          }
  151.        if(flag==0)//沒有按過符號鍵
  152.     {
  153.      a=a*10+table[num];
  154.     }
  155.     else//如果按過符號鍵
  156.     {
  157.      b=b*10+table[num];
  158.     }
  159.    }
  160.    else//如果按下的是'/'
  161.    {
  162.     flag=1;
  163.     fuhao=3;//3表示乘號已按
  164.    }
  165.    i=table1[num];
  166.    write_date(0x30+i);
  167. }

  168. P3=0xfb;
  169. if(P3!=0xfb)
  170. {
  171.    delay(5);
  172.    if(P3!=0xfb)
  173.    {
  174.     temp=P3&0xf0;
  175.     switch(temp)
  176.     {
  177.      case 0xe0:num=8;
  178.          break;
  179.       
  180.      case 0xd0:num=9;
  181.          break;
  182.       
  183.      case 0xb0:num=10;
  184.          break;
  185.       
  186.      case 0x70:num=11;
  187.          break;
  188.     }
  189.    }
  190.    while(P3!=0xfb);
  191.    if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
  192.    {
  193.     if(j!=0)
  194.         {
  195.           write_com(0x01);
  196.           j=0;
  197.          }
  198.       if(flag==0)//沒有按過符號鍵
  199.     {
  200.      a=a*10+table[num];
  201.     }
  202.     else//如果按過符號鍵
  203.     {
  204.      b=b*10+table[num];
  205.     }
  206.    }
  207.    else if(num==11)//如果按下的是'-'
  208.    {
  209.     flag=1;
  210.     fuhao=2;//2表示減號已按
  211.    }
  212.    i=table1[num];
  213.    write_date(0x30+i);
  214. }

  215. P3=0xf7;
  216. if(P3!=0xf7)
  217. {
  218.    delay(5);
  219.    if(P3!=0xf7)
  220.    {
  221.     temp=P3&0xf0;
  222.     switch(temp)
  223.     {
  224.      case 0xe0:num=12;
  225.          break;
  226.       
  227.      case 0xd0:num=13;
  228.          break;
  229.       
  230.      case 0xb0:num=14;
  231.          break;
  232.       
  233.      case 0x70:num=15;
  234.          break;
  235.     }
  236.    }
  237.    while(P3!=0xf7);
  238.    switch(num)
  239.    {
  240.     case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
  241.      break;
  242.     case 13:{                //按下的是"0"
  243.        if(flag==0)//沒有按過符號鍵
  244.        {
  245.         a=a*10;
  246.         write_date(0x30);
  247.         P1=0;
  248.        }
  249.        else if(flag==1)//如果按過符號鍵
  250.        {
  251.         b=b*10;
  252.         write_date(0x30);
  253.         }
  254.       }
  255.      break;
  256.     case 14:{j=1;
  257.            if(fuhao==1){write_com(0x80+0x4f);//按下等于鍵,光標前進至第二行最后一個顯示處
  258.            write_com(0x04);     //設置從后住前寫數據,每寫完一個數據,光標后退一格
  259.            c=a+b;
  260.            while(c!=0)
  261.            {
  262.              write_date(0x30+c%10);
  263.              c=c/10;
  264.            }
  265.            write_date(0x3d);     //再寫"="
  266.            a=0;b=0;flag=0;fuhao=0;
  267.            }
  268.       else if(fuhao==2){write_com(0x80+0x4f);//光標前進至第二行最后一個顯示處
  269.             write_com(0x04);     //設置從后住前寫數據,每寫完一個數據,光標后退一格(這個照理說順序不對,可顯示和上段一樣)
  270.            if(a-b>0)
  271.              c=a-b;
  272.            else
  273.              c=b-a;
  274.            while(c!=0)
  275.            {
  276.              write_date(0x30+c%10);
  277.              c=c/10;
  278.            }
  279.            if(a-b<0)
  280.              write_date(0x2d);
  281.            write_date(0x3d);     //再寫"="           
  282.            a=0;b=0;flag=0;fuhao=0;
  283.           }
  284.       else if(fuhao==3){write_com(0x80+0x4f);
  285.             write_com(0x04);
  286.              c=a*b;
  287.              while(c!=0)
  288.              {
  289.              write_date(0x30+c%10);
  290.              c=c/10;
  291.              }
  292.              write_date(0x3d);     
  293.           a=0;b=0;flag=0;fuhao=0;
  294.              }
  295.       else if(fuhao==4){write_com(0x80+0x4f);
  296.             write_com(0x04);
  297.             i=0;
  298.             c=(long)(((float)a/b)*1000);
  299.             while(c!=0)
  300.              {
  301.                write_date(0x30+c%10);
  302.                c=c/10;
  303.            i++;
  304.            if(i==3)
  305.                write_date(0x2e);
  306.              }
  307.             if(a/b<=0)
  308.               write_date(0x30);
  309.             write_date(0x3d);                              
  310.             a=0;b=0;flag=0;fuhao=0;
  311.                     }
  312.       }
  313.      break;
  314.      case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;}
  315.      break;
  316.    }
  317. }
  318. }

  319. main()
  320. {
  321. init();
  322. while(1)
  323. {
  324.    keyscan();
  325. }
  326. }
復制代碼

word格式下載: 基于51單片機計算器設計.docx (191.92 KB, 下載次數: 117)

回復

使用道具 舉報

ID:126449 發表于 2016-6-13 00:48 來自觸屏版 | 顯示全部樓層
好棒,頂一個
回復

使用道具 舉報

ID:126696 發表于 2016-6-14 16:20 來自觸屏版 | 顯示全部樓層
真是大好人啊 論文都給了
回復

使用道具 舉報

ID:128087 發表于 2016-6-25 15:25 來自觸屏版 | 顯示全部樓層
感謝樓主 !!!
回復

使用道具 舉報

ID:145691 發表于 2016-11-2 13:59 | 顯示全部樓層
能不能進行負數計算
回復

使用道具 舉報

ID:145691 發表于 2016-11-2 14:27 | 顯示全部樓層
程序為啥會出錯呢
回復

使用道具 舉報

ID:200060 發表于 2017-6-7 22:22 | 顯示全部樓層
為什么我的電路圖出不來
回復

使用道具 舉報

ID:219259 發表于 2017-7-12 23:02 | 顯示全部樓層
led不顯示怎么辦啊
回復

使用道具 舉報

ID:219418 發表于 2017-7-13 22:28 | 顯示全部樓層
棒棒棒,頂頂頂
回復

使用道具 舉報

ID:244546 發表于 2017-11-1 11:24 | 顯示全部樓層
仿真用的數碼管 怎么看源碼用的液晶
回復

使用道具 舉報

ID:247636 發表于 2017-11-10 09:24 來自觸屏版 | 顯示全部樓層
謝謝樓主分享
回復

使用道具 舉報

ID:361498 發表于 2018-6-29 10:26 | 顯示全部樓層
為什么顯示不出來
回復

使用道具 舉報

ID:777318 發表于 2020-6-12 16:10 | 顯示全部樓層
明天你好LJN 發表于 2017-6-7 22:22
**** 作者被禁止或刪除 內容自動屏蔽 ****

我的P0也是灰色的
回復

使用道具 舉報

ID:777318 發表于 2020-6-12 16:49 | 顯示全部樓層
這個P0是懸空的啊,怎么亮起來的啊?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表