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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機的簡易計算器課程設計報告書

[復制鏈接]
跳轉到指定樓層
樓主
ID:272736 發表于 2018-1-7 14:58 | 只看該作者 回帖獎勵 |正序瀏覽 |閱讀模式
課程設計報告書

課程名稱:
題    目:
系 (院):電子工程學院自動化
學    期:2016-2017第一學期
專業班級:自動化141
姓    名:*
學    號:2014121036

評語:
成績:
簽名:
日期:

[摘要] 近幾年單片機技術的發展很快,其中電子產品的更新速度迅猛。計算器是日常生活中比較的常見的電子產品之一。如何才能使計算器技術更加的成熟,充分利用已有的軟件和硬件條件,設計出更出色的計算器呢。

本設計是以AT89C52單片機為核心的計算器模擬系統設計。矩陣按鍵輸入、LCD1602液晶顯

示,構成一套可以運算兩個數之間的加減乘除的設計。最大運算是:9999*9999,可以運算負數。

科技的進步告別了以前復雜的模擬電路,一塊幾厘米平方的單片機可以省去很多繁瑣的電路。現在應用較廣泛的是科學計算器,與我們日常所用的簡單計算器有較大差別,除了能進行加減乘除,科學計算器還可以進行正數的四則運算和乘方、開方運算,具有指數、對數、三角函數、反三角函數及存儲等計算功能。計算器的未來是小型化和輕便化,現在市面上出現的使用太陽能電池的計算器,使用ASIC設計的計算器,如使用純軟件實現的計算器等,未來的智能化計算器將是我們的發展方向,更希望成為應用廣泛的計算工具。


目錄

第一章 前言
1.1 系統開發背景
1.2 系統開發意義
1.3 設計目的
第二章 方案論證
2.1 方案構思
2.2  方案比較與選擇
第三章 系統硬件設計及說明
3.1系統組成及總體框圖
3.2元件簡介
3.2.1 AT89C52特點
3.2.2 LCD1602液晶顯示屏
第四章 設計原理分析
4.1  設計方案的確定
4.2計算器硬件方案及硬件資源分配
4.2.1 硬件資源分配
4.2.2 系統的硬件設計
4.2.3 鍵盤電路的設計
4.2.4 顯示電路的設計
第五章 計算器的軟件設計
5.1計算器的軟件規劃
5.2 匯編語言和C語言的特點及選擇
5.3 按鍵鍵掃描程序設計
5.4 算術運算程序設計
5.5 顯示程序設計
第六章 系統調試與存在的問題
6.1 硬件調試
6.2 軟件調試
結束語
致謝
參考文獻
附錄
附錄一:硬件實物圖
附錄二:系統程序清單


第一章 前言
1.1 系統開發背景
隨著社會的發展,科學的進步,人們的生活水平在逐步的提高,尤其是微電子技術的發展,猶如雨后春筍般的變化。電子產品的更新速度快就不足驚奇了。計算器在人們的日常中是比較的常見的電子產品之一。如何使計算器技術更加的成熟,充分利用已有的軟件和硬件條件,設計出更出色的計算器,使其更好的為各個行業服務,成了如今電子領域重要的研究課題。
1.2 系統開發意義
今天,人們的日常生活中已經離不開計算器了,社會的各個角落都有它的身影,比如商店,辦公室,學校……。因此設計一款簡單實用的計算器會有很大的實際意義。
1.3 設計目的
本設計旨在進一步掌握單片機理論知識,理解嵌入式單片機系統的硬軟件設計,加強對實際應用系統設計的能力。通過本設計的學習,使我掌握單片機程序設計和微機接口應用的基本方法,并能綜合運用本科階段所學軟、硬件知識分析實際問題,提高解決畢業設計實際問題的能力,為單片機應用和開發打下良好的基礎。
1、對字符液晶顯示模塊的工作原理,如初始化、清屏、顯示、調用及外特性有較清楚的認識,并會使用LCD(液晶顯示模塊)實現計算結果的顯示;掌握液晶顯示模塊的驅動和編程,設計LCD和單片機的接口電路,以及利用單片機對液晶模塊的驅動和操作;
2、在充分分析內部邏輯的概念,進行軟件和調試,學會使用,并能夠以其為平臺設計出具有四則運算能力簡易計算器的硬件電路和軟件程序。

第二章 方案論證

2.1 方案構思
本設計可以采用兩種方案,一種是以FPGA為核心處理芯片,配備相應的外設;另外一種是以AT89S52處理器,配備相應的外設。
1、方案一:采用FPGA控制
FPGA是一種高密度的可編程邏輯器件,自從Xilinx公司1985年推出第一片FPGA以來,FPGA的集成密度和性能提高很快,其集成密度最高達500萬門/片以上,系統性能可達200MHz。由于FPGA器件集成度高,方便易用,開發和上市周期短,在數字設計和電子生產中得到迅速普及和應用,并一度在高密度的可編程邏輯器件領域中獨占鰲頭。
但是而基于 SRAM編程的FPGA,其編程信息需存放在外部存儲器上 ,需外部存儲器芯片 ,且使用方法復雜 ,保密性差,而其對于一個簡單的計算器而言,實用FPGA有點大材小用,成本太高。
2、方案二:采用AT89S52
單片機是單片微型機的簡稱,故又稱為微控制器MCU(Micro Control Unit)。通常由單塊集成電路芯片組成,內部包含有計算機的基本功能部件:中央處理器CPU,存儲器和I/O接口電路等。因此,單片機只要和適當的軟件及外部設備相結合,便可成為一個單片機控制系統。單片機廣泛用于智能產品,智能儀表,測控技術,智能接口等,具有操作簡單,實用方便,價格便宜等優點,而其中AT89S52以MCS-51為內核,是單片機中最典型的代表,應用于各種控制領域。

2.2  方案比較與選擇
通過以上兩種方案論證和比較,從設計的實用性,方便性和成本出發,選擇了以AT89S52單片機作為中央處理單元進行計算器的設計,這樣設計能夠實現對四位加減乘除和除法四位小點數的運算。

第三章 系統硬件設計及說明

3.2.2 LCD1602液晶顯示屏
1、應用簡介
模塊內部自帶字符發生存儲器(CGROM),字符有:阿拉伯數字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有一個固定的代碼,比如大寫的英文字母“A”的代碼是(41H),顯示時模塊把代碼41H發給液晶模塊,我們就能在液晶上看到字母“A”。
1602液晶模塊內部的控制器共有11條控制指令,豐富的指令可以完成液晶的時序控制、工作方式式設置和數據顯示等。
采用的LCD1602液晶模塊是標準16針插座,接口電路如圖3.2.3所示:關于LCD1602的詳細資料見表3.2.3-1和表3.2.3-2。


圖3.2.3 LCD接口電路


表3.2.3-1 LCD1602引腳說明
第1腳
VSS為地電源
第2腳
VDD接5V正電源
第3腳
V0為液晶顯示器對比度調整端,接正電源時對比度最弱,接地電源時對比度最高,對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度。
實際電路中采用2K電阻到地,比較理想。
第4腳
RS為寄存器選擇,高電平選擇數據寄存器、低電平選擇指令寄存器。
第5腳
RW為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。
當RS和RW共同為低電平時  (00)可以寫入指令或者顯示地址;
當RS為低電平RW為高電平時(01)可以讀入忙信號;
當RS為高電平RW為低電平時(10)可以寫入數據。
第6腳
E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執行命令。
第7~14腳
D0~D7為8位雙向數據線。
第15~16腳
背光陽極和背光陰極。


表3.2.3-2 LCD1602指令表
指令1
清顯示     指令碼01H, 光標復位到地址00H位置;
指令2
光標復位   指令碼02H, 光標返回到地址00H位置 ;
指令3
光標和顯示模式設置
I/D位 → 光標移動方向,高電平右移,低電平左移;
S  位 → 屏幕上所有文字是否左移或者右移,高電平有效,低電平無效;
指令4
顯示開關控制
D  位 → 控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示;
C  位 → 控制光標的開與關,高電平表示有光標,低電平表示無光標;   
    B  位 → 控制光標是否閃爍,高電平閃爍,低電平不閃爍 ;
指令5
光標或顯示移位
S/C位 → 高電平時移動顯示的文字,低電平時移動光標
指令6
功能命令設置
DL位---高電平時為4位數據總線,低電平時為8位總線;
N—位低電平時為單行顯示,高電平時為雙行顯示;
F—位低電平時顯示5x7的點陣字符,高電平時為5x10的點陣字符;
指令7
字符發生器RAM地址設置
指令8
DDRAM地址設置
指令9
讀忙信號和光標地址
BF位 → 為忙標志位,高電平表示忙,此時模塊不能接收命令或者數據
指令10
寫數據
指令11
讀數據


2 、LCD的特點:
(1)低壓微功耗;
(2)平板型結構;
(3)被動顯示型(無眩光,不刺激人眼,不會引起眼睛疲勞);
(4)顯示信息量大(因為像素可以做得很小);
(5)易于彩色化(在色譜上可以非常準確的復現);
(6)無電磁輻射(對人體安全,利于信息保密);
(7)長壽命(這種器件幾乎沒有什么劣化問題,因此壽命極長,但是液晶背光壽命有限,不過背光部分可以更換)。


第四章 設計原理分析4.1  設計方案的確定
本設計需要使用LCD液晶顯示屏和編碼鍵盤。故選擇靜態顯示和用編碼鍵盤。使用LCD液晶顯示屏顯示運算結果。
    主程序進行初始化,其他的程序選擇模塊式的方式。首先對每個模塊進行調試, 當模塊調試成功后,逐一的加入主程序中,最后完成整個軟件部分的設計。
4.2計算器硬件方案及硬件資源分配4.2.1 硬件資源分配
主要用到的硬件:AT89S52   LCD液晶顯示屏  編碼鍵盤
硬件分配:
1、P1、P3口:做為輸出口,控制LCD液晶顯示屏顯示數據的結果。
2、P2口:做為輸入口,與鍵盤連接,實現數據的輸入。
3、LCD液晶顯示屏顯示輸出。
4.2.2 系統的硬件設計
為了更好的實現系統得功能,硬件電路的設計應該遵循以下原則:
1、優化硬件電路
采用軟件設計與硬件設計相結合的方法;盡管采用軟件來實現硬件系統的功能時,也許響應時間會比單純使用硬件時長,而且還要占用微處理器(MCU)的時間;但是,用軟件實現硬件的功能可以簡化硬件結構,提高電路的可靠性。所以,在設計本系統得時候,在滿足可靠性和實時性的前提下,盡可能的通過軟件來實現硬件功能。
2、可靠性及抗干擾設計
根據可靠性設計理論,系統所用芯片數量越少,系統的平均無故障時間越長。而且,所用芯片數量越少,地址和數據總線在電路板上受干擾的可能性也就越小。因此,系統的設計思想是在滿足功能的情況下力爭使用較少數量的芯片。
3、靈活的功能擴展
功能擴展是否靈活是衡量一個系統優劣的重要指標。一次設計往往不能完全考慮到系統的各個方面,系統需要不斷完善以及進行功能升級。進行功能擴展時,應該在原有設計的基礎上,通過修改軟件程序和少量硬件完成。對于本系統而言,就是要求在系統硬件不變的情況下,能夠通過修改軟件程序,完成功能的升級和擴展。
根據第提出的系統設計方案,結合以上三條原則,確定了系統硬件的設計。計算器主要由以下一些功能模塊構成:非編碼鍵盤模塊、LCD液晶顯示屏模塊等。
該系統的硬件設計采用了模塊化的設計方法。AT89S52 單片機與LCD液晶顯示屏顯示電路是整個電路的核心,它們實現系統的功能要求。
簡易計算器主要包括:鍵盤電路,顯示電路。
下圖為總體硬件結構。(如圖4.2.2 所示為整個系統的原理圖)
圖4.2.2 計算器原理圖
前面敘述了該系統的設計說明,系統采用了比較簡單的設計方案,所以該系統的硬件設計的總外圍電路不會產生過多的干擾。在下面的闡述中,對系統的外圍電路分別予以介紹。鍵盤部分采用編碼鍵盤,顯示部分采用LCD液晶顯示屏完全能夠很好的實現顯示方面的要求。
4.2.3 鍵盤電路的設計
鍵盤可分為兩類:編碼鍵盤和非編碼鍵盤。編碼鍵盤是較多按鍵(20個以上)和專用驅動芯片的組合,當按下某個按鍵時,它能夠處理按鍵抖動、連擊等問題,直接輸出按鍵的編碼,無需系統軟件干預。通用計算機使用的標準鍵盤就是編碼鍵盤。在智能儀器中,使用并行接口芯片8279或串行接口芯片HD7279均可以組成編碼鍵盤,同時還可以兼顧數碼管的顯示驅動,其相關的接口電路和接口軟件均可在芯片資料中得到。當系統功能比較復雜,按鍵數量很多時,采用編碼鍵盤可以簡化軟件設計。非編碼鍵盤成本低廉。
從成本角度出發,本設計選用的是非編碼鍵盤。如圖4.2.3

圖4.2.3 編碼鍵盤電路

4.2.4 顯示電路的設計
當系統需要顯示少量數據時,采用LCD液晶顯示屏進行顯示是一種經濟實用的方法。P0口作為液晶顯示的數據端口,P3.5-P3.7口作為其控制端口,控制LCD液晶顯示屏顯示輸出數據。
最終電路如圖4.2.4所示:
圖4.2.4 LCD液晶顯示屏顯示

第五章 計算器的軟件設計5.1計算器的軟件規劃
簡易計算器的程序主要包括以下功能模塊:
1、定時查鍵模塊,分為讀鍵程序、判鍵程序段、運算操作子程序等部分;
2、基于LCD液晶顯示屏的顯示模塊;
3、主模塊,為系統的初始化。
5.2 匯編語言和C語言的特點及選擇

本設計是硬件電路和軟件編程相結合的設計方案,選擇合適的編程語言是一個重要的環節。在單片機的應用系統程序設計時,常用的是匯編語言和C語言。機硬件,程序可讀性和可移植性比較差。而C語言雖然執行效率沒有匯編語言高,但語言簡潔,使用方便,靈活,運算豐富,表達化類型多樣化,數據結構類型豐富,具有結構化的控制語句,程序設計自由度大,有很好的可重用性,可移植性等特點。

由于現在單片機的發展已經達到了很高的水平,內部的各種資源相當的豐富,CPU的處理速度非常的快。用C語言來控制單片機無疑是一個理想的選擇。所以在本設計中采用C語言編寫軟件程序。主程序的設計詳見附錄三。

5.3 按鍵鍵掃描程序設

鍵掃程序的過程為:開始時,先判斷是否有鍵閉合,無鍵閉合時,返回繼續判斷,有鍵閉合時,先去抖動,然后確定是否有鍵按下,若無鍵按下,則返回繼續判斷是否有鍵閉合,若有鍵按下,則判斷鍵號,然后釋放,若釋放按鍵完畢,則返回,若沒有釋放按鍵,則返回繼續釋放。其流程圖如圖5.1所示。

圖5.1 鍵掃程序流程圖

5.4 算術運算程序設計

算術運算程序的過程為:先判斷輸入的運算符是+、-、*、/ 中的哪一個,若是+或-,則要判斷運算結果是否溢出,溢出則顯示錯誤信息,沒溢出就顯示運算結果,若是/,則要先判斷除數是否為零,為零就顯示錯誤信息,不為零則顯示運算結果,若是-,則直接顯示運算結果。其流程圖如圖5.2所示。



圖5.2 算術運算程序設計流程圖
5.5 顯示程序設計

顯示程序的過程為:顯示開始時,先進行LCD的初始化,判斷是否顯示漢字或ACSII碼或圖形,若不顯示,則返回,若顯示的是漢字或ACSII碼,則進行相應功能的設置,然后送地址和數據,再判斷是否顯示完,顯示完則返回,沒有顯示完則繼續送地址,若顯示的是圖形,則先進行相應功能的設置,再送行地址和列地址,然后送數據,最后判斷是否顯示完,顯示完則返回,沒有顯示完則繼續送行地址和列地址。其流程圖如圖5.3所示。


圖5.3 顯示程序流程圖
系統調試與存在的問題6.1 硬件調試

常見故障:

1、邏輯錯誤:它是由設計錯誤或加工過程中的工藝性錯誤所造成的。這類錯誤包括錯線、開路、短路等。

2、元器件失效:有兩方面的原因:一是器件本身已損壞或性能不符合要求;二是組裝錯誤造成元件失效,如電解電容、集成電路安裝方向錯誤等。

3、可靠性差:因其可靠性差的原因很多,如金屬化孔、接插件接觸不良會造成系統時好時壞,經不起振動;走線和布局不合理也會引起系統可靠性差。

4、電源故障:若樣機由電源故障,則加電后很容易造成器件損壞。電源故障包括電壓值不符合設計要求,電源引線和插座不對,功率不足,負載能力差等。

調試方法:包括多級調試和聯機調試。在調試過程中要針對可能出現的故障認真分析,直至檢查出原因并排除。

本次硬件調試過程中,對所出現的問題進行了認真的分析和改正,最后能夠很好的達到設計要求的效果。

6.2 軟件調試

軟件調試一般分為以下四個階段:1、 編寫程序并查錯;2、在C語言的編譯系統中編譯源程序3、對程序進行編譯連接,并及時發現程序中存在的錯誤;4、改正錯誤。

在本次調試中出現的問題有:

1、在程序中有的函數名未定義;

2、在抄錄程序時,少錄入一些字符,如:“;”、“{”、“-”等符號,而出現錯誤;

3、有一些函數名錄入時少寫一個字母或順序顛倒;

4、沒有注意函數名的調用及定義;

5、芯片引腳定義出錯而導致沒有實驗現象。

在軟件調試過程中,對出現的錯誤進行了認真的分析和修改,多次調試成功后,能夠很好的達到既定的設計效果。



結束語

在硬件的制作過程中我走了好多的彎路,主要是在系統還沒有設計很有把握就開始動手制作了。后來發現與設計的要求還有偏差,反復的改過了幾次,浪費了大量的時間和體力。感受到設計人員要有耐心,要認真的從要求開始研究。軟件的編寫過程中費了很大的力氣,因為軟件的編寫要求很高,要很細心,一不小心就會調用錯誤,很深刻的體會到作為軟件編程人員是絕不能粗心大意的。一個程序的完成的速度和質量高低與細心與否有著很大聯系。編程時,我充分使用了結構化的思想。這樣因為語句較少,程序調試比較方便,功能模塊可以逐一的調試,充分體現了結構化編程的優勢。當每個模塊都完成時,將其功能加到一起就完成了整體的設計。


致謝
本次畢業設計得到導師XXX老師的熱心指導,在這里對X老師表示最衷心的感謝。X老師平易近人,對學生的設計進度和學習很關心。在畢業設計的前期,首先給我們介紹了不少有用的資料和書籍;在硬件設計等方面給予悉心的指導;在調試的過程中X老師給每個出現的問題給予及時的指導。在寫畢業設計論文的階段,X老師讓我們提前給他評審,不論內容字體,還是格式上的問題都一一指出。待人平和、工作認真、治學嚴謹他的給我留下很深刻的印象。更重要的是,他善于與學生溝通,不僅在畢業設計上給我及時的指導,更為我大學最后階段的學習提出了許多寶貴的意見。這一切都在潛移默化地影響著我,為我以后進入工作崗位樹立了良好的榜樣。
同時還要感謝XXX老師,她關心同學們的進程,了解同學們在撰寫過程中的麻煩,給我們提供很多幫助。
最后向所有幫助和關心過我的人表示衷心感謝!

參考文獻

【1】張靖武,周靈杉.單片機系統的PROTEUS設計與仿真[M].北京:北京電子工業出版社
【2】靳達.求是科技.單片機應用系統開發實例導航[M].:人民郵電出版社,2006
【3】劉守義. 單片機應用技術[M].:西安電子科技大學出版社,2001
【4】林志琦.基于PROTEUS的單片機可視化軟硬件仿真[M].北京:北京航空航天大學出版社,2006
【5】胡漢才.單片機原理及接口技術.清華大學出版社,1996
【6】徐江海.單片機實用教程[M].北京:機械工業出版社,2007.
【7】肖洪兵. 跟我學用單片機. 北京:北京航空航天大學出版社,2002.8
【8】夏繼強. 單片機實驗與實踐教程. 北京:北京航空航天大學出版社, 2001
【9】譚浩強. C語言程序設計[M].北京:清華大學出版社,2000.
【10】劉福基. C語言程序設計與實訓教程[M].北京:科學出版社,2004.
【11】張磊. C語言程序設計[M].北京:高等教育出版社,2005.
【12】嚴桂蘭. C語言程序設計[M].廈門:廈門大學出版社,2006


附錄附錄一:硬件實物圖
硬件實物圖(正面)
自己拍自己的實物照片
硬件實物圖(背面)
附錄二:系統程序清單

單片機源程序如下:

  1. /*
  2. 接盤按鍵說明:
  3. --------------------------------------------------
  4.    - - - - - - - - - - - -- - - - - - -
  5.   |              1602液晶               |
  6.   |                                     |
  7.    - - - - - - - - - - -- - - - - - - -
  8.             - - - - - - - - - - - - -
  9.                                           |      89s52             |  
  10.             - - - - - - - - - - - - -

  11.             |  1  |  2  |  3  |  +  |
  12.             - - - - - - - - - - - - -
  13.             |  4  |  5  |  6  |  -  |
  14.             - - - - - - - - - - - - -
  15.             |  7  |  8  |  9  |  *  |
  16.             - - - - - - - - - - - - -
  17.                                           | C   |  0  |  =  |  /  |
  18. --------------------------------------------------*/
  19. //操作簡介
  20. // 按第一個數,再按'+-*/',再按'='顯示出結果,然后按C清屏
  21. // 加最大9999+9999=19998
  22. // 減最大9999-0   =9999
  23. // 乘最大9999*9999=99980001
  24. // 除 1/9=0.1111 保留小數點后4位
  25. #include<reg51.h>
  26. #define uint unsigned int
  27. #define uchar unsigned char
  28. //--------LCD1602-------------------
  29. //P10-17==== D0-7
  30. sbit rs=P3^0;        //指令or數據
  31. sbit wela=P3^1;      //讀or寫
  32. sbit lcden=P3^2;              //使能信號
  33. //--------LCD1602-------------------
  34. //--------KEY-----------------------
  35. //P2口
  36. //--------KEY-----------------------
  37. uchar code table[]= "                ";

  38. long  int data_a,data_b;               //第一個數和第二個數
  39. long  int data_c;                                          //計算結果

  40. uchar dispaly[10];         //顯示緩沖

  41. //************************************************************************/
  42. // 描述: 延時t us函數
  43. //************************************************************************/
  44. void LCD_Delay_us(unsigned int t)
  45. {
  46.               while(t--);           //t=0,退出
  47. }
  48. //************************************************************************/
  49. // 描述: 延時t ms函數
  50. //************************************************************************/
  51. void LCD_Delay_ms(unsigned int t)
  52. {
  53.               unsigned int i,j;
  54.               for(i=0;i<t;i++)                                   //執行t次循環
  55.               for(j=0;j<113;j++)                                 //執行113次循環
  56.               ;
  57. }
  58. //************************************************************************/
  59. // 描述: 1602液晶寫指令
  60. //************************************************************************/
  61. void write_com(uchar com)                  //1602液晶寫指令
  62. {
  63.               rs=0;                       //寫指令
  64.               lcden=0;                    //使能1602
  65.               P1=com;                     //寫入指令com
  66.               LCD_Delay_ms(1);            //延時1ms
  67.               lcden=1;                    //使能1602
  68.               LCD_Delay_ms(2);            //延時2ms
  69.               lcden=0;                              //使能1602
  70. }
  71. //************************************************************************/
  72. // 描述:1602液晶寫數據
  73. //************************************************************************/
  74. void write_date(uchar date) //1602液晶寫數據
  75. {
  76.               rs=1;                        //寫數據
  77.               lcden=0;                     //使能1602
  78.               P1=date;                     //寫入數據date
  79.               LCD_Delay_ms(1);             //延時1ms
  80.               lcden=1;                     //使能1602
  81.               LCD_Delay_ms(2);             //延時2ms
  82.               lcden=0;                               //使能1602
  83. }
  84. //************************************************************************/
  85. // 描述:指定x,y寫入字符函數
  86. //************************************************************************/
  87. void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
  88. {   
  89.               if (y == 0){write_com(0x80 + x);}   //第一行
  90.               else{write_com(0xc0 + x);}          //第二行
  91.               write_date( Data);                  //寫入數據
  92. }
  93. //指定x,y寫入字符串函數
  94. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  95. {   
  96. if (y == 0){write_com(0x80 + x);}                             //第一行
  97. else{write_com(0xC0 + x);}                                    //第二行
  98. while (*s)                                                    //
  99.               {write_date( *s); s++;}                                  //寫入數據
  100. }
  101. //************************************************************************/
  102. // 描述:初始化液晶,及畫面初始化
  103. //************************************************************************/
  104. void init_lcd(void)            //初始化液晶,及畫面初始化
  105. {
  106.               wela=0;                      //寫液晶
  107.               lcden=0;                     //使能1602
  108.               write_com(0x38);             //8 位總線,雙行顯示,5X7 的點陣字符
  109.               LCD_Delay_us(100);           //延時100us
  110.               write_com(0x0c);             //開顯示,無光標,光標不閃爍
  111.               write_com(0x06);             //光標右移動
  112.               write_com(0x01);             //清屏
  113.               write_com(0x80);             //DDRAM 地址歸0
  114. }
  115. //************************************************************************/
  116. // 描述: 反轉法鍵盤掃描
  117. //************************************************************************/
  118. short keycheckdown()                                                        /* 反轉法鍵盤掃描 */
  119. {

  120.               short temp1,temp2,temp,a=0xff;
  121.               P2=0xf0;                                                                                    /* 輸入行值(或列值) */
  122.               LCD_Delay_ms(20);                                                        /* 延時 */
  123.               temp1=P2;                                                                                    /* 讀列值(或行值) */
  124.               P2=0xff;
  125.               LCD_Delay_ms(20);                                                        /* 延時 */
  126.               P2=0x0f;                                                                                    /* 輸入列值(或行值) */
  127.               LCD_Delay_ms(20);                                                        /* 延時 */            
  128.               temp2=P2;                                                                                    /* 讀行值(或列值) */
  129.               P2=0xff;
  130.               temp=(temp1&0xf0)|(temp2&0xf);              /* 將兩次讀入數據組合 */
  131.               switch(temp)                                                                      /* 通過讀入數據組合判斷按鍵位置 */
  132.               {


  133.                             case 0x77 :a=0x0d;break;//  按鍵/  
  134.                             case 0x7b :a=0x0e; break;// 按鍵=            
  135.                             case 0x7d :a=0;                 break;// 按鍵0
  136.                             case 0x7e :a=0x0f; break;// 按鍵CE

  137.                             case 0xb7 :a=0x0c;break;//               按鍵*
  138.                             case 0xbb :a=0x9;break; //  按鍵9
  139.                             case 0xbd :a=0x8;break; //  按鍵8
  140.                             case 0xbe :a=0x7;break; //               按鍵7

  141.                             case 0xd7 :a=0x0b;break;//  按鍵-
  142.                             case 0xdb :a=0x6;break; //               按鍵6
  143.                             case 0xdd :a=0x5;break; //               按鍵5
  144.                             case 0xde :a=0x4;break; //               按鍵4

  145.                             case 0xe7 :a=0x0a; break;// 按鍵+
  146.                             case 0xeb :a=3;break;              //  按鍵3
  147.                             case 0xed :a=2;break;              //  按鍵2
  148.                             case 0xee :a=1;break;              //  按鍵1

  149.                             default :a=0xff;
  150.               }
  151.               return a;                                                                                    /* 返回按鍵值 */
  152. }
  153. void display_a() //顯示數據a
  154. {
  155.               dispaly[3]=data_a%10000/1000;    //千
  156.               dispaly[2]=data_a%1000/100;      //百
  157.               dispaly[1]=data_a%100/10;        //十
  158.               dispaly[0]=data_a%10;            //個

  159.               write_com(0x80+0);               //顯示數據a
  160.               if(data_a>999){              write_date('0'+dispaly[3]);}      //顯示千位
  161.               if(data_a>99){              write_date('0'+dispaly[2]);}                            //顯示百位
  162.               if(data_a>9){              write_date('0'+dispaly[1]);}     //顯示十位
  163.                                           write_date('0'+dispaly[0]);      //顯示個位
  164. }

  165. void display_b() //顯示數據b
  166. {
  167.               write_com(0x80+7); //第一行
  168.               dispaly[3]=data_b%10000/1000;    //千
  169.               dispaly[2]=data_b%1000/100;      //百
  170.               dispaly[1]=data_b%100/10;        //十
  171.               dispaly[0]=data_b%10;            //個

  172. if(data_b>999){              write_date('0'+dispaly[3]); }     //顯示千位  
  173. if(data_b>99) {              write_date('0'+dispaly[2]); }    //顯示百位
  174. if(data_b>9)  {              write_date('0'+dispaly[1]); }     //顯示十位
  175.                                                 write_date('0'+dispaly[0]);      //顯示個位
  176. }

  177. //計算結果
  178. void display_c(x)
  179. {

  180.               if(data_c<100000000&&data_c>-1)//溢出時顯示錯誤
  181.               {            

  182.                             dispaly[8]=data_c%1000000000/100000000;                  //萬萬
  183.                             dispaly[7]=data_c%100000000/10000000;                  //千萬
  184.                             dispaly[6]=data_c%10000000/1000000;                                //百萬
  185.                             dispaly[5]=data_c%1000000/100000;                                //十萬
  186.                             dispaly[4]=data_c%100000/10000;                                              //萬
  187.                             dispaly[3]=data_c%10000/1000;                                              //千
  188.                             dispaly[2]=data_c%1000/100;                                                //百
  189.                             dispaly[1]=data_c%100/10;                                                  //十
  190.                             dispaly[0]=data_c%10;                                                      //個
  191.                             write_com(0x80+6+0x40); //第一行
  192.                             if(x==4)
  193.                             {   
  194.                             if(data_c>99999999)              {              write_date('0'+dispaly[8]);}    //顯示萬萬
  195.                             if(data_c>9999999)              {              write_date('0'+dispaly[7]);}   //千萬
  196.                             if(data_c>999999)              {              write_date('0'+dispaly[6]);}    //百萬
  197.                             if(data_c>99999)              {              write_date('0'+dispaly[5]);}    //十萬
  198.                                                                                                                 write_date('0'+dispaly[4]);    //萬
  199.                                                                                                                 write_date('.');
  200.                                                                                                                 write_date('0'+dispaly[3]);    //千
  201.                                                                                                                 write_date('0'+dispaly[2]);    //百
  202.                                                                                                                 write_date('0'+dispaly[1]);    //十
  203.                                                                                                                 write_date('0'+dispaly[0]);    //個
  204.                             }
  205.               else{
  206.                             if(data_c>99999999)              {              write_date('0'+dispaly[8]);}    //顯示萬萬
  207.                             if(data_c>9999999)              {              write_date('0'+dispaly[7]);}    //千萬
  208.                             if(data_c>999999)              {              write_date('0'+dispaly[6]);}    //百萬
  209.                             if(data_c>99999)              {              write_date('0'+dispaly[5]);}    //十萬
  210.                             if(data_c>9999)                            {              write_date('0'+dispaly[4]);}    //萬
  211.                             if(data_c>999)                            {              write_date('0'+dispaly[3]);}    //千
  212.                             if(data_c>99)                            {              write_date('0'+dispaly[2]);}    //百
  213.                             if(data_c>9)                            {              write_date('0'+dispaly[1]);}    //十
  214.                                                                                                                 write_date('0'+dispaly[0]);    //個
  215.                             }
  216.               }
  217.               else  //溢出時顯示錯誤
  218.               {
  219.                             write_com(0x80+11+0x40); //第一行
  220.                             write_date('E');         //顯示 E
  221.                             write_date('r');         //顯示R
  222.                             write_date('r');                            //顯示R
  223.                             write_date('o');                            //顯示O
  224.                             write_date('r');                            //顯示E
  225.               }
  226. }

  227. void eql(uchar x)//加減乘除運算
  228. {
  229.               switch(x)                            /*功能鍵選擇*/
  230.                                           {  
  231.                                                         case 1:data_c=data_a+data_b;break;                               //加  /* + S=1 */ /* 數值轉換函數 */                                                                                                                             
  232.                                                         case 2:if(data_a>=data_b){data_c=data_a-data_b;} /* - S=2 *///減
  233.                        else{data_c=data_b-data_a;W_lcd(5,1,'-');} //負數符號
  234.                                                                          break;               
  235.                                                         case 3:data_c=(data_a*data_b);break;                              /* * S=3 *///乘
  236.                                                         case 4:if(data_b==0){LCD_Write_String(0,1,"Error !");}else{data_c=(data_a*10000)/data_b;}break;                              /* / S=4 *///除//溢出時顯示錯誤
  237.                                                         case 0:break;
  238.                                           }               

  239. }

  240. void main()
  241. {
  242.               uchar   key=0xff;               //鍵值初始化
  243.               uchar   n=0;                                                                      //第1個數可以按1-4次
  244.               uchar   m=5;                                                                       //第2個數可以按1-4次
  245. ……………………

  246. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
2017年27-單片機的簡易計算器設計.doc (526.87 KB, 下載次數: 33)


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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

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