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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于單片機的1602萬年歷程序設計資料(附帶小鬧鐘)可做單組自動打鈴系統

  [復制鏈接]
跳轉到指定樓層
樓主
ID:309367 發表于 2018-6-18 14:11 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
自己做過的設計資料,現在放在51hei論壇上,用得著的朋友可以下去用,功能簡單易懂,一些不好的地方可以自己開發或者拓展改進。純粹學習用

設計主要研究基于單片機的自動打鈴系統。設計的系統利用時鐘芯片提供走時,并由單片機對其進行監測和控制,然后通過顯示模塊將時間數據反饋給用戶,同時根據用戶設定的時刻進行打鈴提醒。設計采用的核心控制器是STC89C51單片機,確保對時鐘的實時監測;提供時鐘信號的芯片是DS1302,可以產生較為精準的時鐘;所有的時間數據通過LCD1602顯示器反饋給用戶,這款顯示器具有體積小巧、功耗低的優點;最后根據用戶設定時間用蜂鳴器打鈴輸出。通過對系統的軟、硬件進行設計,并進行系統仿真和系統測試,完成對基于單片機的自動打鈴系統的設計與實現。



Abstract

The design mainly studies the automatic bell ringing system based on single chip microcomputer. The designed system uses the clock chip to provide travel time, and monitors and controls it by the single chip computer. Then the time data is fed back to the user through the display module, and the bell is remined by the time set by the user. The core controller used in the design is the STC89C51 microcontroller to ensure real-time monitoring of the clock. The chip of the clock signal is DS1302, which can produce a more accurate clock. All the time data are fed back to the user through the LCD1602 display. This display has the advantages of small size and low power consumption; finally, it is based on the user. Set the time to bell the output by the buzzer. Through the design of the hardware and software of the system, and the system simulation and system debugging, the design and implementation of the automatic bell system based on single chip microcomputer is completed.


              目錄            

第1章 緒論

1.1 研究的目的和意義

1.2國內外的發展研究狀況

1.3研究的基本任務與方案設計

1.3.1 研究任務

1.3.2 方案設計

1.4 文檔的內容與結構

第2章 硬件電路的設計與實現

2.1 硬件電路總體設計

2.2 單片機最小系統

2.3 顯示電路設計

2.4 按鍵電路設計

2.5 時間電路設計

2.6 打鈴電路的設計

第3章 軟件電路的設計與實現

3.1 軟件系統設計

3.2 顯示子程序

3.3 按鍵子程序

3.4 時間子程序

3.5 打鈴子程序

第4章 開發軟件的介紹及系統測試

4.1 開發軟件的介紹

4.1.1 Proteus
4.1.2 Keil C

4.2 系統仿真

4.3 系統測試

第5章 結論
參考文獻
致謝
附錄

附錄一:自動打鈴系統原理圖

附錄二:源程序


第1章 緒論
1.1
研究的目的和意義

隨著電子計算機技術的高速發展,以及其在信息處理系統中的廣泛應用,單片機作為一種采用超大規模集成電路技術、并把具有數據處理能力的中央處理器CPU和隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統、定時/計數器等功能(可能還包括顯示驅動電路、脈寬調制電路、模擬多路轉換器、A/D轉換器等電路)集成到一塊硅片上構成的一個小而完善的計算機系統。其體積小、功能強、成本低、適用范圍廣,體現出了其很大的使用價值。縱觀我們現在生活的各個領域,從導彈的導航裝置,到飛機上各種儀表的控制,從計算機的網絡通訊與數據傳輸,到工業自動化過程的實時控制和數據處理,以及我們生活中廣泛使用的各種智能IC卡、電子寵物等,這些都離不開單片機。以前沒有單片機時,這些東西也能做,但是只能使用復雜的模擬電路,然而這樣做出來的產品不僅體積大,而且成本高,并且會因為長期使用,使得元器件不斷老化,控制的精度自然也會達不到標準。在單片機產生后,我們就將控制這些東西變得智能化了,我們只需要在單片機外圍接一點簡單的接口電路,核心部分只是由人為的寫入程序來完成。這樣產品的體積變小了,成本也降低了,長期使用也不會擔心精度達不到的問題。所以,它的魔力不僅是在現在,在將來將會有更多的人來接受它、使用它。據統計,我國的單片機年容量已達到3億片,且每年以大約30%的速度高速增長。隨著開發以及推出單片機的公司越來越多,各種高性能的單片機芯片市場也日趨活躍。新技術的不斷加入和納入使用,使得單片機的性能和種類及其應用范圍不斷增強和擴大。集成的功能及其展現出的性能得到了逐步的全面和強化,所以單片機會越來越受到廣大用戶的青睞和使用。

而今,在很多的公共場所,例如學校、機關、工廠、車站等單位,都是用電鈴作為作息時間信號的。而最原始的電鈴控制方式就是人工打鈴,采用邏輯電路進行控制,其原理簡單、便于操作,但會導致設備體積過大,不利于臨時調整。所以,就引入以單片機為基礎控制的自動打鈴系統,這樣不僅節省了人力,同時也使得設備的集成化大大提高,而且便于設備的調整。為此,設計一種基于單片機的自動打鈴系統,采用數字鐘和自動打鈴系統相結合的方式。該系統一單片機為核心來控制各個功能模塊,使用者可以隨時對作息時間進行修改,可以很方便地設定作息時間方案。這是一個集數字鐘顯示、設置、打鈴為一體的多功能打鈴計時系統。這樣,通過簡單的設置,就可以滿足任何學校、企事業公共場所和單位的需求。而本設計就是理論與實踐并重,對于有效地掌握單片機的應用具有很重要的意義。

1.2國內外的發展研究狀況

自1986年德國誕生了世界上第一款商用電子時鐘后,電子鐘的發展趨勢在全球逐步蔓延開來。繼德國之后,日本也普及了電子鐘,英國、美國以及大多數歐洲國家也都在將消費者的熱點轉移到了電子鐘表上面,逐步提高了市場占有率。中國是繼德、日、英、美以后,第五個擁有電子鐘制造技術的國家。中國科學院國家授時中心與西安高華科技有限公司,在河南建立了電子鐘研發基地,用于開發多功能的電子鐘表和數字電子鐘等產品,極大地推動了電子鐘行業的發展。中國第一款數字電子時鐘已經推出針對中國市場接受中國國家授時中心信號的多功能電子鐘表,走時精確,在信號覆蓋區域外日累計誤差小于0.5秒,質量可靠,價格僅為國外同期同類競品的1/8。從區域格局來看,全國已形成以廣州、深圳為龍頭的珠三角地區、福建、浙江、江蘇、山東、天津等6大多功能時鐘主產區;從產量來看,我國已成為世界多功能時鐘生產大國,多功能時鐘產量穩居世界第一。監測數據顯示,2011年,我國多功能時鐘的產量達到2.89億只。我國多功能時鐘行業發展雖然取得長足的進步,但國內多功能時鐘企業及其品牌在國際市場上的信譽度和影響力還微不足道,產量占比雖然已經達到80%以上。可見,其發展趨勢迅猛。而隨著技術的進步,各種新的的功能也負之而上,使得電子鐘的精度大大提高。例如,在國外企業中,日本RICOH公司推出的時鐘芯片甚至已經出現時基軟件調校功能(TTF)及振蕩器停振自動檢測功能而且芯片的價格極為低廉。目前,這些芯片已被客戶大量使用中。最新一代時鐘芯片產品中,除了包含第二代產品所具有的全部功能,更加入了復合功能,如低電壓檢測,主備用電池切換功能,抗印制板漏電功能,且本身封裝更小(高度 0.85mm,面積僅2mm*2mm),如RICOH公司的代表產品R2051。而如今,使用范圍較廣的多功能電子時鐘一般由振蕩器,分頻器,譯碼器,顯示器等部分組成,這些都是數字電路中最基本的,應用最廣的電路。當前市場上已有現成的數字鐘集成電路芯片出售,價格較便宜。由于數字集成電路技術的發展,使數字電子鐘具有走時準確,性能穩定,攜帶方便等特點,是目前人們生活和工作補課或缺的報時用品。國內廠家的產品擁有時間、日期、溫度、夜光、貪睡功能、倒計時、順計時、省電模式、多組鬧鐘、可循環顯示、多檔亮度調節、12/24時制轉換、調節亮度、遙控操作等功能。比如美國的INTEL公司在上世紀80年代推出的AT89C51芯片與HD7279芯片構成的鍵盤控制電路,通過程序的編寫控制I/O口的輸出進而控制顯示定時數據及打鈴電路。當然也有部分采用德州儀器公司產的8255芯片為核心部件的打鈴系統,原理都大同小異。現今在一些特殊的對定時精確度要求高的領域。比如,微電子方面,體育競技項目等行業,單片機技術顯然會有一定的誤差,于是隨之出現了部分通過計算機控的打鈴系統,或者是結合其他影像技術設計而成的打鈴系統。隨著技術的不斷發展,自動打鈴系統不斷地走向體積小、模塊化的集成電路的形式,在一些大型的電子設備或機械儀器中充當不可或缺的一部分,基于單片機為基礎的打鈴系統不僅有較成熟的技術而且成本低廉、體積小,根據功能需求可以很容易的設計多元的定時器,未來的自動打鈴系統將會朝著多元化的趨勢行進,比如定時與記憶保護功能的實現,基于單片機為基礎的自動打鈴系統適合于低成本的大量生產,多元化發展的道路上具有很大的發展前景。

1.3研究的基本任務與方案設計
1.3.1 研究任務

研究基于單片機的自動打鈴系統設計,掌握基于單片機自動打鈴系統工作原理與設計思想,并設計具體電路,達到一定的設計要求,熟悉基本電路原理及模擬技術,掌握基于單片機的自動打鈴系統的結構及原理,具體電路設計和功能等。

1.3.2 方案設計

方案的確立與論證

根據設計要求,進行方案設計,形成以數字邏輯電路為基礎的方案一、以單片機位控制核心的方案二。對這兩種方案說明如下:

方案一:采用數字邏輯電路(即與或非等門電路)設計的自動打鈴系統。利用函數信號發生器來進行脈沖信號輸出,利用74160N來設置十進制和六進制的進位輸出。利用數碼顯示器來顯示時間,利用或門、與門、非門、與非門、等電路元件進行組合實現打鈴的控制。

方案二:采用以51單片機為基礎而設計的自動打鈴系統。單片機內部存儲器設三個字節分別存放時鐘的時、分、秒信息。利用定時器與軟件結合實現1秒定時中斷,每產生一次中斷,存儲器內相應的秒字節值加1;若秒字節值達到60,則將其清零,并將相應的分字節值加1;若分值達到60,則清零分字節,并將時字節值加1;若時值達到24,則將時字節清零。建立完一個實時時鐘后,接下來進行定時分析處理和打鈴輸出,當主程序檢測到有分進位標志時,便開始比較當前時間與用戶設定的定時時間是否相同,若相同,則執行打鈴提醒功能;不相同,則返回主程序。

通過對比以上兩種方案,可以看出:方案一的設計只能事先設定打鈴時間而不能完全自動打鈴,且在修改打鈴時間上存在一定的困難,操作過程繁瑣。而方案二中的設計就能完全實現自動化,并且控制精確、操作簡易、方便,也詮釋了本設計的最終要求和目的。所以,我選擇方案二進行設計。

根據所選定的設計方案,具體的設計主要分為硬件和軟件兩大部分,現規劃如下:

硬件部分其中包括電路原理圖、合理選擇元器件、繪制線路圖,然后對硬件進行調試、測試,達到設計要求。硬件電路采用結構化系統設計方法,該方法保證設計電路的標準化、模塊化。硬件電路的設計最重要的選擇用于控制的單片機,并確定與之配套的外圍芯片,使設計的系統既經濟又高性能。硬件電路設計包括輸入射出接口設計,畫出詳細電路圖,標出芯片的信號、器件參數值,根據電路圖在仿真機上進行調試,修改,最終達到設計要求。

軟件部分:首先在總體設計中完成軟件系統流程規劃和各模塊的功能設計,然后進行具體設計,包括各模塊的流程圖,軟件程序編寫等;最后對軟件進行調試、測試,達到所需的功能要求。

1.4 文檔的內容與結構

在自動打鈴系統的基礎上可以實現多種功能,設計主要研究時間內容的顯示與時間數據的分析并響應兩大部分。文檔共有五章。第一章對自動打鈴系統的概況進行簡單的介紹,包括自動打鈴系統的研究意義和當前的發展狀況。第二章介紹本設計的硬件電路方案,包括單片機系統、LCD顯示部分、按鍵部分、時鐘部分、打鈴部分等。第三章則詳細地介紹軟件系統的設計流程和各項子程序的設計流程。第四章介紹本設計用到的開發軟件,以及對硬件的測試與調試。第五章結論里對本設計進行了總結。


第2章 硬件電路的設計與實現

2.1 硬件電路總體設計

系統的總硬件原理圖和實物圖分別為圖2-1與圖2-2,本系統主要由主控電路,時鐘電路,顯示電路,按鍵電路等4 部分構成。通過內部定時產生中斷,從而使驅動電鈴打鈴。設定51 單片機工作在定時器0工作方式1 ,每100ms產生一次中斷,利用軟件將基準100ms 單元進行累加,當定時器產生10 次中斷就產生lS 信號,這是秒單元加1 。同理,對分單元和時單元計數從而產生秒,分,時的值。由于動態顯示法需要數據所存等硬件,接口較復雜,考慮顯示的位數和系統沒有其他浮躁的處理程序,所以采用LCD1602進行顯示。本系統采用四個按鍵,當時鐘時間和設置時間一致時,CPU控制蜂鳴器進行打鈴。系統設計的實物圖如圖2-2所示。

圖2-1總硬件電路原理圖

圖2-2總硬件電路實物圖

2.2 單片機最小系統

單片機的最小系統是指單片機工作時所需的最少元件,即:單片機、晶振電路、復位電路。本設計主要采用的STC89C51單片機最小系統如圖2-3所示。

圖2-3單片機最小系統

STC89C51單片機

本設計采用STC89C51單片機,如圖2-4所示。STC89C51是一款高性能、低功耗的8位CMOS微處理芯片其具備4K的FLASH程序存儲器,256字節的內部RAM、6個不同的中斷源、4和中斷優先級、4個8位I/O口、2個16位的定時計數器、全雙工的串口通信。

圖2-4 STC89C51單片機引腳圖

各引腳的用途如下所示:

  • VCC(40):接電源+5V,用于電路供電。
  • GND(20):接地,用于保護電路。
  • XTAL1(19)和XTAL2(18):當時鐘脈沖式輸入狀態時,用外部振蕩電路,如果有1個外接電容,就用時鐘電路。當外部時鐘脈沖來臨時,用來接輸入的脈沖信號。由于石英晶體和外部電容的作用,故該口也有反向放大的作用。
  • P0(39-32):雙向I/O口,不拓展的情況下,可用作普通的輸入輸出使用。也可用作地址數據總線口使用、
  • P1(1-8):準雙向通用I/O口,可輸出推動4個肖特基TTL負載,一般加一個上拉電阻以便外部接收器不被損壞,此時它就是輸入端口。
  • P2(21-28):不拓展時,用作一般的雙向I/O口,當它為 8 位雙向 I/O 口時,P2 緩沖器可以接受輸出的 4個晶體管-晶體管邏輯電路門限電流。當 P2口收到的信號為“1”時候,說明外加的電壓大于單片機的電壓,單片機內部將管腳電壓升高,讓該管腳作為輸入端口。
  • P3(10-17):多用途端口。P3口管腳是由8個內部上拉電阻組成的雙向I/O 口,可接收輸出4個TTL門電流。當P3口收到“1”,單片機機內部的電阻開始作用,對此口加上高電平,使得這個管腳有輸入作用
  • RST(9):復位信號輸入端口,收到高電位時,便開始工作,要完成復位作用就需要無外部的時鐘脈沖進行作用。此時會出現多個振蕩周期的高電平信號,它們加在復位端口,完成復位用。
  • EA(31):內部和外部程序存儲器的選擇線,該引腳為低電平EA=0時,讀取外部ROM 0000H-FFFFH,當該引腳為高電位時,地址0000H-0FFFH訪問ROM, 000H-FFFFH訪問外部ROM。
  • PSEN(29):即片選程序存儲器選通信號,當低電平信號到來時,它會自動訪問單片機尾部的程序存儲器。但此時需要兩個連續低電平信號持續訪問才有效。
  • ALE/PROG(30):ALE為高電平信號,同時也是外部地址鎖存器的鎖存信號。在沒有特殊要求的情況下,FALE=1/6FOSC,因此它可以用作其他芯片的時鐘源或用于定時作用。
2.3 顯示電路設計

顯示器是屬于I/O設備,即輸入輸出設備。它是一種將一定的電子文件通過特定的傳輸設備顯示到屏幕上再反射到人眼的顯示工具。而本設計的顯示部分采用的是LCD1602液晶顯示器。其電路圖和實物圖如圖2-5與圖2-6所示。這是一款工業字符型液晶,顯示質量極高,能夠同時顯示16x02即32個字符。其顯示的原理是利用液晶的物理特性,通過電壓對其顯示區域進行控制,即可以顯示出圖形。不過,由于單片機P0口不能輸出高電平,所以必須在LCD1602 上加上拉電阻從而使其能輸出高電平。

圖2-5 LCD1602液晶顯示器電路圖

圖2-6 LCD1602液晶顯示器實物圖

LCD1602引腳功能說明如下:

第1引腳:GND為電源地

第2引腳:VCC接5V電源正極

第3引腳:V0為液晶顯示器對比度調整端,接正電源時對比度最弱,接地電源時對比度最高

第4引腳:RS為寄存器選擇,高電平1時選擇數據寄存器、低電平0時選擇指令寄存器。

第5引腳:RW為讀寫信號線,高電平(1)時進行讀操作,低電平(0)時進行寫操作。

第6引腳:E(或EN)端為使能(enable)端,高電平(1)時讀取信息,負跳變時執行指令。

第7~14引腳:D0~D7為8位雙向數據端。第15~16腳:空腳或背燈電源。第15引腳背光正極,第16引腳背光負極。

2.4 按鍵電路設計

按鍵在電路中的作用就是通過觸點的接觸與斷開來控制電路的通斷。而本設計由于鍵盤只有四個,采用獨立式按鈕,通過查詢完成讀取鍵盤功能分別為K1,K2,K3,K4。其中,K1用以加和查看農歷,K2應以減,K3用以切換設置選項、K4用以進入設置界面和返回時鐘走時主界面。控制時、分、秒的調節以及設定時間模式的開關和返回正常走時模式的功能。按鍵電路的電路圖和實物圖如圖2-7和2-8所示。

圖2-7按鍵電路圖

圖2-8按鍵實物圖

2.5 時間電路設計

本設計采用的時鐘是DS1302。DS1302是一種高性能、低功耗、帶RAM的實時時鐘芯片,它可以對年、月、日、時、分、秒進行計時,具有閏年補償功能,工作電壓為2.0V~5.5V。采用三線接口與CPU進行同步通信,并可采用突發方式一次傳送多個字節的時鐘信號或RAM數據。其與單片機之間能簡單地采用同步串行的方式進行通信,僅需用到三個口線:1.RSE復位,2.I/O數據線,3.SCLK 串行時鐘。時鐘/RAM 的讀/寫數據以一個字節或多達31個字節的字符組方式通信。DS1302工作時功耗很低。提供秒、分、時、日、月、年的信息,每月的天數和閏年的天數可自動調整時鐘,操作可通過AM/PM指示決定采用24或12小時格式。其電路圖和實物圖如圖2-9和2-10所示。

圖2-9 DS1302電路圖


圖2-10 DS1302實物圖

DS1302引腳功能說明如下:

XI XZ 32.768KHz 晶振管腳。

GND 接地。

RST 復位腳。

I/O 數據輸入/輸出引腳。

SCLK 串行時鐘。

VCC1、VCC2 電源供電管腳。

DS1302 串行時鐘芯片8腳 DPI。

DS1302S 串行時鐘芯片8腳 SOIC 200mil。

DS1302Z 串行時鐘芯片8腳 SOIC 150mil。

2.6 打鈴電路的設計

打鈴是為了在用戶需要的時刻起到必要的提醒作用,本設計針對用戶設定的時間進行響應,將實時對比設定時間和系統走時,二者相一致時,打鈴電路就會開始工作。打鈴電路的電路圖與實物圖如圖2-11和2-12所示。蜂鳴器兩端分別接電源和89C51的P3.7接口,接收來自單片機的信號,從而實現打鈴功能。

圖2-11打鈴電路電路圖

圖2-12打鈴電路實物圖(蜂鳴器)










第3章 軟件電路的設計與實現3.1 軟件系統設計

根據硬件電路設計,軟件設計的總流程圖如圖3-1所示。外部電源供電后,系統完成初始化,之后就讀取時間、顯示時間。然后判斷用戶是否要對時間進行調整,若需要,則調整時間,反之則不調整。之后判斷是否需要設置時間進行打鈴提示,若需要,則設置,否則不不設置。最后判斷當前時間是否為設定的打鈴時間,是則打鈴,反之不打鈴并返回讀取時間顯示處,重復進行。

圖3-1軟件設計總流程圖

3.2 顯示子程序

顯示電路流程圖如圖3-2所示。起初,LCD1602初始化顯示。當RS為高電平、RW為低電平時,寫入數據,液晶屏顯示預設值。經過10us的延時后清屏,設置數據為8位,然后,顯示器待機等待數據,數據到來時,顯示在屏幕上。此時,判斷是否顯示完畢,若已顯示完畢,就結束;反之,就繼續接受數據顯示,直至顯示完畢。

圖3-3顯示電路流程圖
3.3 按鍵子程序

按鍵電路流程圖如圖3-4所示。本設計采用了4個獨立按鍵,因工作方式相同,故流程相同。首先判斷按鍵是否閉合,若是,則延時10ms。然后再次判斷按鍵是否,若仍是,則對其進行處理,反之則返回重復執行。

圖3-4按鍵電路流程圖

3.4 時間子程序

時間電路流程圖如圖3-5所示。首先讀取系統默認的時間,再根據用戶需要是否做出調整,若需要,則調整;不需要,則結束。

圖3-5時間電路流程圖

3.5 鈴子程序

打鈴電路流程圖如圖3-6所示。首先,進行初始化,然后讀取當前時間數據,隨后判斷讀取時間與用戶設定的打鈴時間是否一致,是,則打鈴;反之則結束程序。

圖3-6打鈴電路流程圖


第4 開發軟件的介紹及系統測試4.1 開發軟件的介紹4.1.1 Proteus

本系統的硬件設計首先是在Proteus軟件環境中仿真實現的。Proteus軟件是來自英國Labcenter electronics公司的EDA工具軟件,Proteus軟件有十多年的歷史,在全球廣泛使用,除了具有和其它EDA工具一樣的原理布圖、PCB自動或人工布線及電路仿真的功能外,其革命性的功能是,它的電路仿真是互動的。針對微處理器的應用,還可以直接在基于原理圖的虛擬原型上編程,并實現軟件源碼級的實時調試。如果有顯示及輸出,配合系統配置的虛擬儀器如示波器、邏輯分析儀等,還能看到運行后輸入輸出的效果。Proteus建立了完備的電子設計開發環境,尤其重要的是Proteus Lite可以完全免費,也可以花微不足道的費用注冊達到更好的效果[2]。

Proteus是目前最好的模擬單片機外圍器件的工具。可以仿真51系列、AVR、PIC等常用的MCU及其外圍電路(如LCD,RAM,ROM,鍵盤,馬達,LED,AD/DA,部分SPI器件,部分IIC器件...)。其實Proteus 與 multisim比較類似,只不過它可以仿真MCU,當然,軟件仿真精度有限,而且不可能所有的器件都找得到相應的仿真模型,用開發板和仿真器當然是最好選擇,可是初學者擁有它們的可能性比較小。當然,硬件實踐還是必不可少的。在沒有硬件的情況下,Proteus能像pspice 仿真模擬/數字電路那樣仿真MCU及外圍電路。另外,即使有硬件,在程序編寫早期用軟件仿真一下也是很有必要的。Proteus軟件主要具有以下幾個方面的特點:

1、設計和仿真軟件Proteus 是一個很有用的工具,它可以幫助學生和專業人士提高他們的模擬和數字電路的設計能力。

2、它允許對電路設計采用圖形環境,在這種環境中,可以使用一個特定符號來代替元器件,并完成不會對真實電路造成任何損害的電路仿真操作。

3、它可以仿真儀表以及可描述在仿真過程中所獲得的信號的圖表。

4、它可以仿真目前流行的單片機,如PICS, ATMEL-AVR, MOTOROLA, 8051 等。

5、在設計綜合性方案中,還可以利用ARES開發印制電路板。

4.1.2 Keil C

Keil C是美國Keil Software公司出品的51系列兼容單片機C語言軟件開發系統,與匯編相比,C語言在功能上、結構性、可讀性、可維護性上有明顯的優勢,因而易學易用。提供了包括C編譯器、宏匯編、鏈接器、庫管理和一個功能強大的仿真調試器等在內的完整開發方案,通過一個集成開發環境(μVision)將這些部分組合在一起。運行Keil軟件需要WIN98、NT、WIN2000、WINXP等操作系統。用過匯編語言后再使用C來開發,體會更加深刻。KeilC51軟件提供豐富的庫函數和功能強大的集成開發調試工具,全Windows界面。另外重要的一點,只要看一下編譯后生成的匯編代碼,就能體會到Keil C51生成的目標代碼效率非常之高,多數語句生成的匯編代碼很緊湊,容易理解。在開發大型軟件時更能體現高級語言的優勢。

4.2 系統仿真

通過以上硬件設計和軟件設計過程,設計工作已基本完成。接下來的工作就是對已設計好的系統進行仿真和調試。通過仿真,可以體現出系統所具備的功能;通過調試,可以檢查出系統出現的錯誤,從而進行進一步的改正。

本系統設計在Proteus中的仿真圖如圖4-1所示:

圖4-1 系統仿真圖

接通電源后,系統默認上次設定時間,顯示模塊燈亮并顯示時間內容。通過按鍵可以設置打鈴時刻及陰陽歷查看。

4.3 系統測試

電路測試

硬件電路的最終測試是本次設計的核心。為了硬件電路能正常運行,要對每一個電路部分進行測試并調整。圖4-2為測試圖。現分部測試說明如下:

(1)顯示部分:如圖4-2液晶顯示屏測試,通電后,LCD1602顯示器亮,說明顯示部分沒問題。

(2)按鍵部分:如圖4-2按鍵測試,按下按鍵K1,LCD1602顯示的是農歷時間;按下K4,可以進入時間設置界面,說明按鍵部分也沒問題。

(3)打鈴部分:調節打鈴時刻,使當前時間和打鈴所設定的時刻相吻合,蜂鳴器響,說明蜂鳴器也能正常工作。

圖4-2 系統硬件測試圖

系統整體測試

(1)系統測試一如圖4-3所示,系統通電,按下啟動開關。此時,顯示器顯示時鐘芯片默認的時間并正常走時。

圖4-3系統測試一

(2)系統測試二分別為圖4-4和4-5,按下K4按鍵,進入設置主界面。再通過按K3L按鍵來切換設置選項,進入到設置打鈴界面。通過按下K1、K2來設定一個打鈴時間,然后再按下K4,返回時間顯示主界面。

圖4-4 設置主界面

圖4-5 設置打鈴界面

(3)系統測試三如圖4-6所示,當系統時間和設定的打鈴時間吻合時,顯示器顯示提示,蜂鳴器響。此時按下任意鍵,蜂鳴器停止響動,系統繼續走時。

圖4-6 系統測試三












第5章  

綜上所述,整個硬件電路由STC89C51單片機、DS1302時鐘、LCD1602液晶顯示器、按鍵電路、打鈴電路等組成。本設計能夠很好地完成對時間的實時顯示和時刻打鈴的任務,設計從STC89C51單片機最基本的硬件系統入手,拓展到其他所需要的硬件。通過時鐘芯片和LCD顯示器與單片機系統的配合,有效地完成了時間的顯示和時刻的打鈴。本設計采用的是以單片機和時鐘芯片控制的自動化系統,使用起來更加簡單、更加方便。總的來說,完成本設計任務,設計的系統具有很不錯的實用價值。


參考文獻

[1] 譚浩強.C語言程序設計. 第五版[M].北京:清華大學出版社,2017

[2] 馬秀麗、周越、王紅. 單片機原理與應用系統設計.第二版[M].北京:清華大學出版社,2017

[3] 朱曉青、凌云、袁川來. 傳感器與檢測技術[M]. 北京:清華大學出版社,2014

[4] 馬建明. 數據采集與處理技術上冊、下冊.第三版[M]. 西安:西安交通大學出版社,2012

[5] 劉少強、張靖. 現代傳感器技術——面向物聯網應用.第二版[M] . 北京:電子工業出版社,2016

[6] 廖建尚. 物聯網&云平臺高級應用開發[M]. 北京:電子工業出版社,2017

[7] 朱清慧,張鳳蕊,翟天嵩等. Proteus教程—電子線路設計、制版與仿真.第三版[M]. 北京:清華大學出版社,2016

[8] 王淵峰,戴旭輝. Altium Designer 10電路設計標準教程[M]. 北京:科學出版社,2012

[9]馬忠梅,籍順心等.單片機的C語言應用程序設計[M].北京航空航天大學出版社, 2001年

[10]新編單片機原理與應用.第二版[M].西安電子科技大學出版社,2007.2

[11]張萌.單片機應用系統開發綜合實例[M]. 北京:清華大學出版社,2007.7

[12]樓然苗.單片機設計指導[M]. 北京:北京航空航天大學出版社,2007.7

[13]李廣弟. 單片機原理及應用[M].北京航空航天大學出版社,2004年




致謝

時光轉瞬即逝!在即將進行文檔之際,首先要感謝我的指導老師——老師。在他的幫助下,我掌握了參閱查詢資料和篩選有用文獻的方法。從設計之初,老師就全程參與,經常利于課余時間給我們講解,這讓我非常感動,老師嚴謹的指導態度和溫和而耐心的性情讓我終身受益。還有感謝我的同行朋友同學們,在整個設計與學習的過程中給予我很多的幫助。在這樣溫暖的環境中,我們形成了良好的學習風氣,互幫互助,攻克了學習道路上的一道道難關,他們在我低谷的時候不僅沒有嘲笑我,而且還幫助我解決了很多問題,突破了很多難點,帶我走出困境。其次,感謝我的同行同學們,是他們在設計中盡量的幫助我,才讓這次設計進行的如此順利,他們的設計理念、見解給了我很大的啟發,在遇到想不通的問題的時候, 他們給我提供多種方案,帶我走出思維的困境,讓我在實際操作更加順利。同時,在交流和學習中,我也更加深刻的認識到團隊精神的重要性。同學們對在硬件的設計和軟件的編寫上給了我很大的幫助,給我講解如何看懂程序、如何分析內容、如何根據要執行的功能進行正確的編程,以及指出軟硬件中出現的問題。希望今后多多交流,畢竟友誼地久天長!最后,再次向給予我幫助的指導老師和同行同學們致以最衷心的感謝!



附錄附錄一:自動打鈴系統原理圖
附錄二:源程序
  1. #include <reg51.h>                       //調用單片機頭文件
  2. #define uchar unsigned char  //無符號字符型 宏定義              變量范圍0~255
  3. #define uint  unsigned int              //無符號整型 宏定義              變量范圍0~65535
  4. #include "eeprom52.h"
  5. #include "nongli.h"
  6. bit flag_200ms ;
  7. bit flag_100ms ;
  8. sbit beep = P3^7;                //蜂鳴器定義
  9. bit flag_beep_en;
  10. uint clock_value;     //用作鬧鐘用的
  11. sbit dq   = P3^1;                //18b20 IO口的定義
  12. uint temperature ;    //溫度變量
  13. uchar flag_nl;        //農歷 陽歷顯示標志位
  14. uchar menu_1,menu_2;
  15. uchar key_time,flag_value;      //用做連加的中間變量
  16. bit key_500ms  ;
  17. uchar n_nian,n_yue,n_ri;                            //農歷顯示的函數
  18. #include "ds1302.h"
  19. #include "lcd1602.h"
  20. /******************把數據保存到單片機內部eeprom中******************/
  21. void write_eeprom()
  22. {
  23.               SectorErase(0x2000);
  24.               byte_write(0x2000, fen1);
  25.               byte_write(0x2001, shi1);
  26.               byte_write(0x2002, open1);
  27.               byte_write(0x2058, a_a);            
  28. }

  29. /******************把數據從單片機內部eeprom中讀出來*****************/
  30. void read_eeprom()
  31. {
  32.               fen1  = byte_read(0x2000);
  33.               shi1  = byte_read(0x2001);
  34.               open1  = byte_read(0x2002);
  35.               a_a      = byte_read(0x2058);
  36. }
  37. /**************開機自檢eeprom初始化*****************/
  38. void init_eeprom()
  39. {
  40.               read_eeprom();                            //先讀
  41.               if(a_a != 1)                            //新的單片機初始單片機內問eeprom
  42.               {
  43.                             fen1  = 3;
  44.                             shi1  = 8;
  45.                             open1  = 1;
  46.                             a_a = 1;
  47.                             write_eeprom();                 //保存數據
  48.               }            
  49. }
  50. /***********************18b20初始化函數*****************************/
  51. void init_18b20()
  52. {
  53.               bit q;
  54.               dq = 1;                                                        //把總線拿高
  55.               delay_uint(1);                  //15us
  56.               dq = 0;                                                        //給復位脈沖
  57.               delay_uint(80);                            //750us
  58.               dq = 1;                                                        //把總線拿高 等待
  59.               delay_uint(10);                            //110us
  60.               q = dq;                                                        //讀取18b20初始化信號
  61.               delay_uint(20);                            //200us
  62.               dq = 1;                                                        //把總線拿高 釋放總線
  63. }

  64. /*************寫18b20內的數據***************/
  65. void write_18b20(uchar dat)
  66. {
  67.               uchar i;
  68.               for(i=0;i<8;i++)
  69.               {                                                                      //寫數據是低位開始
  70.                             dq = 0;                                          //把總線拿低寫時間隙開始
  71.                             dq = dat & 0x01; //向18b20總線寫數據了
  72.                             delay_uint(5);              // 60us
  73.                             dq = 1;                                          //釋放總線
  74.                             dat >>= 1;
  75.               }            
  76. }

  77. /*************讀取18b20內的數據***************/
  78. uchar read_18b20()
  79. {
  80.               uchar i,value;
  81.               for(i=0;i<8;i++)
  82.               {
  83.                             dq = 0;                                          //把總線拿低讀時間隙開始
  84.                             value >>= 1;              //讀數據是低位開始
  85.                             dq = 1;                                          //釋放總線
  86.                             if(dq == 1)                            //開始讀寫數據
  87.                                           value |= 0x80;
  88.                             delay_uint(5);              //60us              讀一個時間隙最少要保持60us的時間
  89.               }
  90.               return value;                            //返回數據
  91. }
  92. /*************讀取溫度的值 讀出來的是小數***************/
  93. uint read_temp()
  94. {
  95.               uint value;
  96.               uchar low;                                             //在讀取溫度的時候如果中斷的太頻繁了,就應該把中斷給關了,否則會影響到18b20的時序
  97.               init_18b20();                               //初始化18b20
  98.               write_18b20(0xcc);                 //跳過64位ROM
  99.               write_18b20(0x44);                 //啟動一次溫度轉換命令
  100.               delay_uint(50);                               //500us
  101.               init_18b20();                               //初始化18b20
  102.               write_18b20(0xcc);                 //跳過64位ROM
  103.               write_18b20(0xbe);                 //發出讀取暫存器命令
  104.               EA = 0;
  105.               low = read_18b20();                 //讀溫度低字節
  106.               value = read_18b20();  //讀溫度高字節
  107.               EA = 1;
  108.               value <<= 8;                               //把溫度的高位左移8位
  109.               value |= low;                               //把讀出的溫度低位放到value的低八位中
  110.               value *= 0.625;                     //轉換到溫度值 小數
  111.               return value;                               //返回讀出的溫度 帶小數
  112. }



  113. /******************1ms 延時函數*******************/
  114. void delay_1ms(uint q)
  115. {
  116.               uint i,j;
  117.               for(i=0;i<q;i++)
  118.                             for(j=0;j<120;j++);
  119. }

  120. /******************寫星期函數*******************/
  121. void write_week(uchar hang,uchar add,uchar week)//寫星期函數
  122. {
  123.               if(hang==1)  
  124.                             write_com(0x80+add);
  125.               else
  126.                             write_com(0x80+0x40+add);               
  127.               switch(week)
  128.               {
  129.                             case 1:write_data('M');//星期數為1時,顯示
  130.                                              write_data('O');
  131.                                              write_data('N');
  132.                                              break;
  133.                
  134.                             case 2:write_data('T');//星期數據為2時顯示
  135.                                              write_data('U');
  136.                                              write_data('E');
  137.                                              break;
  138.                            
  139.                             case 3:write_data('W');//星期數據為3時顯示
  140.                                              write_data('E');
  141.                                              write_data('D');
  142.                                              break;
  143.                             case 4:write_data('T');//星期數據為4是顯示
  144.                                              write_data('H');
  145.                                              write_data('U');
  146.                                              break;
  147.                             case 5:write_data('F');//星期數據為5時顯示
  148.                                              write_data('R');
  149.                                              write_data('I');
  150.                                              break;
  151.                             case 6:write_data('S');//星期數據為6時顯示
  152.                                              write_data('T');
  153.                                              write_data('A');
  154.                                              break;
  155.                             case 0:write_data('S');//星期數據為7時顯示
  156.                                              write_data('U');
  157.                                              write_data('N');
  158.                                              break;
  159.               }
  160. }
  161. /*************時鐘顯示***************/
  162. void init_1602_ds1302()
  163. {
  164.               write_sfm2_ds1302(1,1,shi);                               //顯示時
  165.               write_sfm2_ds1302(1,4,fen);                               //顯示分
  166.               write_sfm2_ds1302(1,7,miao);                 //顯示秒
  167.               write_week(2,12,week);
  168. //              write_sfm1(1,14,week);                                             //顯示星期
  169.               write_sfm3_18B20(1,11,temperature);                 //顯示溫度
  170.               if(flag_nl == 0)  //顯示陽歷
  171.               {
  172.                             write_sfm2_ds1302(2,2,nian);   //顯示年
  173.                             write_sfm2_ds1302(2,5,yue);                 //顯示月            
  174.                             write_sfm2_ds1302(2,8,ri);                 //顯示日              
  175.               }
  176.               else                                           //顯示農歷
  177.               {
  178.                             write_sfm2_ds1302(2,2,n_nian);              //顯示年
  179.                             write_sfm2_ds1302(2,5,n_yue);              //顯示月            
  180.                             write_sfm2_ds1302(2,8,n_ri);              //顯示日
  181.                            
  182.               }
  183. }                                                                                                                                
  184. /*************定時器0初始化程序***************/
  185. void init_time0()               
  186. {
  187.               EA   = 1;                              //開總中斷
  188.               TMOD = 0X01;                //定時器0、工作方式1
  189.               ET0  = 1;                              //開定時器0中斷
  190.               TR0  = 1;                              //允許定時器0定時
  191. }

  192. /*************鬧鐘報警函數***************/
  193. void menu_dis()
  194. {
  195.               static uchar mm,value;
  196.               if(flag_100ms == 1)                              //100ms執行一次
  197.               {
  198.                             flag_100ms = 0;
  199.                             if(open1 == 1)              //如果鬧鐘打開
  200.                             {
  201.                                           if((miao == 0) && (fen == fen1) && (shi == shi1))
  202.                                           {                           
  203.                                                         flag_beep_en = 1;              //有報警 打開蜂鳴器響的標志位                                         
  204.                                           }                           
  205.                                           if(flag_beep_en == 1)              //鬧鐘以被打開
  206.                                           {
  207.                                                         clock_value++;
  208.                                                         if(clock_value <= 30)            
  209.                                                                       beep = ~beep;                 //蜂鳴器叫3秒
  210.                                                         else if(clock_value > 30)
  211.                                                         {
  212.                                                                       beep = 1;                                //蜂鳴器停1秒
  213.                                                                       if(clock_value > 40)
  214.                                                                       {
  215.                                                                                     clock_value = 0;
  216.                                                                       }
  217.                                                         }
  218.                                                         //  1 分鐘后自動關閉鬧鐘
  219.                                                         value ++;
  220.                                                         if(value >= 10)
  221.                                                         {
  222.                                                                       value = 0;
  223.                                                                       mm++;
  224.                                                                       if(mm >= 60)
  225.                                                                       {
  226.                                                                                     mm = 0;
  227.                                                                                     flag_beep_en = 0;
  228.                                                                                     beep = 1;            
  229.                                                                       }
  230.                                                         }                                                                     
  231.                                           }
  232.                             }            
  233.               }
  234. }
  235. /********************獨立按鍵程序*****************/
  236. uchar key_can;              //按鍵值
  237. void key()              //獨立按鍵程序
  238. {
  239.               static uchar key_new;
  240.               key_can = 20;                   //按鍵值還原
  241.               P3 |= 0x78;                     //對應的按鍵IO口輸出為1
  242.               if((P3 & 0x78) != 0x78)                            //按鍵按下
  243.               {
  244.                             delay_1ms(1);                                 //按鍵消抖動
  245.                             if(((P3 & 0x78) != 0x78) && (key_new == 1))
  246.                             {                                                                                    //確認是按鍵按下
  247.                                           key_new = 0;
  248.                                           switch(P3 & 0x78)
  249.                                           {
  250.                                                         case 0x70:  key_can = 4;  break;              //得到按鍵值
  251.                                                         case 0x68:  key_can = 3;  break;              //得到按鍵值
  252.                                                         case 0x58:  key_can = 2;  break;              //得到按鍵值
  253.                                                         case 0x38:  key_can = 1;  break;              //得到按鍵值
  254.                                           }
  255. //                                          write_sfm2(1,0,key_can);                                                        //顯示按鍵值
  256.                             }                                         
  257.               }
  258.               else
  259.                             key_new = 1;            
  260. }
  261. /**********************設置函數************************/
  262. void key_with()
  263. {
  264.               if(key_can == 1)              //設置鍵
  265.               {
  266.                             menu_1++;
  267.                             if(menu_1 == 1)                //設置時間
  268.                             {
  269.                                           menu_2 = 1;
  270.                                           write_string(1,0,"    :  :    W:  ");                                         
  271.                                           write_string(2,0," 20  -  -       ");            
  272.                             }
  273.                             if(menu_1 == 2)                //設置鬧鐘
  274.                             {
  275.                                           menu_2 = 1;
  276.                                           write_string(1,0,"   set clock    ");                                         
  277.                                           write_string(2,0,"    Y  00:00      ");            
  278.                             }
  279.                             if(menu_1 > 2)    //回到正常顯示
  280.                             {
  281.                                           menu_1 = 0;
  282.                                           write_guanbiao(1,2,0);              //關閉光標
  283.                                           init_1602_dis_csf();      //初始化液晶顯示                           
  284.                             }
  285.               }
  286.               if(key_can == 2)              //選擇鍵
  287.               {
  288.                             flag_200ms = 1;
  289.                             if(menu_1 == 1)                              //設置時間
  290.                             {
  291.                                           menu_2 ++;
  292.                                           if(menu_2 > 7)
  293.                                                         menu_2 = 1;
  294.                             }
  295.                             if(menu_1 == 2)                            //設置鬧鐘
  296.                             {
  297.                                           menu_2 ++;
  298.                                           if(menu_2 > 3)
  299.                                                         menu_2 = 1;                                                      
  300.                             }
  301.               }
  302.               if(menu_1 == 1)
  303.               {
  304.                             if(menu_2 == 1)                              //設置時
  305.                             {
  306.                                           if(key_can == 3)              //加
  307.                                           {
  308.                                                         shi+=0x01;
  309.                                                         if((shi & 0x0f) >= 0x0a)
  310.                                                                       shi = (shi & 0xf0) + 0x10;
  311.                                                         if(shi >= 0x24)
  312.                                                                       shi = 0;
  313.                                           }                           
  314.                                           if(key_can == 4)              //減
  315.                                           {
  316.                                                         if(shi == 0x00)
  317.                                                                       shi = 0x24;
  318.                                                         if((shi & 0x0f) == 0x00)
  319.                                                                       shi = (shi | 0x0a) - 0x10;
  320.                                                         shi -- ;
  321.                                           }                                                                       
  322.                             }
  323.                             if(menu_2 == 2)                              //設置分
  324.                             {
  325.                                           if(key_can == 3)              //加
  326.                                           {
  327.                                                         fen+=0x01;
  328.                                                         if((fen & 0x0f) >= 0x0a)
  329.                                                                       fen = (fen & 0xf0) + 0x10;
  330.                                                         if(fen >= 0x60)
  331.                                                                       fen = 0;
  332.                                           }                           
  333.                                           if(key_can == 4)              //減               
  334.                                           {
  335.                                                         if(fen == 0x00)
  336.                                                                       fen = 0x5a;
  337.                                                         if((fen & 0x0f) == 0x00)
  338.                                                                       fen = (fen | 0x0a) - 0x10;
  339.                                                         fen -- ;
  340.                                           }            
  341.                             }
  342.                             if(menu_2 == 3)                              //設置秒
  343.                             {
  344.                                           if(key_can == 3)              //加
  345.                                           {
  346.                                                         miao+=0x01;
  347.                                                         if((miao & 0x0f) >= 0x0a)
  348.                                                                       miao = (miao & 0xf0) + 0x10;
  349.                                                         if(miao >= 0x60)
  350.                                                                       miao = 0;
  351.                                           }            
  352.                                           if(key_can == 4)              //減               
  353.                                           {
  354.                                                         if(miao == 0x00)
  355.                                                                       miao = 0x5a;
  356.                                                         if((miao & 0x0f) == 0x00)
  357.                                                                       miao = (miao | 0x0a) - 0x10;
  358.                                                         miao -- ;                                         
  359.                                           }
  360.                             }
  361.                             if(menu_2 == 4)                              //設置星期
  362.                             {
  363.                                           if(key_can == 3)              //加
  364.                                           {
  365.                                               week+=0x01;
  366.                                                         if((week & 0x0f) >= 0x0a)
  367.                                                                       week = (week & 0xf0) + 0x10;
  368.                                                         if(week >= 0x08)
  369.                                                                       week = 1;
  370.                                           }                           
  371.                                           if(key_can == 4)              //減               
  372.                                           {
  373.                                                         if(week == 0x01)
  374.                                                                       week = 0x08;
  375.                                                         if((week & 0x0f) == 0x00)
  376.                                                                       week = (week | 0x0a) - 0x10;
  377.                                                         week -- ;
  378.                                           }            
  379.                             }
  380.                             if(menu_2 == 5)                              //設置年
  381.                             {
  382.                                           if(key_can == 3)              //加
  383.                                           {
  384.                                               nian+=0x01;
  385.                                                         if((nian & 0x0f) >= 0x0a)
  386.                                                                       nian = (nian & 0xf0) + 0x10;
  387.                                                         if(nian >= 0x9a)
  388.                                                                       nian = 1;
  389.                                           }                           
  390.                                           if(key_can == 4)              //減               
  391.                                           {
  392.                                                         if(nian == 0x01)
  393.                                                                       nian = 0x9a;
  394.                                                         if((nian & 0x0f) == 0x00)
  395.                                                                       nian = (nian | 0x0a) - 0x10;
  396.                                                         nian -- ;                           
  397.                                           }            
  398.                             }
  399.                             if(menu_2 == 6)                              //設置月
  400.                             {
  401.                                           if(key_can == 3)              //加
  402.                                           {
  403.                                               yue+=0x01;
  404.                                                         if((yue & 0x0f) >= 0x0a)
  405.                                                                       yue = (yue & 0xf0) + 0x10;
  406.                                                         if(yue >= 0x13)
  407.                                                                       yue = 1;
  408.                                           }                           
  409.                                           if(key_can == 4)              //減               
  410.                                           {
  411.                                                         if(yue == 0x01)
  412.                                                                       yue = 0x13;
  413.                                                         if((yue & 0x0f) == 0x00)
  414.                                                                       yue = (yue | 0x0a) - 0x10;
  415.                                                         yue -- ;                                                                     
  416.                                           }            
  417.                             }
  418.                             if(menu_2 == 7)                              //設置日
  419.                             {
  420.                                           if(key_can == 3)              //加
  421.                                           {
  422.                                 ri+=0x01;
  423.                                           if((ri & 0x0f) >= 0x0a)
  424.                                                         ri = (ri & 0xf0) + 0x10;
  425.                                           if(ri >= 0x32)
  426.                                                         ri = 0;                                         
  427.                                           }                           
  428.                                           if(key_can == 4)              //減               
  429.                                           {
  430.                                                         if(ri == 0x01)
  431.                                                                       ri = 0x32;
  432.                                                         if((ri & 0x0f) == 0x00)
  433.                                                                       ri = (ri | 0x0a) - 0x10;
  434.                                                         ri -- ;                                         
  435.                                           }            
  436.                             }
  437.                             write_sfm2_ds1302(1,2,shi);                 //顯示時
  438.                             write_sfm2_ds1302(1,5,fen);                 //顯示分
  439.                             write_sfm2_ds1302(1,8,miao);                 //顯示秒
  440.                             write_sfm1(1,14,week);                 //顯示星期                                                                     
  441.                             write_sfm2_ds1302(2,3,nian);                 //顯示年
  442.                             write_sfm2_ds1302(2,6,yue);                 //顯示月
  443.                             write_sfm2_ds1302(2,9,ri);                 //顯示日
  444.                             switch(menu_2)                 // 光標顯示
  445.                             {
  446.                                           case 1:  write_guanbiao(1,2,1);  break;
  447.                                           case 2:  write_guanbiao(1,5,1);  break;
  448.                                           case 3:  write_guanbiao(1,8,1);  break;
  449.                                           case 4:  write_guanbiao(1,14,1);  break;
  450.                                           case 5:  write_guanbiao(2,3,1);  break;
  451.                                           case 6:  write_guanbiao(2,6,1);  break;
  452.                                           case 7:  write_guanbiao(2,9,1);  break;
  453.                             }
  454.                             write_time();                 //把時間寫進去
  455.               }            
  456. /***************設置鬧鐘*********************/
  457.               if(menu_1 == 2)
  458.               {
  459.                             if(menu_2 == 1)                              //設置鬧鐘開關
  460.                             {
  461.                                           if(key_can == 3)            
  462.                                           {
  463.                                                         open1 = 1;                //鬧鐘開
  464.                                           }                           
  465.                                           if(key_can == 4)            
  466.                                           {
  467.                                                         open1 = 0;                //鬧鐘關
  468.                                           }                                                                       
  469.                             }
  470.                             if(menu_2 == 2)                              //設置鬧鐘時
  471.                             {
  472.                                           if(key_can == 3)              //加
  473.                                           {
  474.                                               shi1+=0x01;
  475.                                                         if((shi1 & 0x0f) >= 0x0a)
  476.                                                                       shi1 = (shi1 & 0xf0) + 0x10;
  477.                                                         if(shi1 >= 0x24)
  478.                                                                       shi1 = 0;
  479.                                           }                           
  480.                                           if(key_can == 4)              //減               
  481.                                           {
  482.                                                         if(shi1 == 0x00)
  483.                                                                       shi1 = 0x5a;
  484.                                                         if((shi1 & 0x0f) == 0x00)
  485.                                                                       shi1 = (shi1 | 0x0a) - 0x10;
  486.                                                         shi1 -- ;
  487.                                           }            
  488.                             }
  489.                             if(menu_2 == 3)                              //設置秒
  490.                             {
  491.                                           if(key_can == 3)              //加
  492.                                           {
  493.                                               fen1+=0x01;
  494.                                                         if((fen1 & 0x0f) >= 0x0a)
  495.                                                                       fen1 = (fen1 & 0xf0) + 0x10;
  496.                                                         if(fen1 >= 0x60)
  497.                                                                       fen1 = 0;
  498.                                           }            
  499.                                           if(key_can == 4)              //減               
  500.                                           {
  501.                                                         if(fen1 == 0x00)
  502.                                                                       fen1 = 0x5a;
  503.                                                         if((fen1 & 0x0f) == 0x00)
  504.                                                                       fen1 = (fen1 | 0x0a) - 0x10;
  505.                                                         fen1 -- ;                                         
  506.                                           }
  507.                             }
  508.                             if(open1 == 1)
  509.                                           write_string(2,4,"Y");            
  510.                             else
  511.                                           write_string(2,4,"N");            
  512.                             write_sfm2_ds1302(2,7,shi1);                 //顯示鬧鐘時
  513.                             write_sfm2_ds1302(2,10,fen1);                 //顯示鬧鐘分
  514.                             switch(menu_2)                 // 光標顯示
  515.                             {
  516.                                           case 1:  write_guanbiao(2,4,1);  break;
  517.                                           case 2:  write_guanbiao(2,7,1);  break;
  518.                                           case 3:  write_guanbiao(2,10,1);  break;
  519.                             }            
  520.                             write_eeprom();     //保存鬧鐘時間
  521.               }                                         
  522. }
  523. /*****************主函數********************/
  524. void main()
  525. {            
  526.               beep = 0;                                            //開機叫一聲  
  527.               delay_1ms(150);
  528.               P0 = P1 = P2 = P3 = 0xff;                            //單片機IO口初始化為1
  529.               init_time0();                            //初始化定時器
  530. ……………………

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


1602萬年歷程序與仿真下載::

資料.7z (4.84 MB, 下載次數: 265)

word文檔.docx (2.29 MB, 下載次數: 182)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:652643 發表于 2019-11-29 20:56 | 只看該作者
樓主你好,請問主函數里是怎么調用的呀,黑幣不夠下載不了附件
回復

使用道具 舉報

板凳
ID:712687 發表于 2020-4-3 17:26 | 只看該作者
非常感謝
回復

使用道具 舉報

地板
ID:735425 發表于 2020-4-22 17:59 | 只看該作者
很感謝,但是主函數這樣就是寫完了嗎?
回復

使用道具 舉報

5#
ID:737567 發表于 2020-4-25 16:50 | 只看該作者
請問一下,可以設置成多個不同時段自動打鈴嗎
回復

使用道具 舉報

6#
ID:767375 發表于 2020-6-3 15:49 | 只看該作者
顯示程序有問題打不開啊
回復

使用道具 舉報

7#
ID:743050 發表于 2020-6-13 16:54 | 只看該作者
謝謝,優秀
回復

使用道具 舉報

8#
ID:979060 發表于 2021-11-8 18:51 | 只看該作者
你好,你是星期計算是有問題的吧?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区精品在线 | 中文字幕av一区 | 欧美一区二区三区在线观看 | 亚洲 欧美 精品 | 91亚洲一区 | 久久99精品久久久久久狂牛 | 一区二区国产精品 | 久久久精品 | 中文字幕在线免费观看 | 国产ts人妖另类 | 天天拍天天操 | 三级欧美 | 国产精品色哟哟网站 | 久久在线| 黄色在线网站 | 国产不卡一区 | 九九热在线免费视频 | 成人h动漫精品一区二区器材 | 国产精品五月天 | 色综合久久久 | 美女久久久久久久久 | 中文在线а√在线8 | 日韩欧美精品 | 国产视频不卡一区 | 久久久久久久电影 | 最新国产视频 | 中文字幕在线一 | 一区二区久久电影 | 久久99精品久久久久久噜噜 | av网站免费观看 | 国产高清久久久 | 国产视频91在线 | 成人免费一区二区三区视频网站 | h视频免费观看 | 激情久久网| 国产精品99视频 | 亚洲国产成人精品久久 | 久久久久久999 | 国产成人av免费看 | 日日碰碰 | 黄色一级大片在线免费看产 |