基于單片機的智能調光燈設計,基于,單片機,智能,調光,設計
本科畢業(yè)設計論文
題 目 基于單片機的智能調光燈設計
專業(yè)名稱 自動化
學生姓名 屈曉東
指導教師 李雪霞
畢業(yè)時間 2014.06
西北工業(yè)大學明德學院本科畢業(yè)設計論文
設計
論文
畢業(yè) 任務書
一、題目:
基于單片機的智能調光燈設計
二、指導思想和目的要求:
通過畢業(yè)設計,使學生對所學電子工藝、電路基礎知識、模電、數(shù)電、等電子基礎課程的基本知識加深理解,掌握單片機的基本指令及基本結構,并將其與實際工程應用緊密結合起來,培養(yǎng)創(chuàng)新意識,增強分析問題解決問題能力,為盡快進入社會角色,熟悉相關開發(fā)工作流程、項目小組組成、分工、合作方式方法等。增強團隊合作意識,提高基本工作技能,為即將踏入社會奠定理論和實踐基礎。
內容:設計一電路,不僅亮度可調,還可以顯示時間等功能。
具體要求如下:
1) 顯示當前的時間,24 時制的時、分、秒;
2) 可調節(jié)時間;
3) 可調節(jié)LED 光亮度;
步驟: l、了解所設計系統(tǒng)的工作原理及要求。
2、設計單片機工作的基本電路,如:晶振電路、復位電路。
3、根據(jù)系統(tǒng)設計要求選擇發(fā)光二極管、按鍵等模擬部件。
4、設計系統(tǒng)基本電路。
5、繪制PRTUSE電原理圖并編寫系統(tǒng)控制程序。
6、聯(lián)機進行系統(tǒng)仿真調試。
三、進度與要求:
1.第一周~第一周 收集設計系統(tǒng)相關資料。
2.第二周~第三周 用PROTUSE設計硬件原理圖并進行器件選型。
3.第四周~第六周 編寫系統(tǒng)各功能模塊控制程序。
4.第七周~第十周 聯(lián)機進行系統(tǒng)調試。
5. 第十一周~第十二周 整理并組織論文。
6.第十三周~第十四周 完成修改稿,定稿,打印,交評閱。
7.第十五周~第十六周 評閱與答辯
學生 屈曉東 指導教師 李雪霞 系主任 史儀凱
摘 要
在實際的應用中發(fā)現(xiàn),當周邊亮度大時,LED燈過亮,存在電能浪費;當周邊亮度小時,LED燈過暗,又不能提供足夠和恰當?shù)墓舛?。用來改善我們的生活質量,體驗到科學技術帶給我們更方便的生活,節(jié)省電能。因此,研究實用具有時鐘功能的臺燈的應用,有著非?,F(xiàn)實的意義,具有很大的實用價值。
本文介紹了設計的框架結構和組成模塊以及各模塊的原理,介紹了各部分硬件設計和各部分軟件設計以及軟件流程圖。該設計是以AT89C52 單片機為控制核心的集多種功能于一體的智能LED臺燈。該臺燈具有燈光亮度調節(jié)功能;具有時間顯示功能。硬件設計分為單片機控制模塊、按鍵模塊、臺燈模塊、時鐘模塊、顯示模塊等五個部分。單片機控制用AT89C52,顯示模塊用LCD1602 液晶顯示時間、日期等內容,按鍵模塊用來調整時間、日期、LED的亮度等,時鐘用DS1302 時鐘芯片,臺燈模塊用13 顆LED燈。軟件設計用單片機C /C++編寫,通過PROTEUS和KEIL仿真軟件進行程序仿真,實現(xiàn)了全部控制功能。
關鍵詞:單片機,智能,顯示,LED燈,時間
ABSTRACT
In practical applications, we found that the brightness of LED lights in the surrounding large power LED is still the same, there is a waste of energy; hours in the surrounding brightness LED lights do not provide adequate and appropriate luminosity. Used to improve our quality of life, to experience science and technology bring us more convenient life, to save energy.Therefore, the study and practical application of electronic bell, has a very real sense, has great practical value.
This paper describes the design principles of the framework structure and composition of modules and each module, introduces the various parts of the various parts of the hardware design and software design and software flow. The design is based on AT89C52 microcontroller core set of functions in one smart LED lamp. The lamp has a light brightness adjustment function; has a time display function; alarm function. Hardware design is divided into five parts.MCU control module, the key modules, lamp modules, clock module, alarm module, display module. MCU control with AT89C52, display module displays time, date and other content with LCD1602 , keypad module is used to adjust the time, date, etc. brightness LED clock with DS1302 clock chip, lamp module with 13 LED. SCM software design written in C/C++ language, the realization of all the control functions.
KEY WORDS: microcontroller, smart, display, LED lights and time
目 錄
摘 要 I
ABSTRACT II
目 錄 III
第一章 緒 論 5
1.1 選題意義 5
1.2 設計要求 6
1.2.1 功能實現(xiàn) 6
1.2.2 系統(tǒng)所需功能模塊 6
1.3 系統(tǒng)基本方案選擇和論證 7
1.3.1 單片機芯片的選擇方案和論證 7
1.3.2 顯示模塊選擇方案和論證 7
1.3.3 時鐘芯片的選擇方案和論證 8
第二章 系統(tǒng)的硬件設計 9
2.1 系統(tǒng)模塊框圖 9
2.2 系統(tǒng)整體硬件圖 9
2.3 各模塊電路的設計 10
2.3.1 單片機控制模塊 10
2.3.2 晶振/復位模塊 11
2.3.3 臺燈模塊 13
2.3.4 臺燈調光按鍵模塊 15
2.3.5 DS1302時鐘電路模塊 15
2.3.6 1602LCD顯示模塊 17
2.3.7 調節(jié)時鐘按鍵模塊 19
第三章 系統(tǒng)的軟件設計 20
3.1 系統(tǒng)軟件編程工具C和C++ 20
3.1.1 C簡介 20
3.1.2 C++ 21
3.2 主程序的設計流程圖 22
3.3.1 臺燈模塊流程圖 22
3.3.2 臺燈模塊程序 23
3.4 LCD1602液晶顯示 25
3.4.1 時鐘設置流程圖 25
3.4.2 時鐘程序 26
第四章 仿真結果 36
4.1 仿真軟件PROTEUS和KEIL 36
4.1.1 PROTEUS仿真軟件 36
4.1.2 KEIL仿真軟件 37
4.2 PROTEUS仿真圖 37
4.2.1 LED燈亮度仿真 37
4.2.2 LCD1602時鐘仿真 39
4.3 KEIL仿真 40
4.4 問題及解決 41
4.4.1 存在的問題 41
4.4.2 解決的措施 41
參考文獻 42
致 謝 43
小 結 44
III
第一章 緒 論
1.1 選題意義
現(xiàn)代人類生活中所用的幾乎每件有電子器件的產品中都會集成有單片機。手機、電話、計算器、家用電器、電子玩具、掌上電腦以及鼠標等電子產品中都含有單片機。智能燈不是傳統(tǒng)燈具,而是智能設備的一種,除了智能燈體,還有一個手持智能控制設備,智能燈控制設備具備計算能力和網絡聯(lián)接能力,通過應用程序,功能可以不斷擴展。智能燈的核心功能是控制、燈光效果、創(chuàng)作、分享、光與音樂互動、光提升健康和幸福。開關燈的控制,不但可以通過控制器,手動遙控燈的開關,還可以進行定時開關燈的控制,可以設定不同的時間開燈關燈。其次是對光的控制,光的亮度,光的冷暖,光的色彩都可以連續(xù)手動控制或自動控制。
白熾燈和金鹵燈在調光領域應用得比較廣泛,但隨著節(jié)能減排的不斷推廣,LED可調光在攻克了調光技術障礙后,開始呈現(xiàn)發(fā)展趨勢,LED可調光與LED紅外智能燈管、LED聲光控等一起統(tǒng)稱為LED智能化系列,在LED普通燈具價格競爭日趨激烈的今天,LED智能化已經成為大型LED照明企業(yè)的發(fā)展方向。
電子鐘已成為人們日常生活中必不可少的物品,廣泛用于個人家庭以及車站、碼頭、劇院、辦公室等公共場所,給人們的生活、學習、工作、娛樂帶來極大的方便。隨著技術的發(fā)展,人們已不再滿足于鐘表原先簡單的報時功能,希望出現(xiàn)一些新的功能,諸如日歷的顯示、鬧鐘的非接觸式止鬧跑表功能、重要日期倒計時顯示等,以帶來更大的方便,而所有這些,又都是以數(shù)字化的電子時鐘為基礎的。因此,研究實用電子鐘的應用,有著非?,F(xiàn)實的意義,具有很大的實用價值。
由于數(shù)字集成電路技術的發(fā)展和采用了先進的石英技術,使電子鐘具有走時準確、性能穩(wěn)定、攜帶方便等優(yōu)點,它還用于計時、自動報時及自動控制等各個領域?,F(xiàn)在市場上已有現(xiàn)成的電子鐘集成電路芯片出售,價格便宜,使用也靈活,如可以隨意設置時、分、秒的輸出,改變顯示數(shù)字的大小等,并且由于集成電路技術的發(fā)展,特別是MOS 集成電路技術的發(fā)展,使電子鐘具有體積小、攜帶方便的特點,這里介紹的實用電子鐘可以滿足使用者的一些基本要求,輸出方式靈活、功耗低、計時準確、性能穩(wěn)定、維護方便等優(yōu)點。實用電子鐘是一個時間控制系統(tǒng),既能作為一般的時間顯示器,也可作為一個定時控制器,驅動負載或顯示信息,同時可以根據(jù)需要擴展其功能。在此項目的設計研究過程中需綜合運用所學的數(shù)字電子技術、單片機原理與應用等課程的知識,掌握實用電子鐘的設計、組裝與調試方法,利用現(xiàn)代的單片機等新電子技術以及現(xiàn)代的設計手段,系統(tǒng)地培養(yǎng)了綜合設計、操作調試、故障處理的能力,達到綜合素質以及創(chuàng)新能力的提高。
1.2 設計要求
1.2.1 功能實現(xiàn)
(1)LED調光燈功能:當按下按鍵K0、K1、K2分為一級亮度紅燈、二級亮度黃燈和三級亮度綠燈來實現(xiàn)。
(2)時間、日期顯示:系統(tǒng)采用24小時制。正常情況下,系統(tǒng)顯示當前日期、時間,由LCD顯示。
(3)設置功能:用戶可以對LED燈光的亮度進行調節(jié),對時間、日期、星期進行設置。用戶依次進入日期設置、星期設置、時間設置。在進行設置時,光標停留在相應位,按下K4鍵、K5鍵對數(shù)值進行加、減調整。通過K3鍵,在各個數(shù)位間移動。 通過K6鍵,確定所設置的時間。
1.2.2 系統(tǒng)所需功能模塊
由功能分析,臺燈系統(tǒng)分為燈光模塊、鍵盤模塊、顯示模塊、時鐘部分、電源模塊和單片機模塊,考慮成本時鐘模塊可由單片機內部計數(shù)器模擬實現(xiàn)。
(1)燈光模塊用D0~D12個LED燈實現(xiàn)。
(2)按鍵模塊分為調光3個按鍵和調節(jié)時間4個按鍵,分別是K0、K1、K2和K3、K4、K5、K6。
(3)顯示模塊負責顯示系統(tǒng)的日期、星期、時間。
(4)電源模塊采用+5V直流供電。
(5)單片機模塊內部計數(shù)器負責LED燈光和時鐘,通過程序模擬生成亮度調節(jié)和時間走時。同時負責掃描鍵盤,并將時間送給LCD顯示。
1.3 系統(tǒng)基本方案選擇和論證
1.3.1 單片機芯片的選擇方案和論證
方案一:
采用STC89C52芯片作為硬件核心,采用Flash ROM,內部具有4KB ROM 存儲空間,能于3V的超低壓工作,而且與MCS-51系列單片機完全兼容,但是運用于電路設計中時由于不具備ISP在線編程技術, 當在對電路進行調試時,由于程序的錯誤修改或對程序的新增功能需要燒入程序時,對芯片的多次拔插會對芯片造成一定的損壞。
方案二:
采用AT89C52,片內ROM全都采用Flash ROM;能以3V的超底壓工作;同時也與MCS-51系列單片機完全該芯片內部存儲器為8KB ROM 存儲空間,同樣具有STC89C52的功能,且具有在線編程可擦除技術,對所下載的程序能夠加密,比較安全。當在對電路進行調試時,由于程序的錯誤修改或對程序的新增功能需要燒入程序時,不需要對芯片多次拔插,所以不會對芯片造成損壞。所以選擇采用AT89C52作為主控制系統(tǒng)。
1.3.2 顯示模塊選擇方案和論證
方案一:
采用點陣式數(shù)碼管顯示,點陣式數(shù)碼管是由八行八列的發(fā)光二極管組成,對于顯示文字比較適合,如采用在顯示數(shù)字顯得太浪費,且價格也相對較高,所以不用此種作為顯示。
方案二:
采用LED數(shù)碼管動態(tài)掃描,雖然LED數(shù)碼管價格適中,但要顯示多個數(shù)字所需要的個數(shù)偏多,功耗較大,所以也不用此種作為顯示。
方案三:
采用LCD液晶顯示屏,液晶顯示屏的顯示功能強大,可顯示大量文字,圖形,顯示多樣,清晰可見,與普通數(shù)碼管相比功耗較小,硬件連接簡單。所以顯示部分采用1602液晶顯示。
1.3.3 時鐘芯片的選擇方案和論證
方案一:
直接采用單片機定時計數(shù)器提供秒信號,使用程序實現(xiàn)年、月、日、星期、時、分、秒計數(shù)。采用此種方案雖然減少芯片的使用,節(jié)約成本,但是,實現(xiàn)的時間誤差較大。所以不采用此方案。
方案二:
采用DS1302時鐘芯片實現(xiàn)時鐘,DS1302芯片是一種高性能的時鐘芯片,可自動對秒、分、時、周、月、年以及閏年補償?shù)哪赀M行計數(shù),而且精度高,RAM作為數(shù)據(jù)暫存區(qū),工作電壓2.5V~5.5V范圍內,2.5V時耗電小于300nA。
第二章 系統(tǒng)的硬件設計
2.1 系統(tǒng)模塊框圖
六大模塊以AT89C52 單片機為控制核心,實現(xiàn)了該智能臺燈的各項要求,外接一個5V 的直流電源,為整個系統(tǒng)供電。
圖2-1 系統(tǒng)結構示意圖
2.2 系統(tǒng)整體硬件圖
該設計是以AT89C52 單片機為控制核心的集多種功能于一體的智能 LED 臺燈。該臺燈具有燈光亮度調節(jié)功能;具有時間顯示功能。硬件設計分為單片機控制模塊、按鍵模塊、臺燈模塊、時鐘模塊、鬧鈴模塊、顯示模塊等五個部分。單片機控制用AT89C52,顯示模塊用LCD1602液晶顯示、時間、日期等內容,按鍵模塊用來調整時間、日期、LED 的亮度等,時鐘用DS1302 時鐘芯片,臺燈模塊用13 顆LED,通過按鍵K0、K1、K2調節(jié)燈光的亮度,分為一級亮度、二級亮度和三級亮度。
圖2-2 系統(tǒng)整體硬件圖
2.3 各模塊電路的設計
2.3.1 單片機控制模塊
單片機是一種集成電路芯片,是采用超大規(guī)模集成電路技術把具有數(shù)據(jù)處理能力的中央處理器CPU、隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統(tǒng)、定時器/計數(shù)器等功能(可能還包括顯示驅動電路、脈寬調制電路、模擬多路轉換器、A/D轉換器等電路)集成到一塊硅片上構成的一個小而完善的微型計算機系統(tǒng),在工業(yè)控制領域廣泛應用。從上世紀80年代,由當時的4位、8位單片機,發(fā)展到現(xiàn)在的300M的高速單片機。AT89C52單片機為40引腳雙列直插芯片,有四個I/O口P0,P1,P2,P3, MCS-51單片機共有4個8位的I/O口(P0、P1、P2、P3),每一條I/O線都能獨立地作輸出或輸入。
圖2-3 AT89C52單片機控制模塊
2.3.2 晶振/復位模塊
晶振是晶體振蕩器的簡稱,在電氣上它可以等效成一個電容和一個電阻并聯(lián)再串聯(lián)一個電容的二端網絡,電工學上這個網絡有兩個諧振點,以頻率的高低分其中較低的頻率是串聯(lián)諧振,較高的頻率是并聯(lián)諧振。由于晶體自身的特性致使這兩個頻率的距離相當?shù)慕咏?在這個極窄的頻率范圍內,晶振等效為一個電感,所以只要晶振的兩端并聯(lián)上合適的電容它就會組成并聯(lián)諧振電路。晶振是給單片機提供工作信號脈沖的。這個脈沖就是單片機的工作速度。單片機的工作頻率是有范圍的,不能太大。
圖中19與18引腳分別為XTAL1、XTAL2,他們分別接晶振的輸入與輸出, XTAL1接外部晶振和微調電容的一端,在片內它是振蕩器倒相放大器的輸入,XTAL2接外部晶振和微調電容的另一端,在片內它是振蕩器倒相放大器的輸出.因為一個機器周期含有6個狀態(tài)周期,而每個狀態(tài)周期為2個振蕩周期,所以一個機器周期共有12個振蕩周期。本設計選擇晶振頻率為12MHz,輸入芯片震蕩周期為1/12μs,一個機器周期為1μs。
圖2-4 晶振電路模塊
復位電路,就是利用它把電路恢復到起始狀態(tài)。就像計算器的清零按鈕的作用一樣,以便回到原始狀態(tài),重新進行計算。和計算器清零按鈕有所不同的是,復位電路啟動的手段有所不同。一是在給電路通電時馬上進行復位操作;二是在必要時可以由手動操作;三是根據(jù)程序或者電路運行的需要自動地進行。在RST復位輸入引腳上接一電容至Vcc端,下接一個電阻到地即可。
復位電路工作原理如下圖所示,Vcc上電時,C3充電,在10K電阻上出現(xiàn)電壓,使得單片機復位;幾個毫秒后,C3充滿,10K電阻上電流降為0,電壓也為0,使得單片機進入工作狀態(tài)。工作期間,按下K7,C3放電,在10K電阻上出現(xiàn)電壓,使得單片機復位。K7松手,C3又充電,幾個毫秒后,單片機進入工作狀態(tài)。第9引腳為復位輸入端,接上電容,電阻及開關后夠上電復位電路。
圖2-5 復位電路模塊
2.3.3 臺燈模塊
臺燈模塊用13 顆LED作為發(fā)光系統(tǒng),每一顆和一個220 的電阻串聯(lián),用P1.4~P1.6 口控制。電阻起限流作用, 13 個I/O 均采用低電平有效方式,即給相應的I/O 低電平LED工作。通過按鍵K0、K1、K2調節(jié)燈光的亮度,亮度分為三個等級:一級亮度控制紅色的D0燈亮;二級亮度控制黃色的D1、D2、D3、D4燈亮;三級亮度控制綠色的D5、D6、D7、D8、D9、D10、D11、D12燈亮。
圖2-6 臺燈模塊(1)
圖2-7 臺燈模塊(2)
2.3.4 臺燈調光按鍵模塊
圖2-8 臺燈按鍵模塊
按鍵K0、K1、K2用來調節(jié)臺燈的亮度,通過按下按鍵K0可以讓臺燈變亮,按下按鍵K1可以讓臺燈變的更亮,按下按鍵K2可以讓臺燈燈光達到最亮。3 個I/O 均采用低電平有效方式。
2.3.5 DS1302時鐘電路模塊
下圖示出DS1302的引腳排列圖,其中Vcc1為后備電源,Vcc2為主電源。在主電源關閉的情況下,也能保持時鐘的連續(xù)運行。DS1302由Vcc1或Vcc2兩者中的較大者供電。當Vcc2大于Vcc1+0.2V時,Vcc2給DS1302供電。當Vcc2小于Vcc1時,DS1302由Vcc1供電。X1和X2是振蕩源,外接32.768KHz晶振。RST是復位/片選線,通過把RST輸入驅動置高電平來啟動所有的數(shù)據(jù)傳送。RST輸入有兩種功能:首先,RST接通控制邏輯,允許地址/命令序列送入移位寄存器;
其次,RST提供終止單字節(jié)或多字節(jié)數(shù)據(jù)的傳送手段。當RST為高電平時,所有的數(shù)據(jù)傳送被初始化,允許對DS1302進行操作。如果在傳送過程中RST置為低電平,則會終止此次數(shù)據(jù)傳送,I/O引腳變?yōu)楦咦钁B(tài)。上電動行時,在Vcc大于等于2.5V之前,RST必須保持低電平。中有在SCLK 為低電平時,才能將RST置為高電平,I/O為串行數(shù)據(jù)輸入端(雙向)。SCLK始終是輸入端。
表1 DS1302引腳功能表
引腳號
引腳名稱
功能
1
VCC2
主電源
2、3
X1、X2
振蕩源,外接32768Hz晶振
4
GND
地線
5
RST
復位/片選線
6
I/O
串行數(shù)據(jù)輸入/輸出端(雙向)
7
SCLK
串行時鐘輸入端
8
VCC1
后備電源
DS1302在每次進行讀、寫程序前都必須初始化,先把SCLK端置“0”,接著把RST端置“1”,最后才給予SCLK脈沖。DS1302的控制字,此控制字的位7必須置1,若為0則不能把對DS1302進行讀寫數(shù)據(jù)。對于位6,若對程序進行讀/寫時RAM=1,對時間進行讀/寫時,CK=0。位1至位5指操作單元的地址。位0是讀/寫操作位,進行讀操作時,該位為1;該位為0則表示進行的是寫操作??刂谱止?jié)總是從最低位開始輸入/輸出的。DS1302的日歷、時間寄存器內容:“CH”是時鐘暫停標志位,當該位為1時,時鐘振蕩器停止,DS1302處于低功耗狀態(tài);當該位為0時,時鐘開始運行?!癢P”是寫保護位,在任何的對時鐘和RAM的寫操作之前,“WP”必須為0。當“WP”為1時,寫保護位防止對任一寄存器的寫操作。
圖2-9 DS1302時鐘電路模塊
2.3.6 1602LCD顯示模塊
字符型液晶顯示模塊是一種專門用于顯示字母、數(shù)字、符號等點陣式LCD,目前常用16*1,16*2,20*2和40*2行等的模塊。
1602LCD分為背光和不帶背光兩種,基控制大部分為HD44780,帶背光的比不帶背光的厚,是否帶背光在應用中并無差別,引腳功能說明:
表2 1602LCD功能表
編號
符號
引腳說明
編號
符號
引腳說明
1
Vss
電源地
9
D2
數(shù)據(jù)口
2
Vcc
電源正極
10
D3
數(shù)據(jù)口
3
VO
液晶顯示對比度調節(jié)端
11
D4
數(shù)據(jù)口
4
RS
數(shù)據(jù)/命令選擇端(H/L)
12
D5
數(shù)據(jù)口
5
R/W
讀寫選擇端(H/L)
13
D6
數(shù)據(jù)口
6
E
能使信號
14
D7
數(shù)據(jù)口
7
D0
數(shù)據(jù)口
15
BLA
背光電源正極
8
D1
數(shù)據(jù)口
16
BLK
背光電源負極
1602LCD采用標準的14腳(無背光)或16腳(帶背光)接口,各引腳接口說明如表2所示:
第1腳:VSS為地電源。
第2腳:VDD接5V正電源。
第3腳:VEE為液晶顯示器對比度調整端,接正電源時對比度最弱,接地時對比度最高,對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度。
第4腳:RS為寄存器選擇,高電平時選擇數(shù)據(jù)寄存器、低電平時選擇指令寄器。
第5腳:R/W為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。當RS和R/W共同為低電平時可以寫入指令或者顯示地址,當RS為低電平R/W高電平時可以讀忙信號,當RS為高電平R/W為低電平時可以寫入數(shù)據(jù)。
第6腳:E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執(zhí)行命令。
第7~14腳:D0~D7為8位雙向數(shù)據(jù)線。
1602LCD的一般初始化(復位)過程
延時15mS
寫指令38H(不檢測忙信號)
延時5mS
寫指令38H(不檢測忙信號)
延時5mS
寫指令38H(不檢測忙信號)
以后每次寫指令、讀/寫數(shù)據(jù)操作均需要檢測忙信號
寫指令38H:顯示模式設置
寫指令08H:顯示關閉
寫指令01H:顯示清屏
寫指令06H:顯示光標移動設置
寫指令0CH:顯示開及光標設置
LCD1602液晶顯示,如下圖所示:
圖2-10 1602LCD顯示模塊
2.3.7 調節(jié)時鐘按鍵模塊
因為有年月日,時分秒幾個參數(shù)要調,所以設置這幾個參數(shù)的計數(shù)。當按下一個鍵時,單片機進行相應的操作。根據(jù)設計要求需要選擇四個獨立按鍵分別為選擇、加、減、確定,按鍵用來調整時間和設置鬧鐘,調光亮度,各鍵功能在介紹硬件部分已描述。按鍵模塊下圖所示:
圖2-11 調節(jié)時鐘按鍵模塊
第三章 系統(tǒng)的軟件設計
3.1 系統(tǒng)軟件編程工具C和C++
3.1.1 C簡介
C語言是一種計算機程序設計語言,它既具有高級語言的特點,又具有匯編語言的特點。它可以作為工作系統(tǒng)設計語言,編寫系統(tǒng)應用程序,也可以作為應用程序設計語言,編寫不依賴計算機硬件的應用程序。它的應用范圍廣泛,具備很強的數(shù)據(jù)處理能力,不僅僅是在軟件開發(fā)上,而且各類科研都需要用到C語言,適于編寫系統(tǒng)軟件、三維、二維圖形和動畫,具體應用例如單片機以及嵌入式系統(tǒng)開發(fā)。
C程序是由一組變量或是函數(shù)的外部對象組成的。 函數(shù)是一個自我包含的完成一定相關功能的執(zhí)行代碼段。我們可以把函數(shù)看成一個“黑盒子”,你只要將數(shù)據(jù)送進去就能得到結果,而函數(shù)內部究竟是如何工作的的,外部程序是不知道的。外部程序所知道的僅限于輸入給函數(shù)什么以及函數(shù)輸出什么。函數(shù)提供了編制程序的手段,使之容易讀、寫、理解、排除錯誤、修改和維護。C程序中函數(shù)的數(shù)目實際上是不限的,如果說有什么限制的話,那就是,一個C程序中必須至少有一個函數(shù),而且其中必須有一個并且僅有一個以main為名,這個函數(shù)稱為主函數(shù),整個程序從這個主函數(shù)開始執(zhí)行。C 語言程序鼓勵和提倡人們把一個大問題劃分成一個個子問題,對應于解決一個子問題編制一個函數(shù),因此,C 語言程序一般是由大量的小函數(shù)而不是由少量大函數(shù)構成的,即所謂“小函數(shù)構成大程序”。這樣的好處是讓各部分相互充分獨立,并且任務單一。因而這些充分獨立的小模塊也可以作為一種固定規(guī)格的小“構件”, 用來構成新的大程序。
3.1.2 C++
C++是在C語言的基礎上開發(fā)的一種集面向對象編程、泛型編程和過程化編程于一體的編程語言。應用較為廣泛,是一種靜態(tài)數(shù)據(jù)類型檢查的,支持多重編程的通用程序設計語言。它支持過程化程序設計,數(shù)據(jù)抽象,面向對象設計,制作圖標等多種程序設計風格。在操作系統(tǒng)和系統(tǒng)使用程序以及需要對硬件進行操作的場合,用C語言明顯優(yōu)于其它高級語言,但在編寫大型程序時,C語言仍面臨著挑戰(zhàn)。C語言是C++的基礎,C++和C語言在很多方面是兼容的。
C語言是一個結構化語言,它的重點在于算法與數(shù)據(jù)結構。C程序的設計首要考慮的是如何通過一個過程,對輸入(或環(huán)境條件)進行運算處理得到輸出(或實現(xiàn)過程(事物)控制)。C++,首要考慮的是如何構造一個對象模型,讓這個模型能夠契合與之對應的問題域,這樣就可以通過獲取對象的狀態(tài)信息得到輸出或實現(xiàn)過程(事物)控制。所以C語言和C++的最大區(qū)別在于它們解決問題的思想方法不一樣。C++語言的主要特點表現(xiàn)在兩個方面,一是盡量兼容C,二是支持面向對象的方法。它操持了C的簡潔、高效的接近匯編語言等特點,對C的類型系統(tǒng)進行了改革的擴充,因此C++比C更安全,C++的編譯系統(tǒng)能檢查出更多的類型錯誤。另外,由于C語言的廣泛使用,因而極大的促進了C++的普及和推廣。
C++由四個“子語言”組成:C子語言,C++支持C語言的幾乎全部功能,主要是c89的部分,在語法上與C語言僅有極微妙的差別(如括號表達式的左右值性,具體請參考C++標準文獻)。這部分功能對應于傳統(tǒng)的面向過程的編程泛型,并提供了面向函數(shù)編程泛型的基礎。面向對象的C++語言,C++語言原本不具備面向對象的設計功能,然而隨著面向對象編程的概念的普及,C++語言也開發(fā)出了支持面向對象功能的版本。這部分功能對應于面向對象的編程泛型。泛型編程語言,C++強大(但容易失控的)模板功能使它能在編譯期完成許多工作,從而大大提高運行期效率,并且大大提高了C++的表達能力。STL(C++標準模板庫,Standard Template Library)是一個基于模板技術的庫。隨著STL的不斷發(fā)展,它已經逐漸成為C++程序設計中不可或缺的部分,其效率可能比一般的native代碼低些,但是其安全性與規(guī)范性使它大受歡迎。模板使C++能夠支持泛型編程(generic programming)和生成式編程(generative programming)
的泛型。在C++0X中引入的Lambda,使得程序員可以定義匿名函數(shù),完善了C++對于面向函數(shù)的編程泛型的支持。
3.2 主程序的設計流程圖
圖3-1 主程序流程圖
一給單片機上電,單片機就初始化。通過接收并處理,有人按下開關就工作。然后檢開始LED工作顯示時間、日期,按鍵按下,修正時間,設置鬧鐘系統(tǒng)初始化測按鍵是否按下,判斷工作在那個模式下。液晶還顯示當前的時間,日期,最后進入循環(huán)。
3.3 臺燈模塊編程
3.3.1 臺燈模塊流程圖
該模塊只需給LED紅燈D0的P1.4口、黃燈D1到D4的P1.5口和綠燈D5到D12的P1.6口送低電平即可,再通過按鍵K0、K1、K2調LED燈光亮度。
圖3-2 臺燈模塊流程圖
3.3.2 臺燈模塊程序
#include
sbit K0=P2^5;//調光燈亮度等級開關I/O口分配
sbit K1=P2^6;
sbit K2=P2^7;
sbit D0=P1^4;//LED燈I/O口分配
sbit D1=P1^5;
sbit D2=P1^5;
sbit D3=P1^5;
sbit D4=P1^5;
sbit D5=P1^6;
sbit D6=P1^6;
sbit D7=P1^6;
sbit D8=P1^6;
sbit D9=P1^6;
sbit D10=P1^6;
sbit D11=P1^6;
sbit D12=P1^6;
void main()//主程序
{
while(1)
{
if(K0==0)//一級亮度調光開關被按下
{
D0=0; //D3燈亮
}
else
{
D0=1; //D3燈滅
}
if(K1==0)//二級亮度調光開關被按下
{
D1=0;//D1,D2,D3,D4燈亮
D2=0;
D3=0;
D4=0;
}
else
{
D1=1;//D1,D2,D3,D4燈滅
D2=1;
D3=1;
D4=1;
}
if(K2==0)//三級亮度調光開關被按下
{
D5=0; //D5,D6,D7,D8,D9,D10,D11,D12燈亮
D6=0;
D7=0;
D8=0;
D9=0;
D10=0;
D11=0;
D12=0;
}
else
{
D5=1; //D5,D6,D7,D8,D9,D10,D11,D12燈滅
D6=1;
D7=1;
D8=1;
D9=1;
D10=1;
D11=1;
D12=1;
}
}
}
3.4 LCD1602液晶顯示
3.4.1 時鐘設置流程圖
調整時間用4個調整按鈕,1個作為選擇控制用,另外3個分別作為加調整,減調整和確定用。
圖3-3 時鐘設置流程圖
3.4.2 時鐘程序
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit RS=P2^0; // LCD寄存器選擇
sbit RW=P2^1; // LCD讀寫控制
sbit EN=P2^2; // LCD啟動
//*--------延時子程序--------*//
void DelayMS(uint K)
{
uchar i;
while(K--)
{
for(i=0;i<120;i++);
}
}
//*----------讀取LCD的狀態(tài)-------*//
uchar Read_LCD_State()
{
uchar state;
RS=0;
RW=1;
EN=1;
DelayMS(2);
state=P0;
EN=0;
DelayMS(2);
return state;
}
//*-------------忙檢查--------------*//
void LCD_Busy_Wait()
{
while((Read_LCD_State()&0x80)==0x80);
DelayMS(5);
}
//*-----------寫LCD命令-----------------*//
void Write_LCD_Command(uchar cmd)
{
LCD_Busy_Wait();
RS=0;
RW=0;
EN=0;
P0=cmd;
EN=1;
DelayMS(2);
EN=0;
}
//*-----------向LCD寫入數(shù)據(jù)-----------------*//
void Write_LCD_Data(uchar dat)
{
LCD_Busy_Wait();
RS=1;
RW=0;
EN=0;
P0=dat;
EN=1;
DelayMS(2);
EN=0;
}
//*-----------LCD初始化-----------------*//
void Initialize_LCD1602() //液晶初始化函數(shù)
{
Write_LCD_Command(0x38);DelayMS(2); //功能設置,數(shù)據(jù)長度為8位,雙行顯示,5×7點陣字體
Write_LCD_Command(0x01);DelayMS(2); //清屏
Write_LCD_Command(0x06);DelayMS(2); //字符進入模式:屏幕不動,字符后移
Write_LCD_Command(0x0c);DelayMS(2); // 顯示開,關光標
}
//*-----------設置液晶顯示位置-----------------*//
void Set_LCD_Position(uchar pos)
{
Write_LCD_Command(pos|0x80); //設置7位的DDRAM地址值
}
//*-----------在LCD上顯示字符串-----------------*//
void LCD_Display(uchar p,uchar *str)
{
uchar i;
Set_LCD_Position(p);
for(i=0;i<16;i++)
{
Write_LCD_Data(str[i]);
DelayMS(2);
}
}
//*----------main.c源程序----------*//
//*-----用DS1302和1602液晶顯示的實時時鐘-----*//
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
void Initialize_LCD1602(); //液晶初始化函數(shù)
void LCD_Display(uchar p,uchar *str);
sbit SDA=P1^0; //DS1302數(shù)據(jù)線
sbit CLK=P1^1; //DS1302時鐘線
sbit RST=P1^2; // DS1302 復位線
sbit k1=P3^4; // 選擇按鍵
sbit k2=P3^5; // 加
sbit k3=P3^6; // 減
sbit k4=P3^7; // 確定
uchar tcount=0;
uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; // 一年中每個月的天數(shù),二月的天數(shù)由年份決定
uchar *Week[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"}; //周日,周一到周六
// LCD顯示緩沖
uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00 "} ;
uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "} ;
uchar DateTime[7];//所讀取的日期時間
char Adjust_Index=-1; //當前調節(jié)的時間對象:秒,分,時,日,月,年(0,1,2,3,4,6)
uchar Change_Flag[]="-MHDM-Y";//(分,時,日,月,年)不調節(jié)秒和周
//函數(shù)聲明
void Write_Byte_TO_DS1302(uchar X); // 向DS1302寫入一個字節(jié)
uchar Read_Byte_FROM_DS1302(); //從DS1302中讀取一個字節(jié)
uchar Read_Data_FROM_DS1302(uchar addr); //從DS1302指定位置讀取數(shù)據(jù) , 讀數(shù)據(jù)
void Write_Data_TO_DS1302(uchar addr,uchar dat); // 向DS1302指定位置寫入數(shù)據(jù), 寫數(shù)據(jù)
void SET_DS1302(); // 設置時間
void GetTime(); // 讀取當前時間
void Initialization(); //初始化函數(shù)
//*----------主程序----------*//
void main()
{
Initialization();
while(1)
{
if(Adjust_Index==-1)
GetTime();
}
}
//*-----------------初始化函數(shù)--------------*//
void Initialization()
{
Initialize_LCD1602(); //調用液晶初始化函數(shù)
IE=0x83; //允許中斷 外部0中斷和T0中斷
IP=0x01; // 設置中斷優(yōu)先級
IT0=0x01; // 設置外部中斷的脈沖觸發(fā)方式
TMOD=0x01; // 設置定時器的工作方式,為方式1
TH0=-50000/256; // 寫入初值
TL0=-50000%256; // 寫入初值
TR0=1; // 啟動定時器
}
//*--------寫字節(jié)函數(shù),向DS1302寫入一個字節(jié)--------*//
void Write_Byte_TO_DS1302(uchar X) // 向DS1302寫入一個字節(jié)
{
uchar i;
for(i=0;i<8;i++)
{
SDA=X&1;
CLK=1;
CLK=0;
X>>=1;
}
}
//*--------讀字節(jié)函數(shù),從DS1302讀取一個字節(jié)--------*//
uchar Read_Byte_FROM_DS1302() //從DS1302中讀取一個字節(jié)
{
uchar i,byte,t;
for(i=0;i<8;i++)
{
byte>>=1;
t=SDA;
byte|=t<<7;
CLK=1;
CLK=0;
}
//-------------------------------------------------------------
//BCD碼轉換
//-------------------------------------------------------------
return byte/16*10+byte%16;
}
//-------------------------------------------------------------
//從DS1302指定位置讀取數(shù)據(jù),讀數(shù)據(jù)
//-------------------------------------------------------------
uchar Read_Data_FROM_DS1302(uchar addr) //從DS1302指定位置讀取數(shù)據(jù) , 讀數(shù)據(jù)
{
uchar dat;
RST=0;
CLK=0;
RST=1;
Write_Byte_TO_DS1302(addr); //向DS1302寫入一個地址
dat=Read_Byte_FROM_DS1302(); //在上面寫入的地址中讀取數(shù)據(jù)
CLK=1;
RST=0;
return dat;
}
//-------------------------------------------------------------
//向DS1302指定位置寫入數(shù)據(jù), 寫數(shù)據(jù)
//-------------------------------------------------------------
void Write_Data_TO_DS1302(uchar addr,uchar dat) // 向DS1302指定位置寫入數(shù)據(jù), 寫數(shù)據(jù)
{
CLK=0;
RST=1;
Write_Byte_TO_DS1302(addr);
Write_Byte_TO_DS1302(dat);
CLK=1;
RST=0;
}
//---------------------------------------------------------
// 設置時間
//---------------------------------------------------------
void SET_DS1302() // 設置時間
{
uchar i;
Write_Data_TO_DS1302(0x8E,0x00); //寫控制字,取消寫保護
// 分,時,日,月,年依次寫入
for(i=1;i<7;i++)
{
// 分的起始地址是10000010(0x82),后面依次是時,日,月,周,年,寫入地址每次遞增2 Write_Data_TO_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));
}
Write_Data_TO_DS1302(0x8E,0x80); //寫控制字,加寫保護
}
//--------------------------------------------------------
// 讀取當前時間
//-------------------------------------------------------
void GetTime() // 讀取當前時間
{
uchar i;
for(i=0;i<7;i++)
{
DateTime[i]=Read_Data_FROM_DS1302(0x81+2*i);
}
}
//------------------------------------------------------------
//日期與時間值轉換為數(shù)字字符
//-------------------------------------------------------------
void Format_DateTime(uchar d,uchar *a)
{
a[0]=d/10+'0';
a[1]=d%10+'0';
}
//-------------------------------------------------------------------
// 判斷是否為閏年
//-------------------------------------------------------------------
uchar Is_Leapyear(uint year)
{
return (year%4==0&&year%100!=0)||(year%400==0) ;
}
//------------------------------------------------------------------
// 求自2000.1.1開始的任何一天是星期幾?
//-------------------------------------------------------------------void Refresh_Week_Day()
{
uint i,d,w=5; //已知1999年12.31是星期五
for(i=2000;i<2000+DateTime[6];i++)
{
d=Is_Leapyear(i)?366:365;
w=(w+d)%7;
}
d=0;
for (i=1;i
收藏