摘 要:本設(shè)計(jì)提出了一種電子密碼鎖的設(shè)計(jì)方法。本系統(tǒng)由STC89C52單片機(jī)系統(tǒng)、4×4矩陣鍵盤、LCD1602顯示和報警系統(tǒng)等組成,具有設(shè)置、修改六位用戶密碼、超次報警、超次鎖定、密碼錯誤報警等功能。本系統(tǒng)成本低廉,功能實(shí)用。
第一章 緒論
1.1 課題背景和意義隨著電子技術(shù)和計(jì)算機(jī)技術(shù)的飛速發(fā)展,單片機(jī)性能不斷完善,性能價格比顯著提高,技術(shù)日趨完善。由于單片機(jī)具有體積小、重量輕、價格便宜、功耗低、控制功能強(qiáng)及運(yùn)算速度快等特點(diǎn),因而在國民經(jīng)濟(jì)建設(shè)、軍事及家用電器等各個領(lǐng)域均得到了廣泛的應(yīng)用。本設(shè)計(jì)利用單片機(jī)及附加電子元器件實(shí)現(xiàn)數(shù)據(jù)采集和控制算法,來完成某一實(shí)際功能。
隨著人們生活水平的提高和安全意識的加強(qiáng),對安全的要求也就越來越高。鎖自古以來就是把守護(hù)門的鐵將軍,人們對它要求甚高,既要安全可靠的防盜,又要使用方便,這也是制鎖者長期以來研制的主題。隨著電子技術(shù)的發(fā)展,各類電子產(chǎn)品應(yīng)運(yùn)而生,電子密碼鎖就是其中之一。電子鎖是通過鍵盤輸入一組密碼完成開鎖過程。研究這種鎖的初衷,就是為提高鎖的安全性。由于電子鎖的密鑰量(密碼量)極大,可以與機(jī)械鎖配合使用,并且可以避免因鑰匙被仿制而留下安全隱患。電子鎖只需記住一組密碼,無需攜帶金屬鑰匙,免除了人們攜帶金屬鑰匙的煩惱,而被越來越多的人所欣賞。電子鎖的種類繁多,例如數(shù)碼鎖,指紋鎖,磁卡鎖,IC卡鎖,生物鎖等。但較實(shí)用的還是按鍵式電子密碼鎖。
20世紀(jì)80年代后,隨著電子鎖專用集成電路的出現(xiàn),電子鎖的體積縮小,可靠性提高,成本較高,是適合使用在安全性要求較高的場合,且需要有電源提供能量,使用還局限在一定范圍,難以普及,所以對它的研究一直沒有明顯進(jìn)展。
目前,在西方發(fā)達(dá)國家,電子密碼鎖技術(shù)相對先進(jìn),種類齊全,電子密碼鎖已被廣泛應(yīng)用于智能門禁系統(tǒng)中,通過多種更加安全,更加可靠的技術(shù)實(shí)現(xiàn)大門的管理。國內(nèi)的不少企業(yè)也引進(jìn)了世界上先進(jìn)的技術(shù),發(fā)展前景非常可觀。希望通過不斷的努力,使電子密碼鎖在我國也能得到廣泛應(yīng)用。
1.2 電子密碼鎖發(fā)展趨勢 電子密碼鎖應(yīng)用于金融業(yè),其根本的作用是“授權(quán)”,即被“授權(quán)”的人才可以存取錢、物。廣義上講,金融業(yè)的“授權(quán)”主要包括以下三種層次的內(nèi)容:1、授予保管權(quán),如使用保管箱、保險箱和保險柜;2、授予出入權(quán),如出入金庫、運(yùn)鈔車和保管室;3、授予流通權(quán),如自動存取款。目前,金融行業(yè)電子密碼鎖的應(yīng)用主要集中在前兩個層面上。下面將介紹幾種在金融行業(yè)中使用較多的電子密碼鎖以及它們的技術(shù)發(fā)展方向。當(dāng)然,以上所說的授權(quán)技術(shù)再高超,都必須由精良的“鎖具”擔(dān)當(dāng)承載結(jié)構(gòu)部件,實(shí)現(xiàn)開啟、閉鎖的功能,而且承擔(dān)實(shí)體防護(hù)作用,抵抗住或盡量延遲破壞行為,讓電子密碼鎖“軟、硬不吃”。一般情況下,鎖具防盜的關(guān)鍵是鎖身外殼、閉鎖的部件的強(qiáng)度、鎖止型式、配合間隙和布局。提高電子密碼鎖之防護(hù)能力的必然途徑是報警,在金融業(yè)的許多場所有人值守、有電視監(jiān)控,具有報警功能,可以綜合物理防范和人力防范兩種作用。報警的前提是具備探測功能,根據(jù)電子密碼鎖的使用場所和防護(hù)要求,可選擇多種多樣的探測手段。在中國的城市金融業(yè)中,實(shí)現(xiàn)聯(lián)網(wǎng)報警已經(jīng)成為對各金融網(wǎng)點(diǎn)的基本要求。根據(jù)國內(nèi)外的實(shí)踐經(jīng)驗(yàn),金融業(yè)實(shí)行安全防范風(fēng)險等級很有必要,即依據(jù)使用的防盜報警器材的性能、安裝布局和人員值守狀況等,可以評估被防護(hù)物或區(qū)域的防護(hù)能力,得出風(fēng)險等級,其中,電子密碼鎖的性能至關(guān)重要。
由于數(shù)字、字符、圖形圖像、人體生物特征和時間等要素均可成為鑰匙的電子信息,組合使用這些信息能夠使電子密碼鎖獲得高度的保密性,如防范森嚴(yán)的金庫,需要使用復(fù)合信息密碼的電子密碼鎖,這樣對盜賊而言是“道高一尺、魔高一丈”。組合使用信息也能夠使電子密碼鎖獲得無窮擴(kuò)展的可能,使產(chǎn)品多樣化,對用戶而言是“千挑百選、自得其所”。
圖1.1 總體框圖
工作過程
- 按鍵設(shè)置6位密碼,輸入密碼,通過單片機(jī)判斷,若密碼正確,通過則鎖打開,顯示open!
- 首次使用時輸入:131420,對密碼進(jìn)行初始化,當(dāng)顯示:initpassword,證明密碼初始化完成,此時的密碼為:000000。
第二章 設(shè)計(jì)思想
(1)本設(shè)計(jì)為了防止密碼被竊取要求在輸入密碼時在LCD屏幕上顯示*號。
(2)設(shè)計(jì)開鎖密碼位六位密碼的電子密碼鎖。
(3)能夠LCD顯示在密碼正確時顯示open!,密碼錯誤時顯示ERROR,輸入密碼時顯示initpassword。
(4)實(shí)現(xiàn)輸入密碼錯誤超過限定的三次電子密碼鎖定。
(5)4×4的矩陣鍵盤其中包括0-9的數(shù)字鍵和A-D的功能鍵
(6)本產(chǎn)品具備報警功能,當(dāng)輸入密碼錯誤時蜂鳴器響并且LED燈亮。
- (7)密碼可以由用戶自己修改設(shè)定(只支持6位密碼),修改密碼之前必須再次輸入密碼,在輸入新密碼時候需要二次確認(rèn),以防止誤操作
-
第三章 系統(tǒng)的硬件設(shè)計(jì)
3.1硬件支持
3.1.1 STC89C52RC 單片機(jī)介紹
STC89C52是一種低功耗、高性能CMOS8位微控制器,具有 8K 在系統(tǒng)可編程Flash 存儲器。在單芯片上,擁有靈巧的8 位CPU 和在系統(tǒng)可編程Flash,使得STC89C51為眾多嵌入式控制應(yīng)用系統(tǒng)提供高靈活、超有效的解決方案。 具有以下標(biāo)準(zhǔn)功能: 8k字節(jié)Flash,512字節(jié)RAM, 32 位I/O 口線,看門狗定時器,內(nèi)置8KB EEPROM,MAX810復(fù)位電路,三個16 位 定時器/計(jì)數(shù)器,一個6向量2級中斷結(jié)構(gòu),全雙工串行口。另外 STC89X51 可降至0Hz 靜態(tài)邏輯操作,支持2種軟件可選擇節(jié)電模式。空閑模式下,CPU 停止工作,允許RAM、定時器/計(jì)數(shù)器、串口、中斷繼續(xù)工作。掉電保護(hù)方式下,RAM內(nèi)容被保存,振蕩器被凍結(jié),單片機(jī)一切工作停止,直到下一個中斷或硬件復(fù)位為止。最高運(yùn)作頻率35Mhz,6T/12T可選。

圖3-1 STC89C52單片機(jī)引腳圖
主要特性如下:
(1) 增強(qiáng)型 8051 單片機(jī),6 時鐘/機(jī)器周期和 12 時鐘/機(jī)器周期可以任 意選擇,指令代碼完全兼容傳統(tǒng) 8051.
(2)工作電壓:5.5V~3.3V(5V 單片機(jī))/3.8V~2.0V(3V 單片機(jī))
(3) 工作頻率范圍:0~40MHz,相當(dāng)于普通 8051 的 0~80MHz,實(shí)際工 作頻率可達(dá) 48MHz
(4) 用戶應(yīng)用程序空間為 8K 字節(jié)
(5) 片上集成 512 字節(jié) RAM
(6) 通用 I/O 口 (32 個) 復(fù)位后為: , P1/P2/P3/P4 是準(zhǔn)雙向口/弱上拉, P0 口是漏極開路輸出,作為總線擴(kuò)展用時,不用加上拉電阻,作為 I/O 口用時,需加上拉電阻。
(7)ISP(在系統(tǒng)可編程)/IAP(在應(yīng)用可編程) ,無需專用編程器,無 需專用仿真器,可通過串口(RxD/P3.0,TxD/P3.1)直接下載用戶程 序,數(shù)秒即可完成一片
(8)具有 EEPROM 功能
(9)具有看門狗功能
(10)共 3 個 16 位定時器/計(jì)數(shù)器。即定時器 T0、T1、T2
(11)外部中斷 4 路,下降沿中斷或低電平觸發(fā)電路,Power Down 模式可 由外部中斷低電平觸發(fā)中斷方式喚醒
(12)通用異步串行口(UART) ,還可用定時器軟件實(shí)現(xiàn)多個 UART
(13) 工作溫度范圍:-40~+85℃(工業(yè)級)/0~75℃(商業(yè)級)
(14) PDIP 封裝
3.1.2液晶顯示LCD1602的介紹(1)LM1602字符型模塊的性能重量輕:<100g;
體積小:<11mm 厚;
功耗低:10—15mW;
顯示內(nèi)容:192 種字符(5×7 點(diǎn)字型);
32 種字符(5×10 點(diǎn)字型);
可自編8(5×7)或許(5×10)種字符;
指令功能強(qiáng):可組合成各種輸入、顯示、移位方式以滿足不同的要求;
接口簡單方便:可與8 位微處理器或微控制器相聯(lián);
工作溫度寬:0—50oC
可靠性高:壽命為50,000 小時(25oC)

圖3-2 液晶原理圖
3.1.3自鎖開關(guān)說明
自鎖開關(guān)電路中起到電源的開關(guān)作用,常開的其中一腳接DC電源插口電源腳,常開的另一腳接電路的VCC

圖3-3自鎖開關(guān)原理圖 圖3-4自鎖開關(guān)硬件圖
3.1.4上拉電阻介紹
其實(shí)排阻就是由8個電阻組成的,其中一端全部接在一起,103為8個10K電阻,
102為8個1K電阻,他們在電路中起到“上拉”的作用,又稱上拉電阻。
上拉就是將不確定的信號通過一個電阻嵌位在高電平,電阻同時起限流作用,下拉同理.
上拉是對器件注入電流,下拉是輸出電流,弱強(qiáng)只是上拉電阻的阻值不同,沒有什么嚴(yán)格區(qū)分,對于非集電極(或漏極)開路輸出型電路(如普通門電路)提升電流和電壓的能力是有限的,上拉電阻的功能主要是為集電極開路輸出型電路輸出電流通道。
上拉,就是把電位拉高,比如拉到VCC
下拉,就是把電壓拉低,拉到GND
一般就是剛上電的時候,端口電壓不穩(wěn)定,為了讓他穩(wěn)定為高或低,就會用到上拉或下拉電阻。
有些芯片內(nèi)部集成了上拉電阻(如單片機(jī)的P1、2、3口),所以外部就不用上拉電阻了。但是有一些開漏的(如單片機(jī)的P0口),外部必須加上拉電阻。

圖3-5 排組上拉電阻原理圖
3.1.5三極管介紹
常見的三極管為9012、s8550、9013、s8050.單片機(jī)應(yīng)用電路中三極管主要的作用就是開關(guān)作用。
其中9012與8550為pnp型三極管,可以通用。
其中9013與8050為npn型三極管,可以通用。
區(qū)別引腳:三極管向著自己,引腳從左到右分別為ebc,原理圖中有箭頭的一端為e,與電阻相連的為b,另一個為c。箭頭向里指為PNP(9012或8550),箭頭向外指為NPN(9013或8050)。
三極管的工作原理
三極管是電流放大器件,有三個極,分別叫做集電極C,基極B,發(fā)射極E。分成NPN和PNP兩種。我們僅以NPN三極管的共發(fā)射極放大電路為例來說明一下三極管放大電路的基本原理。
(1)電流放大
下面的分析僅對于NPN型硅三極管。如上圖所示,我們把從基極B流至發(fā)射極E的電流叫做基極電流Ib;把從集電極C流至發(fā)射極E的電流叫做集電極電流 Ic。這兩個電流的方向都是流出發(fā)射極的,所以發(fā)射極E上就用了一個箭頭來表示電流的方向。三極管的放大作用就是:集電極電流受基極電流的控制(假設(shè)電源 能夠提供給集電極足夠大的電流的話),并且基極電流很小的變化,會引起集電極電流很大的變化,且變化滿足一定的比例關(guān)系:集電極電流的變化量是基極電流變 化量的β倍,即電流變化被放大了β倍,所以我們把β叫做三極管的放大倍數(shù)(β一般遠(yuǎn)大于1,例如幾十,幾百)。如果我們將一個變化的小信號加到基極跟發(fā)射 極之間,這就會引起基極電流Ib的變化,Ib的變化被放大后,導(dǎo)致了Ic很大的變化。如果集電極電流Ic是流過一個電阻R的,那么根據(jù)電壓計(jì)算公式 U=R*I 可以算得,這電阻上電壓就會發(fā)生很大的變化。我們將這個電阻上的電壓取出來,就得到了放大后的電壓信號了。
(2)偏置電路
三極管在實(shí)際的放大電路中使用時,還需要加合適的偏置電路。這有幾個原因。首先是由于三極管BE結(jié)的非線性(相當(dāng)于一個二極管),基極電流必須在輸入電壓 大到一定程度后才能產(chǎn)生(對于硅管,常取0.7V)。當(dāng)基極與發(fā)射極之間的電壓小于0.7V時,基極電流就可以認(rèn)為是0。但實(shí)際中要放大的信號往往遠(yuǎn)比 0.7V要小,如果不加偏置的話,這么小的信號就不足以引起基極電流的改變(因?yàn)樾∮?.7V時,基極電流都是0)。如果我們事先在三極管的基極上加上一 個合適的電流(叫做偏置電流,上圖中那個電阻Rb就是用來提供這個電流的,所以它被叫做基極偏置電阻),那么當(dāng)一個小信號跟這個偏置電流疊加在一起時,小 信號就會導(dǎo)致基極電流的變化,而基極電流的變化,就會被放大并在集電極上輸出。另一個原因就是輸出信號范圍的要求,如果沒有加偏置,那么只有對那些增加的 信號放大,而對減小的信號無效(因?yàn)闆]有偏置時集電極電流為0,不能再減小了)。而加上偏置,事先讓集電極有一定的電流,當(dāng)輸入的基極電流變小時,集電極 電流就可以減小;當(dāng)輸入的基極電流增大時,集電極電流就增大。這樣減小的信號和增大的信號都可以被放大了。
(3)開關(guān)作用
下面說說三極管的飽和情況。像上面那樣的圖,因?yàn)槭艿诫娮?Rc的限制(Rc是固定值,那么最大電流為U/Rc,其中U為電源電壓),集電極電流是不能無限增加下去的。當(dāng)基極電流的增大,不能使集電極電流繼續(xù)增大 時,三極管就進(jìn)入了飽和狀態(tài)。一般判斷三極管是否飽和的準(zhǔn)則是:Ib*β〉Ic。進(jìn)入飽和狀態(tài)之后,三極管的集電極跟發(fā)射極之間的電壓將很小,可以理解為 一個開關(guān)閉合了。這樣我們就可以拿三極管來當(dāng)作開關(guān)使用:當(dāng)基極電流為0時,三極管集電極電流為0(這叫做三極管截止),相當(dāng)于開關(guān)斷開;當(dāng)基極電流很 大,以至于三極管飽和時,相當(dāng)于開關(guān)閉合。如果三極管主要工作在截止和飽和狀態(tài),那么這樣的三極管我們一般把它叫做開關(guān)管。
(4)工作狀態(tài)
如果我們在上面這個圖中,將電阻Rc換成一個燈泡,那么當(dāng)基極電流為0時,集電極電流為0,燈泡滅。如果基極電流比較大時(大于流過燈泡的電流除以三極管 的放大倍數(shù) β),三極管就飽和,相當(dāng)于開關(guān)閉合,燈泡就亮了。由于控制電流只需要比燈泡電流的β分之一大一點(diǎn)就行了,所以就可以用一個小電流來控制一個大電流的通 斷。如果基極電流從0慢慢增加,那么燈泡的亮度也會隨著增加(在三極管未飽和之前)。

圖3-6 三極管引腳介紹 圖3-7 PNP型原理圖 圖3-8 NPN型原理圖
3.1.6繼電器介紹
電磁繼電器一般由鐵芯、線圈、銜鐵、觸點(diǎn)簧片等組成的。只要在線圈兩端加上一定的電壓,線圈中就會流過一定的電流,從而產(chǎn)生電磁效應(yīng),銜鐵就會在電磁力吸引的作用下克服返回彈簧的拉力吸向鐵芯,從而帶動銜鐵的動觸點(diǎn)與靜觸點(diǎn)(常開觸點(diǎn))吸合。當(dāng)線圈斷電后,電磁的吸力也隨之消失,銜鐵就會在彈簧的反作用力返回原來的位置,使動觸點(diǎn)與原來的靜觸點(diǎn)(常閉觸點(diǎn))釋放。這樣吸合、釋放,從而達(dá)到了在電路中的導(dǎo)通、切斷的目的。對于繼電器的“常開、常閉”觸點(diǎn),可以這樣來區(qū)分:繼電器線圈未通電時處于斷開狀態(tài)的靜觸點(diǎn),稱為“常開觸點(diǎn)”;處于接通狀態(tài)的靜觸點(diǎn)稱為“常閉觸點(diǎn)”。繼電器一般有兩股電路,為低壓控制電路和高壓工作電路。
繼電器的線圈和接線端子是分立的,互補(bǔ)影響的~~~~繼電器的觸點(diǎn)只相當(dāng)于開關(guān)

圖3-9 繼電器硬件圖 圖3-10 繼電器原理圖
3.1.7供電方式
圖3-11 DC插頭 圖3-12 USB電源線
3.1.8輕觸按鍵
圖3-13 實(shí)物圖 圖3-14 按鍵原理圖

圖3-15 按鍵解析圖相贈 圖3-16 按鍵解析圖
3.2功能單元模塊設(shè)計(jì)
3.2.1 開鎖機(jī)構(gòu)
通過單片機(jī)送給開鎖執(zhí)行機(jī)構(gòu),電路驅(qū)動電磁鎖吸合,從而達(dá)到開鎖的目的。如下圖所示,為密碼鎖開鎖電路原理圖。
當(dāng)用戶輸入的密碼正確時,單片機(jī)便輸出開門信號,送到開鎖驅(qū)動電路,然后驅(qū)動電磁鎖,達(dá)到開門的目的。本次設(shè)計(jì)中,基于節(jié)省成本考慮,用發(fā)光二極管代替電磁鎖,信息通過LCD顯示,并利用蜂鳴器和二極管聲光指示。其中,綠發(fā)光二極管亮,表示開鎖;否則,表示密碼輸入錯誤并開啟報警電路。
圖3-17 密碼鎖開鎖電路原理圖
3.2.2 矩陣鍵盤設(shè)計(jì)電路
每一條水平(行線)與垂直線(列線)的交叉處不相通,而是通過一個按鍵來連通,利用這種行列式矩陣結(jié)構(gòu)只需要M條行線和N條列線,即可組成具有M×N個按鍵的鍵盤。由于本設(shè)計(jì)中要求使用16個按鍵輸入,為減少鍵盤與單片機(jī)接口時所占用的I/O線的數(shù)目,故使用矩陣鍵盤。本設(shè)計(jì)中,矩陣鍵盤行線和單片機(jī)P1.0-P1.3相連,列線與單片機(jī)P1.4-P1.7相連。矩陣鍵盤設(shè)計(jì)電路圖,如圖4所示。
鍵盤掃描采用行掃描法,即依次置行線中的每一行為低電平,其余均為高電平,掃描列線電平狀態(tài),為低電平即表示該鍵按下。
圖3-18 矩陣鍵盤設(shè)計(jì)電路
3.2.3 聲音提示電路設(shè)計(jì)
聲音提示電路采用小蜂鳴器提示。蜂鳴器能夠根據(jù)脈沖信號,以及信號的頻率發(fā)出各種不同的聲音,這樣可以根據(jù)系統(tǒng)要求在密碼出入正確和密碼輸入錯誤時發(fā)出不同的聲音提示,已達(dá)到報警的要求。蜂鳴器電路,如下圖所示。

圖3-19 蜂鳴器電路
3.2.4 AT24C02掉電存儲單元的設(shè)計(jì)
本設(shè)計(jì)中掉電存儲單元采用AT24C02外部存儲器[8-9],其作用是在系統(tǒng)電源斷開的時候,存儲當(dāng)前設(shè)定的密碼數(shù)據(jù)。
AT24C02是一個2K位串行CMOS E2PROM,內(nèi)部含有256個8位字節(jié), 含一個16字節(jié)頁寫緩沖器,具有寫保護(hù)功能。其采用兩線串行的總線和單片機(jī)通訊,電壓最低可以到2.5V,額定電流為1mA,靜態(tài)電流10Ua(5.5V),芯片內(nèi)的資料可以在斷電的情況下保存40年以上,而且采用8腳的DIP封裝,使用方便。如下所示,下圖為AT24C02管腳示意圖,下表為AT24C02管腳說明。

圖3-20 AT24C02管腳示意圖
表1 AT24C02管腳說明
本設(shè)計(jì)中,AT24C02的SCL和SDA引腳接上拉電阻后與單片機(jī)的P3.4(T0)和P3.5(T1)腳相連,其電路下圖所示。

圖3-22 AT24C02掉電存儲單元設(shè)計(jì)圖
第四章 系統(tǒng)模塊與程序設(shè)計(jì)
4.1 模塊介紹
與硬件電路相關(guān)聯(lián),本系統(tǒng)軟件包括主程序模塊、密碼比較判斷模塊、鍵盤掃描模塊、修改密碼模塊、1602A液晶顯示模塊等[10]。系統(tǒng)程序流程下圖所示。

圖4-1 系統(tǒng)程序流程圖
4.1.1 主程序模塊
主程序主要用于定義全局變量,給全局變量賦初值,初始化E2PROM,啟動定時器以及 從AT24C02中讀取密碼,為整個程序提供數(shù)據(jù);檢測按鍵;調(diào)用顯示等功能。
4.1.2 密碼比較判斷模塊
該模塊的功能是將鍵盤輸入的密碼利用if語句與設(shè)定的密碼進(jìn)行逐個比較,若密碼完全正確則開鎖;若不正確,則開啟報警電路,復(fù)位后重新輸入密碼。其密碼輸入和比較判決流程圖下圖所示。

圖4-2 密碼輸入和比較判決流程圖
4.1.3 鍵盤掃描模塊
鍵盤使用矩陣式鍵盤,由行和列組成,CPU對所有鍵盤進(jìn)行監(jiān)視,從而實(shí)現(xiàn)逐列掃描鍵盤確定被按鍵的具體位置、判斷鍵盤上有無鍵按下、消除去抖動、判斷閉合的鍵是否釋放等功能。如下圖所示,為鍵盤掃描流程圖

圖4-3 鍵盤掃描流程圖
4.1.4 修改密碼模塊
在密碼輸入正確情況下,可以按下“重置密碼”對密碼進(jìn)行重新設(shè)置,每設(shè)定一位就將密碼送給AT24C02存儲起來,當(dāng)設(shè)置6位密碼完畢后,系統(tǒng)將自動跳到程序開始,調(diào)用新設(shè)置的密碼。下圖為修改密碼流程圖。

圖4-4 修改密碼流程圖
4.2電子密碼鎖原理圖
4.2.1 總電路圖
圖4-5 總電路圖
4.2.2控制電路
圖4-6 控制電路圖
4.2.3實(shí)物圖
圖4-7實(shí)物圖
4.2.4仿真圖
五 系統(tǒng)功能
本設(shè)計(jì)中系統(tǒng)可實(shí)現(xiàn)功能如下:
(1)對輸入的6位密碼進(jìn)行隱藏;
(2)通過發(fā)光二極管和蜂鳴器,對解密正確或者錯誤進(jìn)行聲光報警;
(3)6位密碼修改;
(4)在密碼遺失情況下,通過初始密碼進(jìn)行密碼再設(shè)置;
(5)采用AT24C02外部存儲器,完成斷電密碼保護(hù)功能;
六 設(shè)計(jì)總結(jié)
從基本方案的制定,到硬件電路的選擇,再到電路的焊接,最后進(jìn)行程序調(diào)試——在此期間我們遇到很多困難,但經(jīng)過不懈努力,終于擊破了各個難點(diǎn),達(dá)到的所需要的效果。在這次設(shè)計(jì)中,我深刻認(rèn)識到自身的不足——缺少實(shí)戰(zhàn)經(jīng)驗(yàn)。與此同時,也因?yàn)檫@次設(shè)計(jì),我得到一定的鍛煉,體會到理論與實(shí)踐相結(jié)合的重要意義。
由于本次設(shè)計(jì)時間有限,一些設(shè)想沒有完全實(shí)現(xiàn),比如說:電子密碼鎖的網(wǎng)絡(luò)通信擴(kuò)展,人機(jī)界面智能化等。期待以后有機(jī)會對以上設(shè)想進(jìn)行進(jìn)一步研究實(shí)踐。
致謝
非常感謝**老師,老師在我大學(xué)的最后學(xué)習(xí)階段——畢業(yè)設(shè)計(jì)階段給自己的指導(dǎo),從最初的定題,到資料收集,到寫作、修改,到論文定稿,她們給了我耐心的指導(dǎo)和無私的幫助。為了指導(dǎo)我們的畢業(yè)論文,他甚至放棄了自己的休息時間,他的這種無私奉獻(xiàn)的敬業(yè)精神令人欽佩,在此我向他表示我誠摯的謝意。同時,感謝所有任課老師和所有同學(xué)在這四年來給自己的指導(dǎo)和幫助,是他們教會了我專業(yè)知識,教會了我如何學(xué)習(xí),教會了我如何做人。正是由于他們,我才能在各方面取得顯著的進(jìn)步,在此向他們表示我由衷的謝意,并祝所有的老師培養(yǎng)出越來越多的優(yōu)秀人才,桃李滿天下
單片機(jī)源程序如下:
- <font style="background-color:rgb(255, 255, 255)">#include <REG51.h>
- #include<intrins.h>
- #define LCM_Data P0
- #define uchar unsigned char
- #define uint unsigned int
- #define w 6 //定義密碼位數(shù)
- sbit lcd1602_rs=P2^7;
- sbit lcd1602_rw=P2^6;
- sbit lcd1602_en=P2^5;
-
- sbit Scl=P3^4; //24C02串行時鐘
- sbit Sda=P3^5; //24C02串行數(shù)據(jù)
-
- sbit ALAM = P2^1; //報警
- sbit KEY = P3^6; //開鎖
-
- sbit open_led=P2^2; //開鎖指示燈
-
- bit operation=0; //操作標(biāo)志位
- bit pass=0; //密碼正確標(biāo)志
- bit ReInputEn=0; //重置輸入充許標(biāo)志
- bit s3_keydown=0; //3秒按鍵標(biāo)志位
- bit key_disable=0; //鎖定鍵盤標(biāo)志
-
- unsigned char countt0,second; //t0中斷計(jì)數(shù)器,秒計(jì)數(shù)器
-
- void Delay5Ms(void);
-
- unsigned char code a[]={0xFE,0xFD,0xFB,0xF7}; //控盤掃描控制表
-
- unsigned char code start_line[] = {"password: "};
- unsigned char code name[] = {"===Coded Lock==="}; //顯示名稱
- unsigned char code Correct[] = {" correct "}; //輸入正確
- unsigned char code Error[] = {" error "}; //輸入錯誤
- unsigned char code codepass[] = {" pass "};
- unsigned char code LockOpen[] = {" open "}; //OPEN
- unsigned char code SetNew[] = {"SetNewWordEnable"};
- unsigned char code Input[] = {"input: "}; //INPUT
- unsigned char code ResetOK[] = {"ResetPasswordOK "};
- unsigned char code initword[] = {"Init password..."};
- unsigned char code Er_try[] = {"error,try again!"};
- unsigned char code again[] = {"input again "};
-
- unsigned char InputData[6]; //輸入密碼暫存區(qū)
- unsigned char CurrentPassword[6]={1,3,1,4,2,0}; //當(dāng)前密碼值
- unsigned char TempPassword[6];
- unsigned char N=0; //密碼輸入位數(shù)記數(shù)
- unsigned char ErrorCont; //錯誤次數(shù)計(jì)數(shù)
- unsigned char CorrectCont; //正確輸入計(jì)數(shù)
- unsigned char ReInputCont; //重新輸入計(jì)數(shù)
- unsigned char code initpassword[6]={0,0,0,0,0,0};
-
- //=====================5ms延時==============================
- void Delay5Ms(void)
- {
- unsigned int TempCyc = 5552;
- while(TempCyc--);
- }
-
- //===================400ms延時==============================
- void Delay400Ms(void)
- {
- unsigned char TempCycA = 5;
- unsigned int TempCycB;
- while(TempCycA--)
- {
- TempCycB=7269;
- while(TempCycB--);
- }
- }
-
- //=============================================================================================
- //================================24C02========================================================
- //=============================================================================================
-
- void mDelay(uint t) //延時
- {
- uchar i;
- while(t--)
- {
- for(i=0;i<125;i++)
- {;}
- }
- }
- void Nop(void) //空操作
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
-
-
- /*起始條件*/
-
- void Start(void)
- {
- Sda=1;
- Scl=1;
- Nop();
- Sda=0;
- Nop();
- }
-
-
- /*停止條件*/
- void Stop(void)
- {
- Sda=0;
- Scl=1;
- Nop();
- Sda=1;
- Nop();
- }
-
- /*應(yīng)答位*/
- void Ack(void)
- {
- Sda=0;
- Nop();
- Scl=1;
- Nop();
- Scl=0;
- }
-
- /*反向應(yīng)答位*/
- void NoAck(void)
- {
- Sda=1;
- Nop();
- Scl=1;
- Nop();
- Scl=0;
- }
-
- /*發(fā)送數(shù)據(jù)子程序,Data為要求發(fā)送的數(shù)據(jù)*/
- void Send(uchar Data)
- {
- uchar BitCounter=8;
- uchar temp;
- do
- {
- temp=Data;
- Scl=0;
- Nop();
- if((temp&0x80)==0x80)
- Sda=1;
- else
- Sda=0;
- Scl=1;
- temp=Data<<1;
- Data=temp;
- BitCounter--;
- }
- while(BitCounter);
- Scl=0;
- }
-
- /*讀一字節(jié)的數(shù)據(jù),并返回該字節(jié)值*/
- uchar Read(void)
- {
- uchar temp=0;
- uchar temp1=0;
- uchar BitCounter=8;
- Sda=1;
- do{
- Scl=0;
- Nop();
- Scl=1;
- Nop();
- if(Sda)
- temp=temp|0x01;
- else
- temp=temp&0xfe;
- if(BitCounter-1)
- {
- temp1=temp<<1;
- temp=temp1;
- }
- BitCounter--;
- }
- while(BitCounter);
- return(temp);
- }
-
- void WrToROM(uchar Data[],uchar Address,uchar Num)
- {
- uchar i;
- uchar *PData;
- PData=Data;
- for(i=0;i<Num;i++)
- {
- Start();
- Send(0xa0);
- Ack();
- Send(Address+i);
- Ack();
- Send(*(PData+i));
- Ack();
- Stop();
- mDelay(20);
- }
- }
-
- void RdFromROM(uchar Data[],uchar Address,uchar Num)
- {
- uchar i;
- uchar *PData;
- PData=Data;
- for(i=0;i<Num;i++)
- {
- Start();
- Send(0xa0);
- Ack();
- Send(Address+i);
- Ack();
- Start();
- Send(0xa1);
- Ack();
- *(PData+i)=Read();
- Scl=0;
- NoAck();
- Stop();
- }
- }
- //==================================================================================================
- //=======================================LCD1602====================================================
- //==================================================================================================
-
- #define yi 0x80 //LCD第一行的初始位置,因?yàn)長CD1602字符地址首位D7恒定為1(100000000=80)
- #define er 0x80+0x40 //LCD第二行初始位置(因?yàn)榈诙械谝粋字符位置地址是0x40)
-
-
- //----------------延時函數(shù),后面經(jīng)常調(diào)用----------------------
- void delay(uint xms)//延時函數(shù),有參函數(shù)
- {
- uint x,y;
- for(x=xms;x>0;x--)
- for(y=110;y>0;y--);
- }
-
- //--------------------------寫指令---------------------------
- write_1602com(uchar com)//****液晶寫入指令函數(shù)****
- {
- lcd1602_rs=0;//數(shù)據(jù)/指令選擇置為指令
- lcd1602_rw=0; //讀寫選擇置為寫
- P0=com;//送入數(shù)據(jù)
- delay(1);
- lcd1602_en=1;//拉高使能端,為制造有效的下降沿做準(zhǔn)備
- delay(1);
- lcd1602_en=0;//en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令
- }
-
- //-------------------------寫數(shù)據(jù)-----------------------------
- write_1602dat(uchar dat)//***液晶寫入數(shù)據(jù)函數(shù)****
- {
- lcd1602_rs=1;//數(shù)據(jù)/指令選擇置為數(shù)據(jù)
- lcd1602_rw=0; //讀寫選擇置為寫
- P0=dat;//送入數(shù)據(jù)
- delay(1);
- lcd1602_en=1; //en置高電平,為制造下降沿做準(zhǔn)備
- delay(1);
- lcd1602_en=0; //en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令
- }
-
- //-------------------------初始化-------------------------
- void lcd_init(void)
- {
- write_1602com(0x38);//設(shè)置液晶工作模式,意思:16*2行顯示,5*7點(diǎn)陣,8位數(shù)據(jù)
- write_1602com(0x0c);//開顯示不顯示光標(biāo)
- write_1602com(0x06);//整屏不移動,光標(biāo)自動右移
- write_1602com(0x01);//清顯示
- }
- //========================================================================================
- //=========================================================================================
-
- //==============將按鍵值編碼為數(shù)值=========================
- unsigned char coding(unsigned char m)
- {
- unsigned char k;
-
- switch(m)
- {
- case (0x11): k=1;break;
- case (0x21): k=2;break;
- case (0x41): k=3;break;
- case (0x81): k='A';break;
- case (0x12): k=4;break;
- case (0x22): k=5;break;
- case (0x42): k=6;break;
- case (0x82): k='B';break;
- case (0x14): k=7;break;
- case (0x24): k=8;break;
- case (0x44): k=9;break;
- case (0x84): k='C';break;
- case (0x18): k='*';break;
- case (0x28): k=0;break;
- case (0x48): k='#';break;
- case (0x88): k='D';break;
- }
- return(k);
- }
-
-
- //=====================按鍵檢測并返回按鍵值===============================
- unsigned char keynum(void)
- {
- unsigned char row,col,i;
- P1=0xf0;
- if((P1&0xf0)!=0xf0)
- {
- Delay5Ms();
- Delay5Ms();
- if((P1&0xf0)!=0xf0)
- {
- row=P1^0xf0; //確定行線
- i=0;
- P1=a[i]; //精確定位
- while(i<4)
- {
- if((P1&0xf0)!=0xf0)
- {
- col=~(P1&0xff); //確定列線
- break; //已定位后提前退出
- }
- else
- {
- i++;
- P1=a[i];
- }
- }
- }
- else
- {
- return 0;
- }
-
- while((P1&0xf0)!=0xf0);
- return (row|col); //行線與列線組合后返回
- }
- else return 0; //無鍵按下時返回0
- }
- //=======================一聲提示音,表示有效輸入========================
- void OneAlam(void)
- {
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- }
- //========================二聲提示音,表示操作成功========================
- void TwoAlam(void)
- {
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- Delay5Ms();
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- }
- //========================三聲提示音,表示錯誤========================
- void ThreeAlam(void)
- {
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- Delay5Ms();
- ALAM=0;
- Delay5Ms();
- ALAM=1;
- Delay5Ms();
- ALAM=0;
- Delay5Ms();
- ALAM=1;
-
- }
- //=====================顯示輸入的N個數(shù)字,用H代替以便隱藏============================
- void DisplayOne(void)
- {
- // DisplayOneChar(9+N,1,'*');
- write_1602com(yi+5+N);
- write_1602dat('*');
- }
- //=======================顯示提示輸入=========================
- void DisplayChar(void)
- {
- unsigned char i;
- if(pass==1)
- {
- //DisplayListChar(0,1,LockOpen);
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(LockOpen[i]);
- }
- }
- else
- {
- if(N==0)
- {
- //DisplayListChar(0,1,Error);
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(Error[i]);
- }
- }
- else
- {
- //DisplayListChar(0,1,start_line);
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(start_line[i]);
- }
- }
- }
- }
-
- void DisplayInput(void)
- {
- unsigned char i;
- if(CorrectCont==1)
- {
- //DisplayListChar(0,0,Input);
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(Input[i]);
- }
- }
- }
-
-
- //========================重置密碼==================================================
- //==================================================================================
- void ResetPassword(void)
- {
- unsigned char i;
- unsigned char j;
- if(pass==0)
- {
- pass=0;
- DisplayChar();
- ThreeAlam();
- }
- else
- {
- if(ReInputEn==1)
- {
- if(N==6)
- {
- ReInputCont++;
- if(ReInputCont==2)
- {
- for(i=0;i<6;)
- {
- if(TempPassword[i]==InputData[i]) //將兩次輸入的新密碼作對比
- i++;
- else
- {
- //DisplayListChar(0,1,Error);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(Error[j]);
- }
- ThreeAlam(); //錯誤提示
- pass=0;
- ReInputEn=0; //關(guān)閉重置功能,
- ReInputCont=0;
- DisplayChar();
- break;
- }
- }
- if(i==6)
- {
- //DisplayListChar(0,1,ResetOK);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(ResetOK[j]);
- }
-
- TwoAlam(); //操作成功提示
- WrToROM(TempPassword,0,6); //將新密碼寫入24C02存儲
- ReInputEn=0;
- }
- ReInputCont=0;
- CorrectCont=0;
- }
- else
- {
- OneAlam();
- //DisplayListChar(0, 1, again); //顯示再次輸入一次
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(again[j]);
- }
- for(i=0;i<6;i++)
- {
- TempPassword[i]=InputData[i]; //將第一次輸入的數(shù)據(jù)暫存起來
- }
- }
-
- N=0; //輸入數(shù)據(jù)位數(shù)計(jì)數(shù)器清零
- }
- }
- }
-
- }
-
-
-
- //=======================輸入密碼錯誤超過三過,報警并鎖死鍵盤======================
- void Alam_KeyUnable(void)
- {
- P1=0x00;
- {
- ALAM=~ALAM;
- Delay5Ms();
- }
- }
-
-
- //=======================取消所有操作============================================
- void Cancel(void)
- {
- unsigned char i;
- unsigned char j;
- //DisplayListChar(0, 1, start_line);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(start_line[j]);
- }
- TwoAlam(); //提示音
- for(i=0;i<6;i++)
- {
- InputData[i]=0;
- }
- KEY=1; //關(guān)閉鎖
- ALAM=1; //報警關(guān)
- operation=0; //操作標(biāo)志位清零
- pass=0; //密碼正確標(biāo)志清零
- ReInputEn=0; //重置輸入充許標(biāo)志清零
- ErrorCont=0; //密碼錯誤輸入次數(shù)清零
- CorrectCont=0; //密碼正確輸入次數(shù)清零
- ReInputCont=0; //重置密碼輸入次數(shù)清零
- open_led=1;
- s3_keydown=0;
- key_disable=0;
- N=0; //輸入位數(shù)計(jì)數(shù)器清零
- }
-
-
- //==========================確認(rèn)鍵,并通過相應(yīng)標(biāo)志位執(zhí)行相應(yīng)功能===============================
- void Ensure(void)
- {
- unsigned char i,j;
- RdFromROM(CurrentPassword,0,6); //從24C02里讀出存儲密碼
- if(N==6)
- {
- if(ReInputEn==0) //重置密碼功能未開啟
- {
- for(i=0;i<6;)
- {
- if(CurrentPassword[i]==InputData[i])
- {
- i++;
- }
- else
- {
- ErrorCont++;
- if(ErrorCont==3) //錯誤輸入計(jì)數(shù)達(dá)三次時,報警并鎖定鍵盤
- {
- write_1602com(er);
- for(i=0;i<16;i++)
- {
- write_1602dat(Error[i]);
- }
- do
- Alam_KeyUnable();
- while(1);
- }
- else
- {
- TR0=1; //開啟定時
- key_disable=1; //鎖定鍵盤
- pass=0;
- break;
- }
- }
- }
-
- if(i==6)
- {
- CorrectCont++;
- if(CorrectCont==1) //正確輸入計(jì)數(shù),當(dāng)只有一次正確輸入時,開鎖,
- {
- //DisplayListChar(0,1,LockOpen);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(LockOpen[j]);
- }
- TwoAlam(); //操作成功提示音
- KEY=0; //開鎖
- pass=1; //置正確標(biāo)志位
- TR0=1; //開啟定時
- open_led=0; //開鎖指示燈亮
- for(j=0;j<6;j++) //將輸入清除
- {
- InputData[i]=0;
- }
- }
- else //當(dāng)兩次正確輸入時,開啟重置密碼功能
- {
- //DisplayListChar(0,1,SetNew);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(SetNew[j]);
- }
- TwoAlam(); //操作成功提示
- ReInputEn=1; //允許重置密碼輸入
- CorrectCont=0; //正確計(jì)數(shù)器清零
- }
- }
-
- else //=========================當(dāng)?shù)谝淮问褂没蛲浢艽a時可以用131420對其密碼初始化============
- {
- if((InputData[0]==1)&&(InputData[1]==3)&&(InputData[2]==1)&&(InputData[3]==4)&&(InputData[4]==2)&&(InputData[5]==0))
- {
- WrToROM(initpassword,0,6); //強(qiáng)制將初始密碼寫入24C02存儲
- //DisplayListChar(0,1,initword); //顯示初始化密碼
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(initword[j]);
- }
- TwoAlam();
- Delay400Ms();
- TwoAlam();
- N=0;
- }
- else
- {
- //DisplayListChar(0,1,Error);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(Error[j]);
- }
- ThreeAlam(); //錯誤提示音
- pass=0;
- }
- }
- }
-
- else //當(dāng)已經(jīng)開啟重置密碼功能時,而按下開鎖鍵,
- {
- //DisplayListChar(0,1,Er_try);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(Er_try[j]);
- }
- ThreeAlam();
- }
- }
-
- else
- {
- //DisplayListChar(0,1,Error);
- write_1602com(er);
- for(j=0;j<16;j++)
- {
- write_1602dat(Error[j]);
- }
-
- ThreeAlam(); //錯誤提示音
- pass=0;
- }
- N=0; //將輸入數(shù)據(jù)計(jì)數(shù)器清零,為下一次輸入作準(zhǔn)備
- operation=1;
- }
- //==============================主函數(shù)===============================
- void main(void)
- {
- unsigned char KEY,NUM;
- unsigned char i,j;
- P1=0xFF;
- TMOD=0x11;
- TL0=0xB0;
- TH0=0x3C;
- EA=1;
- ET0=1;
- TR0=0;
- Delay400Ms(); //啟動等待,等LCM講入工作狀態(tài)
- lcd_init(); //LCD初始化
- write_1602com(yi);//日歷顯示固定符號從第一行第0個位置之后開始顯示
- for(i=0;i<16;i++)
- {
- write_1602dat(name[i]);//向液晶屏寫日歷顯示的固定符號部分
- }
- write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
- for(i=0;i<16;i++)
- {
- write_1602dat(start_line[i]);//寫顯示時間固定符號,兩個冒號
- }
- write_1602com(er+9); //設(shè)置光標(biāo)位置
- write_1602com(0x0f); //設(shè)置光標(biāo)為閃爍
- Delay5Ms(); //延時片刻(可不要)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
- </font>
復(fù)制代碼
所有資料51hei提供下載: