基于單片機(jī)的電子密碼鎖設(shè)計 摘要:鎖,是指加在門、箱子、抽屜等物體上的封緘器,要用專用的鑰匙才能打開。自古以來鎖都是人們財產(chǎn)安全乃至生命安全的一種重要保障。伴隨著人類歷史的發(fā)展和人們對自身財產(chǎn)安全和人生安全的重視,各種各樣的多功能的鎖具也相繼出現(xiàn),人們使用的鎖具也由傳統(tǒng)的機(jī)械式鎖逐漸發(fā)展為安全性能更好,功能更多的電子密碼鎖。 在現(xiàn)代社會,電子密碼鎖已是一個被大家所熟識的名詞。相信很多人的小區(qū)大門上的鎖都用的是電子密碼鎖。本文中將要介紹的電子密碼鎖是一種通過判斷密碼輸入是否正確來控制電路或是芯片的工作狀態(tài),進(jìn)而控制鎖的打開和閉合,從而完成開鎖、閉鎖任務(wù)的電子鎖裝置。 本設(shè)計是基于AT89C51單片機(jī)為控制核心的密碼鎖設(shè)計方案。在本次基于單片機(jī)的電子密碼鎖設(shè)計中,將采用AT89C51單片機(jī)作為控制核心,配合相應(yīng)的電路和軟件程序,實現(xiàn)密碼的輸入和修改、信息的顯示、鍵盤的鎖定、系統(tǒng)報警、開鎖和閉鎖等功能。在設(shè)計中,利用識別密碼是否正確來開鎖或報警,通過串行存儲器AT24C02來實現(xiàn)密碼的修改和存儲。 本文設(shè)計的密碼鎖具有安全性高、功耗低、操作簡單等優(yōu)點。
The Design Of Electronic Code Lock Based On Single Chip Microcomputer Abstract:As sealed device, the lock added to such objects like door, box, drawer etc, can be opened with specified key. Since the ancient time, lock is a kind of security, guaranteeing people’s property safety even life safety. With the development of human history and more attention paid to property safety and life safety, various multi-functional locks can be seen in the world. Traditional mechanical locks people use in life are gradually replaced by electronic combination lock characterized with better safety performance and more functions. In the modern society, electronic combination lock is a noun familiar to everyone. Usually, the door of community is equipped with electronic combination lock. This paper will introduce an electronic combination lock. This lock controls the electric circuits and the performance of chips by identifying password. Thus, the openness and closeness of the lock can be controlled, and the task of electronic lock device can be completed. This design is about combination lock, based on the AT89C51 single-chip microcomputer as the core of controlling goals. This design in which the AT89C51 single-chip microcomputer as the core of the controlling goals cooperated with relevant circuits and software programs can achieve such functions like password input and modification, information display, keyboard locking, warning system, and the openness and closeness of the lock etc. In this design, the openness of lock and alarming are according to identifying the password, and password revision and storage is achieved by the function of the AT24C02 serial storage. Electronic combination lock described in this paper is characterized with high security, low power consumption, and simplicity of operation etc.
目錄 第1章 緒論 1.1 電子密碼鎖簡介 1.2 電子密碼鎖設(shè)計的背景及意義 1.3 電子密碼鎖的現(xiàn)狀及發(fā)展趨勢 第2章 總體設(shè)計 2.1 設(shè)計分析 2.2 系統(tǒng)結(jié)構(gòu) 第3章 硬件電路設(shè)計 3.1 單片機(jī)接口分配 3.2 單片機(jī)最小系統(tǒng)設(shè)計 3.2.1 時鐘電路 3.2.2 復(fù)位電路 3.2.3 最小系統(tǒng) 3.3 矩陣鍵盤設(shè)計 3.4 LCD顯示模塊設(shè)計 3.5 掉電存儲模塊 3.5.1 I2C總線 3.5.2 AT24C02簡介 3.6 開鎖機(jī)構(gòu) 3.7 報警機(jī)構(gòu) 3.8 硬件綜合設(shè)計 第4章 軟件設(shè)計 4.1 軟件總體設(shè)計 4.2 鍵盤掃描子程序 4.3顯示模塊子程序 4.4 掉電存儲子程序 4.4.1 寫操作方式 4.4.2 讀操作方式 4.5 定時器中斷子程序 4.6 密碼輸入子程序 4.7 報警子程序 第5章 聯(lián)合仿真和調(diào)試 第6章 實物設(shè)計和制作 總結(jié) 致謝 參考文獻(xiàn) 附錄1 設(shè)計實物圖 附錄2 程序源代碼 第1章 緒論 1.1 電子密碼鎖簡介 什么是電子密碼鎖?“一種通過密碼輸入來控制電路或者是芯片工作,從而控制機(jī)械開關(guān)的閉合,完成開鎖、閉鎖任務(wù)的電子產(chǎn)品。”——百度百科上是這樣解釋的。簡單來說,電子密碼鎖就是能夠?qū)崿F(xiàn)密碼等信息的設(shè)置、存貯、識別和顯示,以及報警信號的接收和發(fā)送等功能的電子器件。 電子密碼鎖相對傳統(tǒng)機(jī)械鎖有以下幾個優(yōu)勢: (1)密碼可更改。用戶可以隨時更改密碼,以確保密碼鎖的安全性和可靠性?梢愿拿艽a這一功能同時也避免了人員的更替而使鎖的安全性降低,這是傳統(tǒng)鑰匙鎖所不具備的功能。 (2)操作簡單。無論是開鎖還是更改密碼,只要識字的人都能夠直接使用,使用方法簡單而不繁瑣。 (3)能夠報警。報警功能無疑更增加了鎖的安全性。 (4)無法“技術(shù)”破解。不知道密碼就無法打開鎖,即使是慣偷也只能望“鎖”興嘆。 1.2 電子密碼鎖設(shè)計的背景及意義在現(xiàn)代文明社會,雖然人們的道德素質(zhì)越來越高,“梁上君子”、“三只手”等人群相對舊社會大大減少,但是像“某某小區(qū)遭入室行竊,居民損失XXXX”之類的新聞我們還是經(jīng)常能夠在報紙上看到的。隨著人們生活水平和自身防范意識的提高,個人財產(chǎn)安全和人身安全的問題也越來越受到人們的重視,擁有一把能夠有效保證居民財產(chǎn)安全和人身安全的鎖具也越發(fā)的重要起來。 鎖具的起源可以追朔到人類社會財產(chǎn)私有化的出現(xiàn),鎖具從其出現(xiàn)到發(fā)展至今天的高科技化、信息化,已經(jīng)有若干年的歷史了。經(jīng)過若干年的使用和研究,人們對鎖具的結(jié)構(gòu)、機(jī)理也了解得相當(dāng)透徹了,因此,不使用鑰匙就能將鎖打開的方法也層出不窮。特別是傳統(tǒng)的機(jī)械鎖,由于其構(gòu)造簡單,在慣偷面前,甚至能夠只用一根鐵絲就直接將其打開,使其失去了保障用戶個人財產(chǎn)安全的意義。 那么,如何才能提高鎖具保障用戶財產(chǎn)安全的有效性呢?在信息現(xiàn)代化的今天,鎖具也應(yīng)該向高精度、高安全性的智能化、信息化發(fā)展。自20世紀(jì)70年代第一塊單片機(jī)芯片TMS-1000于美國德克薩斯儀器公司面世以來,基于其體積小、價格低廉、個性突出等特點,越來越多的電子產(chǎn)品開始采用單片機(jī)芯片作為核心控制部件。在這樣的大環(huán)境下,基于單片機(jī)的電子密碼鎖也應(yīng)運(yùn)而生。這種電子密碼鎖是以單片機(jī)為核心,配以相應(yīng)的硬件電路和軟件程序,實現(xiàn)密碼的設(shè)置、存貯、識別和顯示,以及報警信號的接收和發(fā)送等功能,具有操作快、修改密碼簡單、安全性高、功耗低等優(yōu)點;趩纹瑱C(jī)的電子密碼鎖的面世使人們的自身財產(chǎn)安全有了更多的保障,同時也促進(jìn)了安全信息系統(tǒng)的發(fā)展,是安全信息系統(tǒng)的一大進(jìn)步。 基于單片機(jī)的電子密碼鎖的出現(xiàn),在一定程度上解決了用戶私人財產(chǎn)安全的問題。但是,時代在發(fā)展,社會在進(jìn)步,任何事物只有不斷地進(jìn)步才能適應(yīng)時代發(fā)展的需求。電子密碼鎖雖然有安全性高、操作簡單等優(yōu)點,但是卻不如機(jī)械鎖價格低廉,因此,在市場上的主流產(chǎn)品還是機(jī)械鎖。電子密碼鎖要想取代機(jī)械鎖成為市場上的主流,就必須不斷改進(jìn),在具有更多功能的同時向更智能化和更低成本化發(fā)展。這就需要我們不斷研究電子密碼鎖的設(shè)計方法和實現(xiàn)原理。因此,研究基于單片機(jī)的電子密碼鎖的設(shè)計是很有必要且具有現(xiàn)實意義的。 1.3 電子密碼鎖的現(xiàn)狀及發(fā)展趨勢目前,和西方發(fā)達(dá)國家相比,我國的電子密碼鎖技術(shù)還相對落后。在西方發(fā)達(dá)國家,電子密碼鎖的種類已經(jīng)很齊全,技術(shù)也比較先進(jìn),且在各個領(lǐng)域得到了廣泛應(yīng)用。在我國,電子密碼鎖技術(shù)卻才相當(dāng)于國際上七十年代的水平,相對來說還很落后。20世紀(jì)80年代以來,隨著各種電子集成電路的出現(xiàn),特別是單片機(jī)的面世,電子密碼鎖得到了很大的發(fā)展。相對于笨重而構(gòu)造簡單的傳統(tǒng)機(jī)械鎖來說,電子密碼鎖具有體積小,可靠性高的優(yōu)勢。但是就目前而言,電子密碼鎖的價格相對較高且需要有電源提供能量,使得其使用還局限在一定范圍,特別是在國內(nèi),各種條件的制約使得電子密碼鎖暫時難以普及。 盡管電子密碼鎖還存在著一些缺陷,但是其安全性高、方便易用、能夠智能報警的優(yōu)勢卻是傳統(tǒng)鑰匙鎖取代不了的,而且隨著電子信息技術(shù)的發(fā)展和各種電子器件的價格的不斷降低,電子密碼鎖也將往低成本、多功能的方向發(fā)展。
第2章 總體設(shè)計2.1 設(shè)計分析一個電子密碼鎖,應(yīng)該能實現(xiàn)以下功能: (1)能夠從鍵盤中輸入密碼,并相應(yīng)地在顯示器上顯示‘*’; (2)能夠判斷密碼是否正確,正確則開鎖,錯誤則輸出相應(yīng)信息; (3)能夠?qū)崿F(xiàn)密碼的修改; (4)斷電或者單片機(jī)復(fù)位后能夠保存之前的操作,比如密碼的修改; (5)在操作錯誤達(dá)到一定次數(shù)后能夠報警; (6)在一定時間內(nèi)沒有任何按鍵操作則關(guān)閉顯示器,并鎖定鍵盤,禁止鍵盤輸入(單片機(jī)復(fù)位后鎖定取消); (7)設(shè)置一個備用密碼。為了防止用戶忘記密碼而開不了鎖,應(yīng)該在經(jīng)常使用的密碼外再設(shè)置一個備用密碼以防萬一。此備用密碼應(yīng)該只有少數(shù)人知道,比如小區(qū)管理員。 根據(jù)以上分析,本次電子密碼鎖設(shè)計的主要重點是以下幾個部分:4x4矩陣鍵盤設(shè)計、LCD信息顯示、密碼的掉電存儲和密碼的比較和處理。當(dāng)然,除了這幾個部分外還有定時器/計數(shù)器計時中斷和報警等功能模塊。 本設(shè)計應(yīng)該按以下步驟去實現(xiàn): 第一步:選擇材料和器件。 第二步:根據(jù)單片機(jī)原理和模擬電子技術(shù)基礎(chǔ)等理論知識在PROTEUS 中畫出仿真圖。 第三步:檢查仿真圖,確保其能夠?qū)崿F(xiàn)所有功能。 第四步:根據(jù)需要實現(xiàn)的功能邏輯畫出程序流程圖。 第五步:根據(jù)程序流程圖和PROTEUS仿真圖,使用 KEIL軟件進(jìn)行程序的編寫和調(diào)試。 第六步:將KEIL和PROTEUS聯(lián)合仿真、調(diào)試,查看是否實現(xiàn)所有功能。 第七步:根據(jù)PROTEUS仿真圖焊接器件。 第八步:實物調(diào)試。 基于實際情況,在設(shè)計中,用發(fā)光二極管代替電磁鎖,二極管亮則代表鎖開,二極管不亮則代表鎖關(guān)。 2.2 系統(tǒng)結(jié)構(gòu)本設(shè)計系統(tǒng)主要由單片機(jī)芯片、矩陣鍵盤、LCD顯示模塊、掉電存儲模塊、報警機(jī)構(gòu)和開鎖機(jī)構(gòu)組成。如圖2-1所示。 
圖2-1 系統(tǒng)總體設(shè)計結(jié)構(gòu)圖 時鐘電路給單片機(jī)提供晶振頻率,復(fù)位電路不但使單片機(jī)上電復(fù)位,還能在使用過程中通過需要通過按鍵再次手動復(fù)位,矩陣鍵盤提供按鍵的輸入,LCD模塊顯示信息,掉電存儲負(fù)責(zé)密碼的存儲,開鎖機(jī)構(gòu)和報警機(jī)構(gòu)分別負(fù)責(zé)開鎖和報警功能。 設(shè)計中,單片機(jī)選用AT89C51,LCD顯示模塊選用LCD1602液晶顯示器,串行存儲器選用電可擦除存儲器AT24C02,開鎖機(jī)構(gòu)用發(fā)光二極管代替,報警機(jī)構(gòu)選用蜂鳴器。
第3章 硬件電路設(shè)計 3.1 單片機(jī)接口分配AT89C51單片機(jī)在一塊芯片上集成了CPU、RAM、ROM、定時器/計數(shù)器和多種I/O功能部件,具有一臺微型計算機(jī)的基本結(jié)構(gòu),按功能可以將其分成八個組成部分:微處理器(CPU)、數(shù)據(jù)存儲器(RAM)、程序存儲器(ROM/EPROM)、特殊功能寄存器(SFR)、I/O口、串行口、定時器/計數(shù)器及中斷系統(tǒng)。 在本設(shè)計中,單片機(jī)的各個接口我是這樣分配的:P0口接一個上拉電阻后與LCD1602的8位雙向數(shù)據(jù)端D0~D7相接,P1口用作矩陣鍵盤接口,P2口的P2.0~P2.2和LCD1602的4~6引腳相接,P2.5和P2.6接串行存儲器AT24C02,P3口用作開鎖電路和報警電路的接口。 3.2 單片機(jī)最小系統(tǒng)設(shè)計單片機(jī)最小系統(tǒng)就是指能使單片機(jī)工作的最少的器件構(gòu)成的系統(tǒng)。因為單片機(jī)已經(jīng)包含了數(shù)據(jù)存儲器和程序存儲器,所以只要在其外部加上時鐘電路和復(fù)位電路就可以構(gòu)成單片機(jī)最小系統(tǒng)。 3.2.1 時鐘電路 單片機(jī)工作需要晶振給CPU提供頻率,時鐘電路就是給單片機(jī)提供晶振頻率的電路。圖3-1是時鐘電路的PROTEUS仿真圖。 
圖3-1 時鐘電路 單片機(jī)允許的振蕩晶體可在1.2~24MHz之間選擇,一般為11.0592MHz,電容C2,C3的取值對振蕩頻率輸出的穩(wěn)定性、大小及振蕩電路起振速度有一定的影響,可在20~100pF之間選擇,典型值位30pF。 3.2.2 復(fù)位電路計算機(jī)每次開始工作,CPU和系統(tǒng)中的其他部件都必須要有一個確定的初值,即復(fù)位狀態(tài)。圖3-2是單片機(jī)復(fù)位電路仿真圖。 
圖3-2 復(fù)位電路 單片機(jī)RST引腳是高電平有效。單片機(jī)在上電瞬間C1充電,RST引腳端出現(xiàn)正脈沖,只要RST斷保持兩個機(jī)械周期(大約10ms)以上的高電平,單片機(jī)就能復(fù)位。在單片機(jī)工作后,如果還想再次復(fù)位,只需按下開關(guān),單片機(jī)就能重新變成復(fù)位狀態(tài)。 當(dāng)晶體振蕩頻率為12MHz時,RC的典型值為C=10μF,R=8.2KΩ。 3.2.3 最小系統(tǒng) 單片機(jī)加上時鐘電路和復(fù)位電路就構(gòu)成了能使其正常工作的最小系統(tǒng)。 單片機(jī)最小系統(tǒng)是單片機(jī)正常工作的基礎(chǔ),任何一個單片機(jī)系統(tǒng)設(shè)計都是基于單片機(jī)最小系統(tǒng)的基礎(chǔ)上來完成的,而在單片機(jī)系統(tǒng)實物設(shè)計中,最應(yīng)該首先解決的也應(yīng)該是單片機(jī)最小系統(tǒng)問題,只有保證了單片機(jī)最小系統(tǒng)的正確性,才能保證接下來的其他模塊的正確設(shè)計。 圖3-3是單片機(jī)最小系統(tǒng)的完整仿真圖。

圖3-3 單片機(jī)最小系統(tǒng) 3.3 矩陣鍵盤設(shè)計一組鍵或者一個鍵盤,需要通過接口電路和CPU相連接,CPU可以采用查詢接口或者中斷的方式了解有沒有鍵被按下,并檢查是哪個鍵被按下。無論是查詢方式還是中斷方式都要用到單片機(jī)的I/O口。由于單片機(jī)I/O口較少的原因,當(dāng)系統(tǒng)中需要用到較多按鍵時,為了能夠更合理更有效地利用單片機(jī)的I/O口,一般采用矩陣鍵盤的方式來實現(xiàn)多按鍵的功能。 圖3-4是4x4矩陣鍵盤在PROTEUS中的電路原理仿真圖。 
圖3-4 4x4矩陣鍵盤 矩陣鍵盤又叫做行列式鍵盤。行列式鍵盤的硬件結(jié)構(gòu)比較簡單,由行輸出口和列輸出口構(gòu)成行列式鍵盤,按鍵設(shè)置在行、列交點上。圖3-4中,P1.0~P1.3是行輸出口,P1.4~P1.7是列輸出口。行輸出口和列輸出口不相交,只有當(dāng)鍵被按下時相應(yīng)的行和列才能相連。如此,只要檢測行和列是否相連就可以知道是否有鍵按下。 由于按鍵設(shè)置在行、列線交點上,行、列分別連接到按鍵開關(guān)的兩端,平時無鍵按下時,行線處于高電平,假設(shè)列線為低電平,當(dāng)有鍵按下時,按下的鍵就會將相應(yīng)的行和列連通,使得對應(yīng)的行線被列線拉低,也變?yōu)榈碗娖。這就是識別矩陣鍵盤是否有鍵被按下的關(guān)鍵。 當(dāng)確定有鍵被按下時,通過逐行掃描,讀出I/O口的值可以知道哪一行的值被改變了,被改變了的行即是被按下的按鍵所在行。同時,由于每個鍵都有它的行值和列值,行值和列值得組合就是這個按鍵的編碼,當(dāng)算法一定時,每個按鍵的編碼是固定的,且各個按鍵的編碼互不相同,所有通過讀I/O的值還能具體知道是哪一個鍵被按下,這樣就實現(xiàn)了鍵盤的識別。 3.4 LCD顯示模塊設(shè)計 在單片機(jī)應(yīng)用系統(tǒng)中,常用的顯示設(shè)備有單個發(fā)光二極管、八段LED顯示器、液晶顯示器(LCD)、屏幕顯示器(CRT)等。在本次設(shè)計中,基于設(shè)計所要實現(xiàn)的功能和節(jié)約成本等實際情況,我采用LCD1602作為本次設(shè)計的顯示器。 LCD1602是一種字符型液晶顯示器,是一種專門用于顯示字母、數(shù)字、符號等的點陣式液晶顯示器。LCD1602的顯示容量為16x2個字符(可以顯示2行,每行顯示16個字符),芯片工作電壓為4.5~5.5V,工作電流為2.0mA(5.0V),模塊最佳工作電壓是5.0V。 LCD1602具有16個引腳,如表3-1所示。在LCD1602的有關(guān)設(shè)計中,主要是通過編寫程序控制LCD1602的4、5、6引腳來實現(xiàn)數(shù)據(jù)或者指令的寫入和執(zhí)行,再通過數(shù)據(jù)或者指令的寫入和執(zhí)行來進(jìn)一步實現(xiàn)LCD1602的顯示功能。 表3-1是LCD1602的16個引腳和引腳對應(yīng)功能。
表3-1 LCD1602引腳說明 | | | | | | | | | | | | | | | | | 0:向LCD寫指令或者數(shù)據(jù);1:從LCD讀取信息 | | | 使能信號,1:讀取信息,1→0:執(zhí)行命令 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
作為一個字符型液晶顯示器,LCD1602內(nèi)部自帶有一個字符發(fā)生存儲器,此字符發(fā)生存儲器就相當(dāng)于一個字符集。LCD1602的字符集中存有160個不同的字符,這些字符包括了英文大小寫字母、阿拉伯?dāng)?shù)字、標(biāo)點符號等一些經(jīng)常用到的字符。字符集中的每一個字符都對應(yīng)有一個固定的ASCII碼值,通過顯示ASCII碼對應(yīng)的字符圖像就能夠?qū)崿F(xiàn)對應(yīng)字符的顯示。 圖3-5是PROTEUS中顯示模塊的仿真圖。 由于LCD要正常工作必須提供足夠的電流,因此在實際應(yīng)用為了保證顯示器能夠正常工作,應(yīng)在數(shù)據(jù)端口接一上拉電阻。圖3-5中RP1同時還是P0口的上拉電阻。

圖3-5 LCD模塊仿真圖 3.5 掉電存儲模塊 3.5.1 I2C總線I2C總線為同步串行數(shù)據(jù)傳輸總線,用于單片機(jī)的外圍擴(kuò)展。I2C總線上所有的外圍器件都有規(guī)范的器件地址,器件地址有7位組成,它和1位方向為構(gòu)成了I2C總線器件的尋址字節(jié)。尋址字節(jié)格式如下: 表3-2 I2C尋址格式 D7~D4是I2C總線的器件地址,由廠家在器件出廠時給定,對于AT24C系列固定為1010。A2~A0根據(jù)電路中A2,A1,A0引腳接電源或者接地而不同,接地則相應(yīng)位為0,接電源則相應(yīng)位為1。R/位為I2C總線的數(shù)據(jù)方向位,決定I2C總線的數(shù)據(jù)傳送方向,高電平為接收,低電平為發(fā)送。
圖3-6為I2C總線的數(shù)據(jù)傳送時序。

圖3-6 I2C總線數(shù)據(jù)傳送時序 起始信號:時鐘線SCL為高電平,數(shù)據(jù)線SDA出現(xiàn)由高向低的負(fù)跳變時,啟動I2C總線。 停止信號:時鐘線SCL為高電平,數(shù)據(jù)線SDA出現(xiàn)由低向高的正跳變時,停止I2C總線。 應(yīng)答信號位ACK:I2C總線進(jìn)行數(shù)據(jù)傳送時,每成功傳送一個字節(jié)的數(shù)據(jù)后,接收器件都必然產(chǎn)生一個應(yīng)答信號,即在第9個時鐘周期時將SDA線拉低,表示其已經(jīng)成功接收到一個8個數(shù)據(jù)。圖3-6中的第9個時鐘脈沖對應(yīng)于應(yīng)答位。應(yīng)答位對應(yīng)的數(shù)據(jù)線SDA上是低電平時為應(yīng)答信號,是高電平則為非應(yīng)答信號。為非應(yīng)答信號時,證明器件沒有成功接收到一個8位數(shù)據(jù)。 數(shù)據(jù)傳送位:圖3-6中的第1~8個時鐘脈沖為一個字節(jié)的8位數(shù)據(jù)傳送位。脈沖為高電平時,串行傳送數(shù)據(jù);脈沖為低電平時,不傳送數(shù)據(jù),允許總線上數(shù)據(jù)線SDA的電平發(fā)生變化。在I2C數(shù)據(jù)傳輸過程中,只有當(dāng)SCL為低電平時才允許SDA變化,當(dāng)SCL為高電平時,不允許SDA電平改變。當(dāng)然,起始信號和停止信號是例外。因此,當(dāng)SCL為高電平時,SDA的變化被看成是起始信號或者停止信號。 3.5.2 AT24C02簡介 AT24C02是Atmel公司生產(chǎn)的AT24CXX系列串行E2PROM中的一種,是具有I2C總線接口功能的電可擦除串行存儲器。AT24C02內(nèi)部含有256個字節(jié),通過I2C總線接口進(jìn)行操作,有一個專門的寫保護(hù)功能(WP=1時即為寫保護(hù))。 圖3-7是AT24C02的引腳排列圖。  其引腳功能如下: A0~A2:器件地址輸入端。在本設(shè)計中,A0~A2都接地,故其值都為0。 Vcc:+1.8~6.0V工作電壓。 Vss:地或電源負(fù)極。 圖3-7 AT24C02引腳 SCL:串行時鐘輸入端。數(shù)據(jù)發(fā)送或者接收的時鐘從此引腳輸入。 SDA:串行/數(shù)據(jù)地址線。用于傳送地址和發(fā)送或者接收數(shù)據(jù),是雙向傳送端口。 WP:寫保護(hù)端。WP=1時,只能讀出,不能寫入;WP=0時,允許正常的讀寫操作。 圖3-8為PROTEUS中E2PROM的仿真圖。 
圖3-8 AT24C02仿真圖 P2.5為串行時鐘輸入線接口,P2.6為數(shù)據(jù)線接口。A0,A1,A2接地,所以單片機(jī)在讀AT24C02時,器件地址為:10100001B=0A1H;在寫AT24C02時,器件地址為:10100000B=0A0H。WP=0,允許單片機(jī)進(jìn)行讀寫操作。 3.6 開鎖機(jī)構(gòu) 在基于單片機(jī)的電子密碼鎖設(shè)計中,用戶需要輸入密碼,密碼正確則發(fā)出開鎖信號開鎖。 因為在設(shè)計中是以發(fā)光二極管代替電磁鎖,二極管亮代表鎖開,因此可以設(shè)計一個簡單的可以點亮二極管的電路系統(tǒng)代替電磁鎖開鎖機(jī)構(gòu)。如圖3-9所示。 
圖3-9 二極管電路 由于單片機(jī)I/O口默認(rèn)為高電平,故初始時二極管不亮,代表鎖是閉著的。當(dāng)用戶輸入密碼并驗證正確時,發(fā)出開鎖信號(使P3.6=0)。 3.7 報警機(jī)構(gòu)在這次基于單片機(jī)的電子密碼鎖設(shè)計中,通過控制蜂鳴器的發(fā)音來實現(xiàn)系統(tǒng)的報警功能。 蜂鳴器是一種采用直流電壓供電的電子訊響器。圖3-10是用蜂鳴器模擬的報警機(jī)構(gòu)仿真圖。 
圖3-10 報警機(jī)構(gòu)模擬仿真圖
當(dāng)P3.7口有脈沖信號輸入時,蜂鳴器SPEAKER即會發(fā)音。通過控制輸入脈沖的頻率還能控制蜂鳴器的發(fā)音頻率。 當(dāng)用戶輸入密碼錯誤次數(shù)達(dá)到預(yù)設(shè)警告次數(shù)時,系統(tǒng)調(diào)用報警子程序,使蜂鳴器發(fā)出報警音,同時禁止鍵盤輸入。 3.8 硬件綜合設(shè)計 根據(jù)電路原理,在PROTEUS中畫出各功能模塊的仿真圖,各個功能模塊驗證正確后,將所有模塊集合到一個電路設(shè)計圖中,畫出具有所有功能的總體硬件仿真圖。 圖3-11即為本設(shè)計的硬件綜合設(shè)計圖。 
圖3-11 基于單片機(jī)的電子密碼鎖設(shè)計仿真圖 待程序編寫好后,將KEIL和PROTEUS聯(lián)調(diào),觀察此電路設(shè)計圖可以知道各個功能模塊和器件的工作情況。屆時,根據(jù)實際情況可以適當(dāng)修改電路圖或者程序,以達(dá)到設(shè)計的目的。
第4章 軟件設(shè)計4.1 軟件總體設(shè)計根據(jù)電子密碼鎖的實際應(yīng)用要求和其應(yīng)該具有的功能,本次設(shè)計的主程序流程圖如圖4-1所示。 
圖4-1 主程序流程圖 此次基于單片機(jī)的電子密碼鎖設(shè)計的軟件設(shè)計方面的主要問題是如何實現(xiàn)鍵盤輸入、信息顯示、密碼的掉電存儲以及密碼的比較和處理。本設(shè)計接下來將分步解決這幾個問題。 4.2 鍵盤掃描子程序矩陣鍵盤掃描子程序應(yīng)該具有以下2個基本的功能:(1)能判斷是否有鍵按下;(2)能確定是哪個鍵被按下。其軟件管理主要分為以下三步來完成: 讓所有的行為0,然后讀列的數(shù)值。如果列的數(shù)值全部為1,說明沒有鍵被按下,否則說明有鍵被按下。 采用一行一行的掃描方法,逐行輸出0,然后讀列的值。如果列的數(shù)值全部為1,說明不是這一行的按鍵被按下,掃描下一行,如果列的數(shù)值不全為1,則說明被按下的按鍵時在這一行。 - 查鍵值表,返回鍵值對應(yīng)信息,以便確定各按鍵應(yīng)該完成的功能。
采用某種算法,將被按下的鍵所在的行和列的信息合并成為一個信息,該信息即為此鍵的鍵值。用相同的方法給每一個鍵確定鍵值。在給按鍵確定鍵值時必須采用同一種算法,并且計算出來的鍵值應(yīng)該是互不相同的。 本設(shè)計中各按鍵對應(yīng)鍵值如表3所示。 表4-1 按鍵鍵值表
鍵盤掃描子程序的流程圖如圖4-2所示: 
圖4-2 鍵盤掃描程序流程圖 從流程圖可以看出,此鍵盤識別程序是通過逐行掃描來確定是否有鍵按下,當(dāng)確定某一行有鍵按下時,再在該行中確定被按下的是哪一個按鍵。 在本設(shè)計中,P1.0~P1.3為行輸出口,P1.4~P1.7為列輸出口。初始時將P1.0~P1.3值賦為0,P1.4~P1.7賦為1,CPU始終掃描P1端口,當(dāng)P1值不為0xf0時,有按鍵被按下,否責(zé)沒有按鍵被按下。 在實際應(yīng)用中,為了防止因為按鍵的抖動而使得一次按鍵按下被當(dāng)做2次或者2次以上處理,應(yīng)該進(jìn)行按鍵消抖程序設(shè)計,只要方法是當(dāng)有鍵閉合時,延時一段時間再確定是否還有鍵閉合,若有,則為鍵有效閉合,若無則為鍵無效閉合,返回重新掃描。 圖4-3為CPU掃描第一行鍵盤的程序流程圖。單行鍵盤掃描能夠準(zhǔn)確確定被按下鍵所在的位置。 
圖4-3 單行鍵盤掃描流程圖 在本設(shè)計中,數(shù)字鍵0~9對應(yīng)輸入數(shù)字0~9,功能鍵A鍵是確定鍵,B鍵是取消鍵,C鍵是改密碼鍵,D鍵位閉鎖鍵,E鍵和F鍵閑置不用。 4.3顯示模塊子程序 由于設(shè)計中要求能夠顯示密碼輸入界面、密碼輸入信息、密碼正確后提示界面、密碼錯誤后提示界面和修改密碼相關(guān)界面等信息,故要用到很多個顯示子程序來顯示不同的內(nèi)容。雖然顯示子程序很多,但是由于其顯示原理都一樣,所以我就不一一介紹各個子程序了,只要能夠熟練使用LCD1602各個指令,這些大同小異的子程序也就不在話下了。 下面為LCD1602寫命令子函數(shù)和寫數(shù)據(jù)子函數(shù)。 //************************************************ //函數(shù):寫命令函數(shù) //功能:調(diào)用該函數(shù)可能定義1602液晶顯示器的各種命令 //************************************************ void write_1602com(uchar com) { while(lcdbusy()); //lcdbusy()為檢測LCD忙標(biāo)志函數(shù),lcdbusy()返回值 e=0; //為1,則說明LCD正在工作 rw=0; rs=0; //rs=0時為寫命令 P0=com; //待寫命令賦P0 delay(1); e=1; //e由1→0跳變時為執(zhí)行命令 delay(1); e=0; } //************************************************* //函數(shù):寫數(shù)據(jù)函數(shù) //功能:調(diào)入該函數(shù)可以向1602液晶顯示器輸入數(shù)據(jù) //************************************************* void write_1602dat(uchar dat) { while(lcdbusy()); e=0; rw=0; rs=1; //rs=1時為寫數(shù)據(jù) P0=dat; delay(1); e=1; delay(1); e=0; } 以下是LCD1602從第一行第一列開始顯示N(0<N≤16)個字符的程序流程圖。 
圖4-4 顯示字符程序流程圖 顯示模塊子程序主要指根據(jù)LCD1602的命令和引腳功能來編寫,程序邏輯相當(dāng)簡單。 4.4 掉電存儲子程序 掉電存儲子程序就是將初始密碼寫進(jìn)AT24C02,單片機(jī)每次復(fù)位后從AT24C02中讀取密碼用來和輸入的密碼進(jìn)行比較,以判斷輸入的密碼的正確性。當(dāng)密碼修改成功后,將新密碼寫入AT24C02,以便單片機(jī)下次復(fù)位后使用。 掉電存儲模塊子程序主要涉及AT24C02的寫操作方式和讀操作方式。AT24C02有2種不同的寫操作形式和3種不同的讀操作方式。 4.4.1 寫操作方式兩種寫操作方式為:字節(jié)寫和頁寫。 (1)字節(jié)寫。字節(jié)寫模式下,主機(jī)發(fā)送(R/位置為0)起始命令和器件地址信息,主機(jī)在收到AT24C02的應(yīng)答信號后,發(fā)送1~8位字節(jié)地址,寫入AT24C02的地址指針中。對于高于8位的地址,主機(jī)連續(xù)發(fā)送兩個8位字節(jié)地址寫入AT24C02中,主機(jī)在收到AT24C02的另外一個應(yīng)答信號后再發(fā)送數(shù)據(jù)到被尋址的存儲單元,AT24C02再次應(yīng)答,并在主機(jī)發(fā)出停止信號后開始內(nèi)部數(shù)據(jù)的擦寫。AT24C02在內(nèi)部擦寫過程中不響應(yīng)主機(jī)的任何請求,因此在兩次寫操作之間應(yīng)該留有足夠的反應(yīng)時間。 字節(jié)寫的時序是這樣的: 地址只有8位:開始→器件地址→響應(yīng)→8位字節(jié)地址→響應(yīng)→數(shù)據(jù)→響應(yīng)→停止 地址高于8位:開始→器件地址→響應(yīng)→高8位字節(jié)地址→響應(yīng)→低8位字節(jié)地址→響應(yīng)→數(shù)據(jù)→響應(yīng)→停止 本次設(shè)計中采用的是字節(jié)寫方式。圖4-5為字節(jié)寫的程序流程圖。 
圖4-5 將字節(jié)寫入AT24C02的程序流程圖 (2)頁寫。頁寫和字節(jié)寫所不同的是:字節(jié)寫一次只能寫入一個字節(jié)數(shù)據(jù),頁寫一次可以寫入8個或16個字節(jié)數(shù)據(jù)。 頁寫的時序是這樣的: 地址只有8位:開始→器件地址→響應(yīng)→8位字節(jié)地址→響應(yīng)→數(shù)據(jù)1→響應(yīng)→……→數(shù)據(jù)N→響應(yīng)→停止。 地址高于8位:開始→器件地址→響應(yīng)→高8位字節(jié)地址→響應(yīng)→低8位字節(jié)地址→響應(yīng)→數(shù)據(jù)1→響應(yīng)→……→數(shù)據(jù)N→響應(yīng)→停止。 4.4.2 讀操作方式 三種不同的讀操作方式為:讀當(dāng)前地址內(nèi)容(立即地址讀。、讀隨機(jī)地址內(nèi)容(隨機(jī)地址讀取)和讀順序地址內(nèi)容(順序地址讀。。 (1)讀當(dāng)前地址內(nèi)容。AT24C02的地址計數(shù)器內(nèi)容為最后操作字節(jié)的地址加1,所有如果上次讀寫操作的地址為N,采用讀當(dāng)前地址內(nèi)容方式讀地址應(yīng)該從N+1地址處開始。AT24C02接收到器件地址信號并且I2C總線允許接收數(shù)據(jù)(R/=1),則首先發(fā)送一個應(yīng)答信號然后輸出數(shù)據(jù)。數(shù)據(jù)輸出完畢后,主機(jī)發(fā)送停止信號,讀操作完畢。 (2)讀隨機(jī)地址內(nèi)容。這種讀操作方式允許主機(jī)讀出AT24C02的任意字節(jié)。主機(jī)置通過R/位為0,發(fā)送開始信號、AT24C02地址和欲讀取的字節(jié)數(shù)據(jù)地址來執(zhí)行一次偽操作,在AT24C02應(yīng)答后,主機(jī)再一次發(fā)送開始信號和AT24C02的地址,此時R/位置1,AT24C02響應(yīng)并應(yīng)答信號,然后輸出字節(jié)數(shù)據(jù),最后主機(jī)以一個停止信號結(jié)束數(shù)據(jù)的讀取。 (3)讀順序地址內(nèi)容。讀順序地址內(nèi)容操作方式通過立即讀或隨機(jī)地址讀操作來啟動,主機(jī)在AT24C02發(fā)送完一個8位數(shù)據(jù)后產(chǎn)生一個應(yīng)答信號,告知AT24C02主機(jī)要求更多數(shù)據(jù)。AT24C02收到主機(jī)的應(yīng)答信號后繼續(xù)發(fā)送數(shù)據(jù),直到主機(jī)不發(fā)送應(yīng)答信號響應(yīng)而發(fā)送停止信號后操作結(jié)束。 下面是三種不同的讀操作方式時序?qū)Ρ龋?/div> 讀當(dāng)前地址內(nèi)容:開始→讀器件地址→響應(yīng)→數(shù)據(jù)→無響應(yīng)→停止。 讀隨機(jī)地址內(nèi)容:開始→寫器件地址→響應(yīng)→要讀的字節(jié)地址→響應(yīng)→開始→讀器件地址→響應(yīng)→數(shù)據(jù)→無響應(yīng)→停止。 讀順序地址內(nèi)容:開始→寫器件地址→響應(yīng)→要讀的字節(jié)地址→響應(yīng)→開始→讀器件地址→響應(yīng)→數(shù)據(jù)1→響應(yīng)→……→數(shù)據(jù)N→無響應(yīng)→停止。 本次設(shè)計中采用的是讀隨機(jī)地址內(nèi)容操作方式。
程序流程圖如圖4-6所示。 
圖4-6 讀AT24C02相應(yīng)地址內(nèi)容的程序流程圖 掉電存儲功能就是通過調(diào)用向AT24C02寫字節(jié)數(shù)據(jù)的程序和從AT24C02讀字節(jié)數(shù)據(jù)的程序來實現(xiàn)的。由于AT24C02在內(nèi)部擦寫過程中不會應(yīng)答任何來自主機(jī)的請求,所以當(dāng)向AT24C02連續(xù)寫多個字節(jié)數(shù)據(jù)時有可能不成功,這可以通過對同一字節(jié)數(shù)據(jù)寫多次的方法來實現(xiàn)。 4.5 定時器中斷子程序 為了防止戶主以外的“借用”戶主的密碼,當(dāng)沒有任何按鍵被按下的狀態(tài)持續(xù)一段時間后(比如20S內(nèi)),應(yīng)該馬上關(guān)閉顯示器屏幕,同時禁止按鍵的輸入。這樣做可以避免因為戶主忘記退出系統(tǒng)而使他人有機(jī)可乘。 圖4-7為實現(xiàn)此功能的程序流程圖。 
圖4-7 定時關(guān)閉屏幕和鎖定鍵盤輸入程序流程圖 程序中,使定時器0每50毫秒產(chǎn)生一次中斷,因此中斷每產(chǎn)生20次為1秒,當(dāng)秒數(shù)為20時(每次有鍵輸入時都執(zhí)行50毫秒數(shù)和秒數(shù)清0操作),關(guān)閉屏幕,并禁止鍵盤輸入。 當(dāng)定時/計數(shù)器工作在定時方式時,定時時間的計算公式為: 定時時間=(216 —計數(shù)初值)×定時周期 晶振頻率為12MHz時,定時/計數(shù)器的定時周期為1μs,所以定時50ms的定時/計數(shù)器初值為: 計數(shù)初值=216 —50000 4.6 密碼輸入子程序 當(dāng)從鍵盤輸入密碼時,應(yīng)當(dāng)將輸入的密碼存放,以便用做密碼的相關(guān)操作(判斷,修改和保存等),同時每輸入一位密碼應(yīng)相應(yīng)地在顯示器上顯示一個“*”號。圖4-8是密碼輸入子程序的流程圖。 
圖4-8 密碼輸入程序流程圖
輸入密碼時,當(dāng)輸入的密碼位數(shù)小于6位的時候,每按下一次數(shù)字鍵,就將此數(shù)字存入數(shù)組。當(dāng)輸入的密碼位數(shù)不小于6位時,再次按下數(shù)字鍵,程序就不進(jìn)行任何處理,繼續(xù)掃描鍵盤,此時只有按下確定鍵或者取消鍵程序才做出相應(yīng)反應(yīng)。取消鍵的功能是退格。當(dāng)不小心輸錯密碼時,可以退格將輸錯的位清除,退格一次密碼的位數(shù)減一位,同時顯示器上的“*”個數(shù)也減1。當(dāng)輸入的密碼位數(shù)變?yōu)?時,取消鍵不再起作用。 4.7 報警子程序 報警子程序的原理很簡單,即當(dāng)輸入密碼錯誤次數(shù)超過規(guī)定的最高允許次數(shù)時,不斷給蜂鳴器脈沖,使其不斷發(fā)音。同時,由于CPU一直在給蜂鳴器提供脈沖,故無暇處理諸如密碼掃描等事件,也就是說,在蜂鳴器報警的同時也屏蔽了鍵盤的輸入。 本次設(shè)計中,密碼輸入錯誤次數(shù)不得高于3次。圖4-9為報警子程序流程圖。 
圖4-9 報警子程序流程圖 第5章 聯(lián)合仿真和調(diào)試在PROTEUS中畫出仿真電路圖和在KEIL中編寫出程序后,需要驗證其正確性和可行性,最好的辦法就是就它們聯(lián)合起來仿真和調(diào)試。 KEIL和PROTEUS都是單片機(jī)愛好者和單片機(jī)相關(guān)工作者經(jīng)常用到的具有相當(dāng)好的輔助功能的軟件工具。KEIL是一款具有強(qiáng)悍功能的51系列兼容單片機(jī)C語言軟件開發(fā)系統(tǒng),為用戶提供豐富的庫函數(shù)和功能強(qiáng)大的集成開發(fā)調(diào)試工具,其生成目標(biāo)代碼的效率非常之高,且多數(shù)語句生成的匯編代碼很緊湊,容易理解。PROTEUS是目前世界上唯一一款將電路仿真軟件、PCB設(shè)計軟件和虛擬模型仿真軟件三合一的設(shè)計平臺。PROTEUS不僅具有其它電子設(shè)計自動化工具軟件的仿真功能,還能仿真單片機(jī)及外圍器件,是目前最好的仿真單片機(jī)及外圍器件的工具。 KEIL和PROTEUS都是單片機(jī)相關(guān)設(shè)計中經(jīng)常用到的軟件,KEIL和PROTEUS的聯(lián)合仿真和調(diào)試能夠相當(dāng)清晰地反映系統(tǒng)的各個功能模塊和器件的工作情況。通過KEIL和PROTEUS的聯(lián)合調(diào)試,單步執(zhí)行程序或者在程序中設(shè)置斷點,可以有效地查看各語句的執(zhí)行情況和各變量的值,從而找到程序中的錯誤。 KEIL和PROTEUS的聯(lián)合調(diào)試和仿真步驟如下: (1)在KEIL中建立工程,將編寫好的程序添加到工程中。 (2)在KEIL中為工程設(shè)置選項。為了實現(xiàn)和PROTEUS的聯(lián)合調(diào)試,除了一般工程選項的設(shè)置外,還要設(shè)置DUBUG項。具體方法為:單擊“工程菜單/為目標(biāo)‘目標(biāo)1’設(shè)置選項”選項,彈出窗口,點擊“Debug”按鈕。在出現(xiàn)的對話框里在右欄上部的下拉菜單里選中“Proteus VSM Monitor一51 Driver”。并且還要點擊一下“Use”前面表明選中的小圓點。再點擊“Setting”按鈕,設(shè)置通信接口,在“Host”后面添上“127.0.0.1”,如果使用的不是同一臺電腦,則需要在這里添上另一臺電腦的IP地址(另一臺電腦也應(yīng)安裝Proteus)。在“Port”后面添加“8000”,然后點擊“OK”按鈕。最后將工程編譯,進(jìn)入調(diào)試狀態(tài),并運(yùn)行。設(shè)置完之后,重新編譯、鏈接、生成可執(zhí)行文件。 (3)PROTEUS設(shè)置。進(jìn)入Proteus的ISIS,鼠標(biāo)左鍵點擊菜單“Debug”, 選中“使用遠(yuǎn)程調(diào)試監(jiān)控”。 (4)將可執(zhí)行文件加到單片機(jī)中。打開PROTEUS仿真圖,雙擊單片機(jī),將KEIL產(chǎn)生的“*.HEX”文件添加到單片機(jī)中。 (5)KEIL與PROTEUS連接仿真調(diào)試。點擊PROTEUS的開始仿真按鈕即可開始KEIL與PROTEUS的聯(lián)合仿真和調(diào)試。 本次設(shè)計的聯(lián)合仿真結(jié)果如下圖所示。 
圖5-1 密碼正確后的仿真圖 密碼輸入正確后,點亮二極管,顯示器顯示歡迎回家畫面。通過觀察鍵盤引腳的電平,還能知道CPU正在掃描鍵盤第四行,等待功能鍵的輸入。 本設(shè)計中鍵盤第四行只用到了前兩個按鍵,后兩個按鍵沒有被使用。第一個按鍵為改密碼鍵,通過按鍵此鍵可以進(jìn)入修改密碼功能界面;第二個鍵位閉鎖鍵,通過按下此鍵可以將鎖閉合,在設(shè)計中的直接表現(xiàn)是發(fā)光二極管熄滅。
第6章 實物設(shè)計和制作 聯(lián)合仿真調(diào)試通過后,本次設(shè)計業(yè)就進(jìn)入了最后一步,但也是最關(guān)鍵的一步——實物設(shè)計和制作。 由于電路板空間有限,所有在進(jìn)行實物設(shè)計之前應(yīng)該根據(jù)系統(tǒng)的仿真電路圖做好各功能模塊的整體布局,這樣既可以使得實物設(shè)計的順利進(jìn)行,也可以最大化的令做出來的實物看起來簡潔而美觀。 在本次設(shè)計中,實物設(shè)計是按以下步驟完成的: (1)單片機(jī)最小系統(tǒng)的電路焊接。只有保證了單片機(jī)最小系統(tǒng)的正確性,才能在接下來的其他模塊設(shè)計和焊接出現(xiàn)錯誤時能夠方便地檢查出原因,因此單片機(jī)最小系統(tǒng)是必須首先完成的。 (2)下載口電路的焊接。單片機(jī)最小系統(tǒng)電路焊接好后,需要檢查其正確性,這就需要往單片機(jī)中下載一個簡單的程序,看其是否能正常工作和復(fù)位,這就需要焊接一個下載口電路,此下載口電路還可以當(dāng)做電源口使用,通過數(shù)據(jù)線連接電源即可給單片機(jī)供電。 圖6-1為單片機(jī)下載口電路接線圖。 圖6-1 下載口電路接線圖 其中MOSI接口接單片機(jī)的P1.5口,RST接單片機(jī)的復(fù)位端口,SCK接單片機(jī)的P1.7口,MISO接單片機(jī)的P1.6口。下載口的2端口接電源,4、6、8、10端口接地。在下載口接好后,應(yīng)用單片機(jī)程序燒寫軟件通過下載口將測試程序下載進(jìn)入單片機(jī)測試最小系統(tǒng)是否焊接正確。一般使用的測試方法是在單片機(jī)端口接一個發(fā)光二極管,通過程序控制二極管發(fā)光,若能點亮二極管則最小系統(tǒng)焊接正確。在本次設(shè)計中使用的單片機(jī)程序燒寫軟件為AVR_fighter。 (3)液晶顯示器及電路焊接。按照仿真電路原理圖和液晶顯示器接口使用說明焊接好液晶顯示器,將顯示子程序下載入單片機(jī),若顯示器能夠按照要求顯示字符則焊接正確。 (4)鍵盤模塊焊接。按照鍵盤模塊仿真圖焊接按鍵,之后將測試程序?qū)雴纹瑱C(jī)中檢驗按鍵是否正確焊接成功。本設(shè)計中檢驗按鍵的程序功能是當(dāng)有按鍵按下時,將所按下的鍵值在液晶顯示器中顯示出來。 (5)E2PROM存儲器的焊接。根據(jù)AT24C02的引腳介紹,將AT24C02接到單片機(jī)上。測試AT24C02是否焊接正確的程序功能是將一個數(shù)組中的數(shù)寫入AT24C02,再將這一個數(shù)組中的數(shù)從AT24C02中讀出放入另一個數(shù)組中,比較兩個數(shù)組中的數(shù)是否相同,若相同則AT24C02的電路焊接正確,掉電存儲功能模塊功能實現(xiàn)。 (6)將蜂鳴器和發(fā)光二極管焊接到單片機(jī)系統(tǒng)中,將本次設(shè)計的源程序下載進(jìn)入單片機(jī)中,看是否所有功能都實現(xiàn)了。若能夠?qū)崿F(xiàn)所有功能則本次設(shè)計也就宣告完成,若不能實現(xiàn),則根據(jù)出現(xiàn)的問題檢查線路,找出原因,直至能夠?qū)崿F(xiàn)所有功能。 在實物制作過程中,應(yīng)該注意幾個問題:第一,根據(jù)仿真圖焊接電路,但不能盡信仿真圖。仿真圖始終不能代替實物調(diào)試,在實物制作過程中應(yīng)根據(jù)實際情況調(diào)試電路;第二,調(diào)試和查找錯誤過程中,如非必要應(yīng)盡量不要帶電操作,以免損壞器件;第三,電路布局應(yīng)盡量工整。工整簡潔的電路布局不但看著美觀,而且能夠更方便地查找電路錯誤。 本次設(shè)計的實物制作,由于經(jīng)驗不足的原因,許多焊接點焊得不夠美觀,但是整體布局還是夠簡潔工整的。這也是設(shè)計中雖然經(jīng)驗不足,制作過程中出現(xiàn)了各種各樣的問題,但是進(jìn)展卻很順利的原因,簡潔工整的布局使得查找問題變得更加容易,能夠方便的理清電路,找出錯誤并加以改正。
總結(jié)本次設(shè)計經(jīng)過近兩個月時間忙碌終于完成了,所有設(shè)計要求具備的功能都得到了實現(xiàn),具體如下: (1)加電后,單片機(jī)自動復(fù)位,LCD顯示提示輸入密碼的信息; (2)輸入密碼時,只逐位顯示“*”,以防止密碼泄漏; (3)在按鍵輸入的過程中,如果不小心輸錯,可以清除所輸入的錯誤內(nèi)容,然后繼續(xù)輸入; (4)當(dāng)密碼輸入完畢并按下確認(rèn)鍵后,單片機(jī)將輸入的密碼與設(shè)定的密碼比較,若密碼正確,則打開密碼鎖;若密碼不正確,則無法打開密碼鎖; (5)在密碼輸入錯誤次數(shù)達(dá)到預(yù)設(shè)值時,啟動報警程序報警; (6)可以在開鎖后進(jìn)行密碼的修改,但需要兩次輸入確認(rèn); (7)修改的密碼存入AT24C02,不會因為掉電的原因而丟失; (8)在長時間沒有按鍵輸入時,系統(tǒng)鎖定顯示器,并禁止按鍵的輸入; (9)設(shè)定一個備用密碼,防止常用密碼忘記時無法開門。 由于設(shè)計水平有限,此次設(shè)計還是存在一些小缺陷的,比如報警系統(tǒng)的報警音量不夠大,雖然加了一個三極管作為驅(qū)動,使得問題得到了改善,但是問題還是沒有得到完美的解決。 另外,通過這幾個月對電子密碼鎖的研究和學(xué)習(xí),我認(rèn)為本次設(shè)計中使用的這種鍵盤輸入密碼的方式可以進(jìn)行改革。在越來越高科技化的今天,遙控控制顯的愈發(fā)重要,今后的電子密碼鎖應(yīng)該具有以紅外技術(shù)或無線電技術(shù)為輔助的密碼按鍵輸入遠(yuǎn)程交互技術(shù),這樣就能遠(yuǎn)程輸入密碼完成操作。也可以放棄傳統(tǒng)的按鍵輸入密碼模式,借助傳感器技術(shù)運(yùn)用聲控來實現(xiàn)密碼輸入,又或者使用人臉識別技術(shù),或者用戶指紋識別技術(shù)代替?zhèn)鹘y(tǒng)的按鍵輸入,這些都可以使開鎖的時間更短更方便,同時是鎖更安全。
致謝在老師的耐心指導(dǎo)和同學(xué)們的熱情幫助下,經(jīng)過近三個月的不懈努力,本設(shè)計終于基本完成。在做設(shè)計的這段時間里,老師給我提供了極大的幫助和指導(dǎo)。從設(shè)計方向的分析到開題答辯報告的撰寫,從具體程序的設(shè)計到器件的選擇,老師都給了我很多很有用的建議。另外,老師親切和善、能和學(xué)生們打成一片的工作態(tài)度和認(rèn)真負(fù)責(zé)的治學(xué)作風(fēng)也給了我很深的印象。在此,對王老師表達(dá)最真誠的謝意和最崇高的敬意。 在做設(shè)計的過程中,自動化班的同學(xué)們也給我提供了很大的幫助,他們的關(guān)心和愛護(hù)不但幫助我更好地完成設(shè)計,更使我感受到了這個集體里家一樣的溫暖。非常感激自動化班的同學(xué)們。 同時,在即將離開校園的此時,衷心感謝每一位教導(dǎo)過我的老師和一直默默支持和鼓勵我的家人。 最后,我要向百忙之中抽出時間對本文進(jìn)行審閱、評議和參與本人論文答辯的各位老師表示感謝。
附錄1 設(shè)計實物圖附圖1 實物正面圖
附圖2 實物反面圖 附錄2 程序源代碼
- #include <reg51.h>
- #include <string.h>
- #include <intrins.h>
- #include<stdio.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define NOP3() _nop_();_nop_();_nop_()
- uchar time_1s=0,i=0;
- uchar time_50ms=0;
- sbit rs=P2^2;
- sbit rw=P2^1;
- sbit e=P2^0;
- sbit SCL=P2^5;
- sbit SDA=P2^6;
- sbit P35=P3^5;
- sbit P36=P3^6;
- sbit P37=P3^7;
- uchar data kong[7]={'\0','\0','\0','\0','\0','\0',0};
- uchar data mima[7]={'1','2','3','4','5','6',0};
- uchar data mima0[7]={'\0','\0','\0','\0','\0','\0',0};
- uchar data mima1[7]={'\0','\0','\0','\0','\0','\0',0};
- uchar data mima2[7]={'\0','\0','\0','\0','\0','\0',0};
- uchar data mima3[7]={'\0','\0','\0','\0','\0','\0',0};
- uchar data table1[7]={'1','9','9','0','1','0',0};
- uchar code table2[15]="Enter Password:";
- uchar code table4[16]="Password Error!";
- uchar code table5[14]="Old Password:";
- uchar code table6[14]="New Password:";
- uchar code table7[12]="Enter Again:";
- uchar code table8[12]="Enter Error!";
- uchar code table9[15]="Modify Success!";
- uchar code table10[13]="Welcome back!";
- //***********************************
- //相關(guān)函數(shù)的聲明
- //***********************************
- void delay1ms();
- void delay(uchar n);
- void write_1602com(uchar com);
- void write_1602dat(uchar dat);
- void initinal(void);
- bit lcdbusy();
- uchar key_scan();
- void enter_password(void); //功能:顯示輸入密碼畫面
- void password_error(void);//功能:顯示輸入密碼錯誤后的畫面
- void ok(void);//功能:顯示輸入密碼正確后的畫面
- void new_password(void);//功能:顯示輸入新密碼的畫面
- void enter_again(void);//功能:顯示再次輸入新密碼的畫面
- void enter_error(void);//功能:顯示兩次輸入的密碼不一樣后的畫面
- void modify_success(void);//功能:顯示更改成功后的畫面
- void welcome(void); //功能:顯示歡迎畫面
- void wtite_1602com(uchar com);
- void write_1602dat(uchar dat);
- /*****************************************************
- 函數(shù)功能:延時若干毫秒
- 入口參數(shù):n
- ***************************************************/
- void delay(uchar n)
- { unsigned char i,x,y;
- for(i=0;i<n;i++){for(x=0;x<10;x++)for(y=0;y<33;y++); } }
- /*****************************************************
- 函數(shù)功能:延時1ms
- ***************************************************/
- void delay1(uchar n){ unsigned char i,j;
- for(i=0;i<n;i++){ for(j=0;j<10;j++)delay(10);} }
- /*****************************************************
- 函數(shù)功能:定時器子函數(shù),調(diào)用該函數(shù)可以計時
- ***************************************************/
- void time( ){ TMOD = 0x01; //定時器0,工作方式1
- TH0 = (65536-50000)/256;
- TL0 = (65536-50000)%256; //50ms中斷一次
- EA = 1;ET0 = 1;TR0 = 1;}
- /*****************************************************
- 函數(shù)功能:定時函數(shù),在一段時間內(nèi)沒有鍵按下則關(guān)閉顯示器
- ***************************************************/
- void time_1( ) interrupt 1{
- TH0 = (65536-65536)/256;TL0 = (65536-65536)%256;time_50ms++;
- if(time_50ms==20){time_1s++;time_50ms=0;}
- if(time_1s==20){write_1602com(0x01);write_1602com(0x0c);
- time_1s=0; while(1);}}
- //***********************************
- //功能:使蜂鳴器發(fā)音
- //***********************************
- void warn(){P37=1;NOP3();NOP3();NOP3();
- P37=0;NOP3();NOP3();NOP3(); }
- //***********************************
- //函數(shù)名:bit lcdbusy()
- //功能:檢測忙標(biāo)志
- //***********************************
- bit lcdbusy(){bit result; rs=0;rw=1;e=1;
- delay(1);
- result=(bit)(P0&0x80);e=0;
- return result;}
- //************************************************
- //函數(shù)名:寫命令函數(shù)
- //功能:調(diào)用該函數(shù)可能定義1602液晶顯示器的各種命令
- //************************************************
- void write_1602com(uchar com){
- while(lcdbusy());
- e=0; rw=0; rs=0;
- P0=com; delay(1);
- e=1; delay(1);e=0;}
- //*************************************************
- //函數(shù)名:寫數(shù)據(jù)函數(shù)
- //功能:調(diào)入該函數(shù)可以向1602液晶顯示器輸入數(shù)據(jù)
- //*************************************************
- void write_1602dat(uchar dat){
- while(lcdbusy());e=0;rw=0;rs=1;
- P0=dat;delay(1);e=1;delay(1);e=0;}
- //**************************************************
- //函數(shù)名:初始化函數(shù)
- //功能:對1602液晶顯示器進(jìn)行初始化
- //**************************************************
- void initinal(void){
- rs=0;e=0;
- write_1602com(0x38); //數(shù)據(jù)總線為8位,顯示2行,0=5×7點陣/每字符
- write_1602com(0x0f); //顯示功能開,有光標(biāo),光標(biāo)不閃爍
- write_1602com(0x06); //顯示光標(biāo)
- write_1602com(0x01); //清屏
- write_1602com(0x80);}
- //*********************************************
- //函數(shù)名:顯示函數(shù)
- //功能:顯示輸入密碼
- //*********************************************
- void enter_password(void){ uchar j;
- initinal();write_1602com(0x80);
- for(j=0;j<15;j++){write_1602dat(table2[j]);delay(10);}
- write_1602com(0xc0+0x0a);}
- //********************************************
- //函數(shù)名:顯示函數(shù)
- //功能:顯示輸入密碼錯誤后的畫面
- //********************************************
- void password_error(void){uchar j;
- write_1602com(0x0c); //顯示功能開,無光標(biāo)
- write_1602com(0x80); //顯示位置第一行第一列
- write_1602com(0x01);
- for(j=0;j<15;j++){write_1602dat(table4[j]);delay(10);}}
- //******************************************
- //函數(shù)名:顯示函數(shù)
- //功能:顯示輸入舊密碼的畫面
- //******************************************
- void old_password(void){uchar j;
- initinal();write_1602com(0x80);
- for(j=0;j<14;j++){write_1602dat(table5[j]);delay(10);}
- write_1602com(0xc0+0x0a);}
- //******************************************
- //函數(shù)名:顯示函數(shù)
- //功能:顯示輸入新密碼的畫面
- //******************************************
- void new_password(void){uchar j;initinal();
- write_1602com(0x80);
- for(j=0;j<14;j++){write_1602dat(table6[j]);delay(10);}
- write_1602com(0xc0+0x0a);}
- //******************************************
- //函數(shù)名:顯示函數(shù)
- //功能:顯示再次輸入新密碼的畫面
- //******************************************
- void enter_again(void){uchar j;initinal();
- write_1602com(0x80);
- for(j=0;j<12;j++){write_1602dat(table7[j]);delay(10);}
- write_1602com(0xc0+0x0a);}
- //********************************************
- //函數(shù)名:顯示函數(shù)
- //功能:顯示兩次輸入的密碼不一樣后的畫面
- //********************************************
- void enter_error(void){uchar j;
- write_1602com(0x0c); //顯示功能開,無光標(biāo)
- write_1602com(0x80); //顯示位置第一行第一列
- write_1602com(0x01);
- for(j=0;j<12;j++){write_1602dat(table8[j]);delay(10);}}
- //******************************************
- //函數(shù)名:顯示函數(shù)
- //功能:顯示更改成功之后的畫面
- //******************************************
- void modify_success(void){uchar j;write_1602com(0x0c);
- write_1602com(0x80);write_1602com(0x01);
- for(j=0;j<15;j++){write_1602dat(table9[j]);delay(10);}}
- //******************************************
- //函數(shù)名:顯示函數(shù)
- //功能:顯示歡迎畫面
- //******************************************
- void welcome(void){
- uchar j;
- write_1602com(0x0c); //顯示功能開,無光標(biāo)
- write_1602com(0x80); //顯示位置第一行第4列
- write_1602com(0x01);
- write_1602com(0x80);
- for(j=0;j<13;j++){write_1602dat(table10[j]);delay(10);}}
- //**************************************************
- //函數(shù)名:鍵盤識別函數(shù)
- //功能:通過掃描對鍵盤進(jìn)行識別
- //**************************************************
- uchar key_num(){uint temp,b;
- while(1){P1=0xfe; //開始掃描第一行
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0){delay(1);temp=P1;b=temp;temp=temp&0xf0;
- if(temp!=0xf0){
- while(temp!=0xf0){temp=P1;temp=temp&0xf0;}
- switch(b){case 0xee: return '4';break;
- case 0xde: return '3';break;
- case 0xbe: return '2';break;
- case 0x7e: return '1';break;}}}
- P1=0xfd; //掃描第二行
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0){delay(1);temp=P1;b=temp;temp=temp&0xf0;
- if(temp!=0xf0){
- while(temp!=0xf0){temp=P1;temp=temp&0xf0;}
- switch(b){case 0xed: return '8';break;
- case 0xdd: return '7';break;
- case 0xbd: return '6';break;
- case 0x7d: return '5';break;}}}
- P1=0xfb; //掃描第三行
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0){delay(1);temp=P1;b=temp;temp=temp&0xf0;
- if(temp!=0xf0){
- while(temp!=0xf0){temp=P1;temp=temp&0xf0;}
- switch(b){ case 0xeb: return 'b';break;
- case 0xdb: return 'a';break;
- case 0xbb: return '0';break;
- case 0x7b: return '9';break;}}}}}
- /****************************************
- 只掃描第四行,禁止數(shù)字鍵輸入
- ****************************************/
- uchar key_gn(){uint temp,b;
- while(1){P1=0xf7; //掃描第四行
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0){delay(1);temp=P1;b=temp;temp=temp&0xf0;
- if(temp!=0xf0){
- while(temp!=0xf0){ temp=P1;temp=temp&0xf0;}
- switch(b){case 0xe7: return 'f';break;
- case 0xd7: return 'e';break;
- case 0xb7: return 'd';break;
- case 0x77: return 'c';break;}}} }}
- /****************************************
- 密碼函數(shù):將輸入的密碼寫放進(jìn)數(shù)組
- ****************************************/
- uchar enter(uchar password[]){uchar m=0,j,back=0;
- for(m=0;;){j=key_num();time_50ms=0;time_1s=0;
- if(j>='0'&&j<='9'&&m<6){write_1602com(0x06);password[m]=j; m++;
- write_1602dat('*');}
- if(j=='a'){password[m+1]='\0';return 1;} if(j=='b'){if(m>0){write_1602com(0x11);write_1602dat(0x20);
- write_1602com(0x11);password[m]='\0';m--;}} }}
- /******************************************
- 啟動I2C總線函數(shù)
- ******************************************/
- void Start(){ SCL=1;
- SDA=1;NOP3();
- SDA=0;NOP3();
- SCL=0;}
- /******************************************
- I2C停止
- ******************************************/
- void Stop(){ SDA=0;
- SCL=1;NOP3();
- SDA=1;NOP3();}
- /******************************************
- 發(fā)送應(yīng)答位函數(shù)
- ******************************************/
- void CHECK_ACK(){ SDA=0;NOP3();
- SCL=1;NOP3();
- SCL=0;NOP3();
- SDA=1;}
- /******************************************
- 發(fā)送非應(yīng)答位函數(shù)
- ******************************************/
- void CHECK_NACK(){ SDA=1;NOP3();
- SCL=1;NOP3();
- SCL=0;NOP3();
- SDA=0;}
-
- /******************************************
- I2C初始化
- ******************************************/
- void Init_24cxx(){ SDA=1;NOP3();
- SCL=1;NOP3();}
- /******************************************
- 讀I2C函數(shù)
- ******************************************/
- uchar I2C_Read(){
- uchar i,temp;temp=0;
- SDA=1;SCL=0;
- for(i=0;i<8;i++){
- temp=temp<<1;SCL=1;NOP3();
- if(SDA==1){temp=temp+1;}NOP3();
- SCL=0; }
- return temp;}
- /******************************************
- 寫I2C函數(shù)
- ******************************************/
- void I2C_Write(uchar date1){
- uchar i,temp;temp=date1;
- SCL=0;
- for(i=0;i<8;i++){
- SDA=(bit)(temp&0x80);
- SCL=1;NOP3();SCL=0;
- temp=temp<<1;}NOP3();}
- /******************************************
- 寫相應(yīng)地址的數(shù)據(jù)
- ******************************************/
- void Write_add(uint address,uchar date1){
- uchar addrh,addrl;
- addrh=address>>8;
- addrl=address%256;
- EA=0;
- Start();
- I2C_Write(0xa0);//發(fā)送命令字+芯片編號+P0+W
- CHECK_ACK();
- I2C_Write(addrh);//發(fā)高位地址
- CHECK_ACK();
- I2C_Write(addrl);//發(fā)低位地址
- CHECK_ACK();
- I2C_Write(date1);//發(fā)送數(shù)據(jù)
- CHECK_ACK();
- Stop();//停止
- EA=1;}
- /******************************************
- 讀相應(yīng)地址的數(shù)據(jù)
- ******************************************/
- uchar Read_add(uint address){
- uchar addrh,addrl,temp;
- addrh=address>>8;
- addrl=address%256;
- EA=0;
- Start();
- I2C_Write(0xa0);
- CHECK_ACK();
- I2C_Write(addrh);//發(fā)高位地址
- CHECK_ACK();
- I2C_Write(addrl);//發(fā)低位地址
- CHECK_ACK();
- Start();
- I2C_Write(0xa1);
- CHECK_ACK();
- temp=I2C_Read();
- CHECK_NACK();
- Stop();
- EA=1;
- return temp;
- }
- /******************************************
- 寫數(shù)據(jù)函數(shù):將數(shù)組寫入AT24C02
- ******************************************/
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
完整的Word格式文檔51黑下載地址:
基于單片機(jī)的電子密碼鎖設(shè)計(終稿).doc
(2.77 MB, 下載次數(shù): 1452)
2019-1-10 11:01 上傳
點擊文件名下載附件
仿真 工程代碼等下載: http://www.torrancerestoration.com/bbs/dpj-162561-1.html
|