這是我的單片機結課項目
原理比較簡單,主要使用80C51單片機,加一個lcd屏
接線圖
按鍵
信息與機電工程學院
《單片機原理及應用》課程設計報告
課題名稱 基于51單片機的電子密碼鎖設計
專業班級 2016級電子信息工程國內班
基于51單片機的電子密碼鎖設計 摘 要 在日常的生活和工作中,住宅安全,文件資料的保護都需要用鎖來保證。傳統往往使用機械式鑰匙開鎖,但鑰匙丟失會使鎖的安全性大打折扣。隨著科學技術的不斷發展,電子密碼鎖應運而生,而密碼鎖也具有安全性高、成本低、功耗低、易操作等優點。 本設計是基于51單片機,并結合液晶顯示LCD1602,以及矩陣鍵盤輸入、復位、電源等電路組合而成。系統能夠完成開鎖、修改密碼等基本功能。整個設計在Keil開發環境下,用C語言編寫主控芯片的控制程序來實現具有多功能的電子密碼鎖。
一、緒論 1.1電子密碼鎖的背景 隨著社會不斷進步,人民生活水平不斷提高,安全成為現代居民最關心的問題之一。從古至今,鎖一直就是保護人們財產的必不可少的工具。目前,我們最常用的鎖就是圓柱形銷栓的彈子鎖,其機構簡單,使用方便,價格便宜,但在使用中暴露了很多缺點:1、容易被開啟;2、內部機械結構復雜、故障率高;3、換鎖麻煩;4、互開率高;5、易被破壞;6、帶鑰匙的煩惱;7、鑰匙開門的煩惱。 電子密碼鎖是一種通過密碼輸入來控制電路或是芯片工作,從而控制機械開關的閉合,完成開鎖、閉鎖任務的電子產品。它的種類很多,有簡易的電路產品,也有基于芯片的性價比較高的產品。現在應用較廣的電子密碼鎖是以芯片為核心,通過編程來實現的。其性能和安全性已大大超過了機械鎖。所以,研究電子密碼鎖,符合現在主流發展趨勢,具有極大的研究意義和現實意義,也具有經濟可行性。 1.2電子密碼鎖的特點 1.保密性好,編碼量多,遠遠大于彈子鎖。隨機開鎖成功率幾乎為零。 2.密碼可變。 用戶可以經常更改密碼,防止密碼被盜,同時也可以避免因人員的更替而使鎖的密級下降。 3.誤碼輸入保護。當輸入密碼多次錯誤時,報警系統自動啟動。 4. 電子密碼鎖操作簡單易行,一學即會。 5.干擾碼功能。在輸入正確密碼前可輸入任意碼。 6.安保功能。如果連續輸錯4次密碼將會自動斷電3分鐘。 7.緊急開啟功能(Panic Open)。出門時無需其他操作,只需一次的把手動作,可機械的開啟門,所以遇到火災等應急狀況下也迅速,安全的開啟門。 8.入侵感應功能。在門上鎖的狀態下,有人破鎖而入時,會發出強力的報警音。 9.火災報警功能。在室內如果溫度達到75°左右,將會發出強力的報警音,同時鎖會自動開啟。 10.雙重鎖定功能。外部強制鎖定:在內部不能開啟,適用于外出時,防止有人入侵。內部強制鎖定:在外部不能開啟,讓您在家時更安心、安全。 11.弱電提醒功能。弱電提醒當電量不足時,在啟動開門時,會有美妙的音樂提示您及時更換電池。 12.自動上鎖功能。采用全自動鎖芯,門關后6秒內自動上鎖,外出更加安全。 13.外部顯示功能。當密碼輸入錯誤,鎖舌沒正常鎖到位,室內反鎖,弱電等情況下,外部都有提示功能。 1.3電子密碼鎖的設計意義 單片機是典型的嵌入式微控制器(Microcontroller Unit),由運算器,控制器,存儲器,輸入輸出設備等構成,相當于一個微型的計算機。與應用在個人電腦中的通用型微處理器相比,它更強調自供應(不用外接硬件)和節約成本。它的最大優點是體積小,可放在儀表內部,但存儲量小,輸入輸出接口簡單,功能較低。由于其發展非常迅速,舊的單片機的定義已不能滿足,所以在很多應用場合被稱為范圍更廣的微控制器;從上世紀80年代,由當時的4位、8位單片機,已經發展到現在的32位300M的高速單片機。 單片機相當于一個微型的計算機(最小系統),和計算機相比,單片機缺少了外圍設備等。概括的講:一塊芯片就成了一臺計算機。它的體積小、質量輕、價格便宜、為學習、應用和開發提供了便利條件。同時,學習使用單片機是了解計算機原理與結構的最佳選擇。它最早是被用在工業控制領域。 在很多方面單片機比專用處理器更適合應用于嵌入式系統,因此它得到了廣泛的應用。事實上單片機是世界上數量最多處理器,隨著單片機家族的發展壯大,單片機和專用處理器的發展便分道揚鑣。
現代人類生活中所用的幾乎每件有電子器件的產品中都會集成有單片機。手機、電話、計算器、家用電器、電子玩具、掌上電腦以及鼠標等電子產品中都含有單片機。 基于單片機的電子密碼鎖設計,只需在單片機外圍接簡單的接口電路,核心部分由人為寫入程序即可,這樣不僅易于操作,也可使產品成本大大降級,且容易進行升級改善。該種電子密碼鎖設計方法合理,簡單易行,成本低,符合人們需求,具有一定的商業價值和市場推廣性。 二、實驗原理 2.1單片機開發系統主要硬件簡介 單片機開發系統的硬件采用的是普中科技的HC6800EM3單片機開發試驗儀,它是具有“實驗、編程、ISP下載線”多功能合一的新一代單片機開發系統。該51單片機學習實驗板支持STC的增強型51單片機的實驗、編程功能,同時也兼容AVR系列單片機的燒寫和實驗。 2、實驗板端口資源 整個板子采取功能模塊化設計,也就是說每個功能模塊都是獨立,端口之間都未連接,因此做實驗時候需要學習者自己先進行硬件電路的設計與連接來搭建。詳細見實驗板原理圖和每個實驗的內容。下表為部分引腳和外圍IC的接口對照表: 2.2單片機開發軟件簡介 KeilC51軟件開發系統簡介 
單片機開發中除必要的硬件外,同樣離不開軟件,匯編語言源程序要變為CPU可以執行的機器碼有兩種方法,一種是手工匯編,另一種是機器匯編,目前已極少使用手工匯編的方法了。 單片機在發展了這么多年來,出現了各種各樣的編譯軟件,Keil C51是美國Keil Software公司出品的51系列兼容單片機C語言軟件開發系統,是目前開發51系列單片機的主流工具。與匯編相比,C語言在功能上、結構性、可讀性、可維護性上有明顯的優勢,因而易學易用。用過匯編語言后再使用C來開發,體會更加深刻。 C語言是一個通用的編程語言,它提供高效的代碼、結構化的編程和豐富的操作符。C語言不是一種大語言,不是為任何特殊應用領域而設計,它一般來說限制較少,可以為各種軟件任務提供方便和有效的編程。許多應用用C比其他語言編程更方便和有效。 優化的Cx51的C編譯器完整的實現了ANSI的C語言標準,對8051來說,Cx51不是一個通用的C編譯器,它首先的目標是生成針對8051的最快和最緊湊的代碼。Cx51具有C編程的彈性和高效的代碼和匯編語言的速度。 C語言不能執行的操作如輸入和輸出,需要操作系統的支持的一部分提供,因為這些函數和語言本身無關,所以C特別適合對多平臺提供代碼。 8051系列是增長最快的微處理器構架之一,從不同的芯片廠家提供了400多種新擴展的8051芯片,如PHILIPS的8051MX有幾M字節的代碼和數據空間大的應用中。為了支持這些不同的8051芯片,Keil提供了幾種開發工具輸出文件格式,OMF2允許支持最多16MB代碼和數據空間的PHILIPS 8051MX結構。 Keil C51軟件提供豐富的庫函數和功能強大的集成開發調試工具,全Windows界面。另外重要的一點,只要看一下編譯后生成的匯編代碼,就能體會到Keil C51生成的目標代碼效率非常之高,多數語句生成的匯編代碼很緊湊,容易理解。在開發大型軟件時更能體現高級語言的優勢。 2.3程序燒錄 程序燒錄有兩種方法: - 使用普中科技的程序下載軟件
。 - 使用STC官方軟件下載

三、系統總體方案設計 3.1電子密碼鎖功能簡介 電子密碼鎖由機械模塊、集成線路、電子元件、運行算法等多部分組成,其核心為芯片,通過程序算法下達各種指令,由其他部分配合完成密碼的設置、存貯、識別和顯示、驅動電磁執行器并檢測其驅動電流值、接收傳感器送來的報警信號、發送數據等工作。 密碼鎖的核心原理也很容易讓人理解,單片機接收用戶輸入的指令(密碼),與存貯在EEPROM中的密碼進行對比。若指令相同,則驅動電機開鎖;若指令不同,則提示錯誤和重新輸入密碼。同時芯片會記錄用戶操作的指令以及芯片做出的反應狀態,作為后續智能化分析單依據。 3.2 STC15W4K32S4系列單片機簡介 STC15W4K32S4系列單片機是 單片機是STC生產的單時鐘/機器周期(1T)的單片機,是寬電壓/高速/高可靠/低功耗/超強抗干擾的新一代8051單片機,采用STC第九代加密技術,無法解密,指令代碼完全兼容傳統8051,但速度快8-12倍。內部集成高精度R/C時鐘(±0.3%),±1%溫飄(-40℃~+85℃),常溫下溫飄±0.6%(-20℃~+65℃),ISP編程時5MHz~30MHz寬范圍可設置,可徹底省掉外部昂貴的晶振和外部復位電路(內部已集成高可靠復位電路,ISP編程時16級復位門檻電壓 可選)。8路10位PWM,8路高速10位A/D轉換(30萬次/秒),內置4K字節大容量SRAM,4組獨立 的高速異步串行通信端口(UART1/UART2/UART3/UART4),1組高速同步串行通信端口SPI, 針對多串行口通信/電機控制/強干擾場合。內置比較器,功能更強大。 現STC15系列單片機采用STC-Y5超高速CPU內核,在相同的時鐘頻率下,速度又比STC早期的1T系列單片機(如STC12系列/STC11系列/STC10系列)的速度快20%。 1.增強型 8051 CPU,1T,單時鐘/機器周期,速度比普通8051快8-12倍 2.工作電壓:2.5V - 5.5V 3.16K/32K/40K/48K/56K/58K/61K/63.5K字節片內Flash程序存儲器,擦寫次數10萬次以上 4.片內大容量4096字節的SRAM,包括常規的256字節RAM <idata> 和內部擴展的3840字節 XRAM <xdata> 5.大容量片內EEPROM,擦寫次數10萬次以上 EEPROM,擦寫次數10萬次以上,擦寫次數10萬次以上 6.ISP/IAP,在系統可編程/在應用可編程,無需編程器/仿真器 7.共8通道10位高速ADC,速度可達30萬次/秒,8路PWM還可當8路D/A使用 8.6通道15位專門的高精度PWM(帶死區控制)+2通道CCP(利用它的高速脈沖輸出功能可實現11~16位PWM)----可用來再實現8路D/A或2個16位定時器,或2個外部中斷(支持上升沿/下降沿中斷)與STC15W4K32S4系列單片機的6路增強型PWM相關的端口.上電后默認為高阻輸入,上電前用戶須在程序中將該些端口設置為其他模式(如準雙向口或強推挽模式);注意該些端口進入掉電模式時不能為高阻輸入,否則需外部加上拉電阻。
9.內部高可靠復位,ISP編程時16級復位門檻電壓可選,可徹底省掉外部復位電路 10.工作頻率范圍: 5MHz~28MHz, 相當于普通8051的60MHz~336MHz 11.內部高精度R/C時鐘(+0.3%),+1%溫飄( 40°C~+85*C),常溫下溫飄+0.6%(-20*C~+65*C) 12.不需外部晶振和外部復位,還可對外輸出時鐘和低電平復位信號 13.四組完全獨立的高速異步串行通信端口,分時切換可當9組串口使用:串口1(RxD/P3.0,TxD/P3.1)可以切換到(RxD_2/P3.6,TxD_2/P3.7),還可以切換到(RxD_3/P1.6,TxD_3/P1.7);串口2(RxD2/P1.0,TxD2/P1.1)可以切換到(RxD2_ 2/P4.6,TxD2_2/P4.7);串口3(RxD3/P0.0,TxD3/P0.1)可以切換到(RxD3_ 2/P5.0,TxD3_ 2/P5.1);串口4(RxD4/P0.2, TxD4/P0.3)可以切換到(RxD4_ 2/P5.2, TxD4_ _2/P5.3) 注意:建議用戶將串口1放在P3.6/P3.7或P1.6/ P1.7 (P3.0/P3.1作下載/仿真用);若用戶不想切換,堅持使用P3.0/P3.1或作為串口1進行通信,則務必在下載程序時,在軟件上勾選“下次冷啟動時,P3.2/P3.3為0/0時才可以下載程序”。 14.一組高速同步串行通信端口SPI. 15.支持程序加密后傳輸,防攔截 16.支持RS485下載
17.低功耗設計:低速模式,空閑模式,掉電模式/停機模式.
18.可將掉電模式/停機模式喚醒的定時器:有內部低功耗掉電喚醒專用定時器。
19.共7個定時器,5個16位可重裝載定時器/計數器(TO/T1/T2/T3/T4,其中T0/T1兼容普通8051的定時器/計數器),并均可獨立實現對外可編程時鐘輸出(5通道),另外管腳SysClkO可將系統時鐘對外分頻輸出(+1或+2或+4或+16),2路CCP還可再實現2個定時器 20.定時器/計數器2,也可實現1個16位重裝載定時器/計數器,定時器/計數器2也可產生時鐘輸出T2CLKO 單片機引腳說明 單片機的40個引腳大致可分為4類:電源、時鐘、控制和I/O引腳。
⒈ 電源:
⑴ VCC - 芯片電源,接+5V;
⑵ VSS - 接地端; ⒉ 時鐘:XTAL1、XTAL2 - 晶體振蕩電路反相輸入端和輸出端。 ⒊ 控制線:控制線共有4根,
⑴ ALE/PROG:地址鎖存允許/片內EPROM編程脈沖
① ALE功能:用來鎖存P0口送出的低8位地址
② PROG功能:片內有EPROM的芯片,在EPROM編程期間,此引腳輸入編程脈沖。
⑵ PSEN:外ROM讀選通信號。
⑶ RST/VPD:復位/備用電源。
① RST(Reset)功能:復位信號輸入端。
② VPD功能:在Vcc掉電情況下,接備用電源。
⑷ EA/Vpp:內外ROM選擇/片內EPROM編程電源。
① EA功能:內外ROM選擇端。
② Vpp功能:片內有EPROM的芯片,在EPROM編程期間,施加編程電源Vpp。 ⒋ I/O線
80C51共有4個8位并行I/O端口:P0、P1、P2、P3口,共32個引腳。P3口還具有第二功能,用于特殊信號輸入輸出和控制信號(屬控制總線)。 3.3LCD1602簡介 工業字符型液晶,能夠同時顯示16x02即32個字符。(16列2行)
1602液晶也叫1602字符型液晶,它是一種專門用來顯示字母、數字、符號等的點陣型液晶模塊。它由若干個5X7或者5X11等點陣字符位組成,每個點陣字符位都可以顯示一個字符,每位之間有一個點距的間隔,每行之間也有間隔,起到了字符間距和行間距的作用,正因為如此所以它不能很好地顯示圖形(用自定義CGRAM,顯示效果也不好)。
1602LCD是指顯示的內容為16X2,即可以顯示兩行,每行16個字符液晶模塊(顯示字符和數字)。
市面上字符液晶大多數是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780寫的控制程序可以很方便地應用于市面上大部分的字符型液晶。 1602LCD 主要技術參數: 顯示容量:16×2 個字符 芯片工作電壓:4.5—5.5V 工作電流:2.0mA(5.0V) 模塊最佳工作電壓:5.0V 字符尺寸:2.95×4.35(W×H)mm 管腳功能: 1602采用標準的16腳接口,其中:
第1腳:VSS為電源地
第2腳:VCC接5V電源正極
第3腳:V0為液晶顯示器對比度調整端,接正電源時對比度最弱,接地電源時對比度最高(對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度)。
第4腳:RS為寄存器選擇,高電平1時選擇數據寄存器、低電平0時選擇指令寄存器。
第5腳:RW為讀寫信號線,高電平(1)時進行讀操作,低電平(0)時進行寫操作。
第6腳:E(或EN)端為使能(enable)端,高電平(1)時讀取信息,負跳變時執行指令。
第7~14腳:D0~D7為8位雙向數據端。
第15~16腳:空腳或背燈電源。15腳背光正極,16腳背光負極。 特性 3.3V或5V工作電壓,對比度可調
內含復位電路
提供各種控制命令,如:清屏、字符閃爍、光標閃爍、顯示移位等多種功能
有80字節顯示數據存儲器DDRAM
內建有192個5X7點陣的字型的字符發生器CGROM
8個可由用戶自定義的5X7的字符發生器CGRAM 特征應用 微功耗、體積小、顯示內容豐富、超薄輕巧,常用在袖珍式儀表和低功耗應用系統中。 操作控制 注:關于E=H脈沖——開始時初始化E為0,然后置E為1。
字符集
1602液晶模塊內部的字符發生存儲器(CGROM)已經存儲了160個不同的點陣字符圖形,這些字符有:阿拉伯數字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有一個固定的代碼,比如大寫的英文字母“A”的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字符圖形顯示出來,我們就能看到字母“A”。
在單片機編程中還可以用字符型常量或變量賦值,如'A’。因為CGROM儲存的字符代碼與我們PC中的字符代碼是基本一致的,因此我們在向DDRAM寫C51字符代碼程序時甚至可以直接用P1=‘A’這樣的方法。PC在編譯時就把'A'先轉換為41H代碼了。
字符代碼0x00~0x0F為用戶自定義的字符圖形RAM(對于5X8點陣的字符,可以存放8組,5X10點陣的字符,存放4組),就是CGRAM了。
0x20~0x7F為標準的ASCII碼,0xA0~0xFF為日文字符和希臘文字符,其余字符碼(0x10~0x1F及0x80~0x9F)沒有定義。
以下是1602的16進制ASCII碼表地址:讀的時候,先讀左邊那列,再讀上面那行,如:感嘆號!的ASCII為0x21,字母B的ASCII為0x42(前面加0x表示十六進制)。 1602LCD 的指令說明及時序 1602 液晶模塊內部的控制器共有11條控制指令。 控制命令表 1602 液晶模塊的讀寫操作、屏幕和光標的操作都是通過指令編程來實現的。(說明:1 為高電平、0 為低電平) 指令 1:清顯示,指令碼 01H,光標復位到地址 00H 位置。 指令 2:光標復位,光標返回到地址 00H。 指令 3:光標和顯示模式設置 I/D:光標移動方向,高電平右移,低電平左移 S:屏幕上所有文字是否 左移或者右移。高電平表示有效,低電平則無效。 指令 4:顯示開關控制。 D:控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示 C:控 制光標的開與關,高電平表示有光標,低電平表示無光標 B:控制光標是否閃爍,高電平閃爍,低電 平不閃爍。 指令 5:光標或顯示移位 S/C:高電平時移動顯示的文字,低電平時移動光標。 指令 6:功能設置命令 DL:高電平時為 4 位總線,低電平時為 8 位總線 N:低電平時為單行顯示,高 電平時雙行顯示 F: 低電平時顯示 5x7 的點陣字符,高電平時顯示 5x10 的點陣字符。 指令 7:字符發生器 RAM 地址設置。 指令 8:DDRAM 地址設置。 指令 9:讀忙信號和光標地址 BF:為忙標志位,高電平表示忙,此時模塊不能接收命令或者數據,如 果為低電平表示不忙。 指令 10:寫數據。 指令 11:讀數據。 基本操作時序表 讀操作時序: 
寫操作時序: 
LCD1602的RAM地址映射 液晶顯示模塊是一個慢顯示器件,所以在執行每條指令之前一定要確認模塊的忙標志為低電平,表示 不忙,否則此指令失效。要顯示字符時要先輸入顯示字符地址,也就是告訴模塊在哪里顯示字符,圖 10-57 是 1602 的內部顯示地址。 1602 的內部顯示地址: 
例如第二行第一個字符的地址是 40H,那么是否直接寫入 40H 就可以將光標定位在第二行第一個字符 的位置呢?這樣不行,因為寫入顯示地址時要求最高位 D7 恒定為高電平 1 所以實際寫入的數據應該是 01000000B(40H)+10000000B(80H)=11000000B(C0H)。 在對液晶模塊的初始化中要先設置其顯示模式,在液晶模塊顯示字符時光標是自動右移的,無需人工 干預。每次輸入指令前都要判斷液晶模塊是否處于忙的狀態。 1602 液晶模塊內部的字符發生存儲器(CGROM)已經存儲了 160 個不同的點陣字符圖形,如圖 10-58 所示,這些字符有:阿拉伯數字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有 一個固定的代碼,比如大寫的英文字母“A”的代碼是 01000001B(41H),顯示時模塊把地址 41H 中 的點陣字符圖形顯示出來,我們就能看到字母“A”。 1602LCD 的一般初始化(復位)過程 延時 15mS 寫指令 38H(不檢測忙信號) 延時 5mS 寫指令 38H(不檢測忙信號) 延時 5mS 寫指令 38H(不檢測忙信號) 以后每次寫指令、讀/寫數據操作均需要檢測忙信號 寫指令 38H:顯示模式設置 寫指令 08H:顯示關閉 寫指令 01H:顯示清屏 寫指令 06H:顯示光標移動設置 寫指令 0CH:顯示開及光標設置 3.4矩陣鍵盤簡介 矩陣鍵盤是單片機外部設備中所使用的排布類似于矩陣的鍵盤組。矩陣式結構的鍵盤顯然比直接法要復雜一些,識別也要復雜一些,列線通過電阻接正電源,并將行線所接的單片機的I/O口作為輸出端,而列線所接的I/O口則作為輸入。矩陣鍵盤的優點是節約單片機IO口,例如普通鍵盤8個IO口只能用作8個按鍵,而矩陣鍵盤能作16個按鍵。 組成結構 在鍵盤中按鍵數量較多時,為了減少I/O口的占用,通常將按鍵排列成矩陣形式。在矩陣式鍵盤中,每條水平線和垂直線在交叉處不直接連通,而是通過一個按鍵加以連接。這樣,一個端口(如P1口)就可以構成4*4=16個按鍵,比之直接將端口線用于鍵盤多出了一倍,而且線數越多,區別越明顯,比如再多加一條線就可以構成20鍵的鍵盤,而直接用端口線則只能多出一鍵(9鍵)。由此可見,在需要的鍵數比較多時,采用矩陣法來做鍵盤是合理的。 矩陣鍵盤不僅在連接上比單獨式按鍵復雜,它的按鍵識別方法也比單獨式按鍵復雜。在矩陣鍵盤的軟件接口程序中,常使用的按鍵識別方法有行掃描法和線反轉法。這兩種方法的基本思路是采用循環查循的方法,反復查詢按鍵的狀態,因此會大量占用MCU的時間,所以較好的方式也是采用狀態機的方法來設計,盡量減少鍵盤查詢過程對MCU的占用時間。 單片機系統中,若使用按鍵較多時如電子密碼鎖、電話機鍵盤等一般都至少有12到16個按鍵,通常采用矩陣鍵盤。 矩陣鍵盤又稱行列鍵盤,它是用四條I/O線作為行線,四條I/O線作為列線組成的鍵盤。在行線和列線的每個交叉點上設置一個按鍵。這樣鍵盤上按鍵的個數就為4*4個。這種行列式鍵盤結構能有效地提高單片機系統中I/O口的利用率。 矩陣鍵盤的工作原理 最常見的鍵盤布局如圖3所示。一般由16個按鍵組成,在單片機中正好可以用一個P口實現16個按鍵功能,這也是在單片機系統中最常用的形式,4*4矩陣鍵盤的內部電路如圖。 矩陣鍵盤布局圖: 
矩陣鍵盤內部布局圖: 
當無按鍵閉合時,P3.0~P3.3與P3.4~P3.7之間開路。當有鍵閉合時,與閉合鍵相連的兩條I/O口線之間短路。判斷有無按鍵按下的方法是:第一步,置列線P3.4~P3.7為輸入狀態,從行線P3.0~P3.3輸出低電平,讀入列線數據,若某一列線為低電平,則該列線上有鍵閉合。第二步,行線輪流輸出低電平,從列線P3.4~P3.7讀入數據,若有某一列為低電平,則對應行線上有鍵按下。綜合一二兩步的結果,可確定按鍵編號。但是鍵閉合一次只能進行一次鍵功能操作,因此須等到按鍵釋放后,再進行鍵功能操作,否則按一次鍵,有可能會連續多次進行同樣的鍵操作。 行掃描法:
以4*4矩陣按鍵為例,將全部行線置低電平,然后檢測列線的狀態。只要有一列的電平為低,則表示鍵盤中有鍵被按下,而且閉合的鍵位于低電平線與4根行線相交叉的4個按鍵之中。若所有列線均為高電平,則鍵盤中無鍵按下。
判斷閉合鍵所在的位置: 在確認有鍵按下后,即可進入確定具體閉合鍵的過程。其方法是:依次將行線置為低電平,即在置某根行線為低電平時,其它線為高電平。在確定某根行線位置為低電平后,再逐行檢測各列線的電平狀態。若某列為低,則該列線與置為低電平的行線交叉處的按鍵就是閉合的按鍵。
線反轉法: Step 1:將列線作為輸出線,行線作為輸入線。置輸出線全部為0,此時行線中呈低電平0的為按鍵所在行,如果全部都不是0,則沒有按鍵按下。
Step 2:將第一步反過來,即將行線作為輸出線,列線作為輸入線。置輸出線全部為0,此時列線呈低電平的為按鍵所在的列。這樣,就可以確定了按鍵的位置(X,Y)。 鍵盤掃描方法: 鍵盤掃描方法是:行線P10~P13為輸出線,列線P14~P17為輸入線。一開始單片機將行線(P10~P13)全部輸出低電平,此時讀入列線數據,若列線全為高電平則沒有鍵按下,當列線有出現低電平時調用延時程序以此來去除按鍵抖動。延時完成后再判斷是否有低電平,如果此時讀入列線數據還是有低電平,則說明確實有鍵按下。最后一步確定鍵值。以第二行的S5鍵為例,若按下S5后該怎么得到這個鍵值呢?當判斷確實有鍵按下之后,行線輪流輸出低電平,根據讀入列線的數據可以確定鍵值。首先,單片機將P10輸出為低電平,其它P11~P13輸出高電平,此時讀取列線的數據全為高電平,說明沒有在第一行有鍵按下;其次,單片機將P11輸出低電平,其它P10、P12、P13仍為高電平,此時再來讀取列線數據,發現列線讀到的數據有低電平,數值為1011(0x0B),如果鍵盤布局已經確定,那么0x0B就代表S5的值了。轉到S5鍵功能處理子程序就可以達到目的。 四、系統軟件設計方案 4.1軟件設計思路 將整個程序分為三個部分,一個是輸入部分,一個是顯示部分,最后是密碼驗證和重置。 輸入部分由矩陣鍵盤完成,將矩陣鍵盤上的每一個鍵賦值,主要有數字鍵0-9,確認鍵,更正鍵(重新輸入密碼),以及重置鍵(設置新的密碼)。 顯示部分:在矩陣鍵盤上輸入數字時,將輸入的數字顯示在LCD液晶屏上,并且在輸入密碼、驗證密碼后顯示密碼是否正確。 密碼驗證和重置:在輸入密碼完成后,將輸入密碼和實際密碼比較。而在重置密碼時,要先確認輸入密碼是否正確。
五、系統調試 
編程運行顯示無錯誤,經過在老師面前進行實物操作,顯示該電子密碼鎖確實具有輸入,顯示,驗證,修改密碼,重置密碼等功能。
單片機源程序如下: - <font color="rgb(0, 0, 0)">#include <STC15.h>
- #include "intrins.h"
- typedef unsigned char u8;
- typedef unsigned int u16;
- u8 code KeyCodeTable[]=
- {0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,
- 0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};
- sbit FMQ=P4^2;
- sbit RS = P2^6; //數據/命令選擇控制位
- sbit RW = P2^5; //讀/寫控制位
- sbit EN = P2^7; //使能控制位
- #define DataPort P0
- u8 Keys_Scan(void);
- void Delay_500us(void);
- void Delay_nms(u16 nms);
- void Beep(void);
- void Pin_Mode(void);
- void LCD_Initial(void);
- bit LCD_Check_Busy(void);
- void LCD_Write_Command(u8 command);
- void LCD_Write_Data(u8 Data);
- void LCD_Clear(void);
- void xianshi(void); //LCD顯示函數
- void xianshiyes(void); //輸入密碼正確的顯示函數
- void xianshiwrong(void); //輸入密碼錯誤后的顯示函數
- void input(void); //輸入函數
- void CZMA(void); //重置密碼函數
- void yanzhen(void); //將輸入的密碼與正確密碼對比的驗證函數
- void fuzhi1(void); //對LCD顯示函數中的數組賦值函數
- u8 RIGHT[]="pass";
- u8 WRONG[]="Password Error";
- u8 SHURU[]="aaaaaaaaaa";
- u8 SHUZU[]="aaaaaaaaaa";
- u8 MIMA[]="000aaaaaaa";
- u16 Yanzhenshu=0;
- void main(void)
- {
- Pin_Mode();
- LCD_Initial();
- LCD_Clear();
- while(1)
- { P1=0x0f;
-
- if((P1&0x0f)!=0x0f)
- { Delay_nms(15);
- if((P1&0x0f)!=0x0f)
- { LCD_Clear();
- fuzhi1(); //先對顯示的數組進行賦值,以免出現顯示錯誤
-
- input(); //輸入密碼
- if(Keys_Scan()==12)
- LCD_Clear();
- fuzhi1();
-
- input(); //若按下重置鍵,則重新輸入
- if(Keys_Scan()==13)
- { yanzhen(); //按下確認鍵,對密碼進行驗證
- if(Yanzhenshu==0)
- {LCD_Clear();
- xianshiyes(); //密碼正確
- }
- else
- { LCD_Clear();
- fuzhi1();
- xianshiwrong(); //密碼錯誤
- }
- }
- if(Keys_Scan()==15)
- {
- LCD_Clear();
- fuzhi1();
- yanzhen(); //按下重置密碼鍵之后,先確認之前輸入的密碼是否正確
- if(Yanzhenshu==0)
- CZMA(); //正確則重置密碼
- else
- {LCD_Clear();
- xianshiwrong();
- }
- }
- P1=0xf0;
- while((P1&0xf0)!=0xf0)
- { P1=0xf0;
- Beep();
- }
- }
- }
- }
- }
- void fuzhi1(void)
- { u8 i=0;
- for(;i<10;i++)
- { SHUZU[i]='a';
- }
- }
- void yanzhen(void)
- { u8 i;
- Yanzhenshu=0;
- for(i=0;MIMA[i]!='a' && MIMA[i]!='\0';i++)
- { if(SHURU[i]!=MIMA[i] || SHURU[i+1]!=MIMA[i+1]) //驗證密碼是否正確
- {Yanzhenshu=1;
- break;
- }
- }
- }
- void xianshiyes(void)
- { u8 m;
- u8 n=0;
- for (m=0x80;m<0x90;m++)
- {
- LCD_Write_Command(m);
- if(RIGHT[n]=='\0') break;
- LCD_Write_Data(RIGHT[n]);
- n++;
- }
- }
- void xianshiwrong(void)
- { u8 m;
- u8 n=0;
- for (m=0x80;m<0x90;m++)
- {
- LCD_Write_Command(m);
- if(WRONG[n]=='\0') break;
- LCD_Write_Data(WRONG[n]);
- n++;
- }
- }
- void xianshi(void)
- { u8 m;
- u8 n=0;
- for (m=0x80;m<0x90;m++)
- {
- LCD_Write_Command(m);
- if(SHUZU[n]=='a'|| SHUZU[n]=='\0') break;
- LCD_Write_Data(SHUZU[n]);
- n++;
- }
- }
- void CZMA(void)
- { u8 i,key;
- for(i=0;i<10;)
- { P1=0xf0;
- if((P1&0xf0)!=0xf0)
- { Delay_nms(15);
- if((P1&0xf0)!=0xf0 )
- { if(Keys_Scan()!=15)
- {
- if (Keys_Scan()==13) break; //再確認要重置密碼后,把輸入的新密碼存入'SHUZU'數組中,若按下確認鍵則跳出
- key=Keys_Scan();
- SHUZU[i]=key+'0';
- xianshi();
- i++;
- }
- P1=0xf0;
- while((P1&0xf0)!=0xf0)
- { P1=0xf0;
- Beep();
- }
- }
- }
-
- }
- for(i=0;i<9;i++)
- {MIMA[i]=SHUZU[i];//將密碼存入“MIMA”數組中
- }
- LCD_Clear();
- fuzhi1();
- }
- void input(void)
- {
- u8 i=0,key;
- for(;i<10;)
- { P1=0xf0;
- if((P1&0xf0)!=0xf0)
- { Delay_nms(15);
- if((P1&0xf0)!=0xf0)
- { if (Keys_Scan()>=10) break; //確認有鍵按下后,如果按下的不是數字鍵0-9,則跳出循環
- key=Keys_Scan();
- SHURU[i]=key+'0'; //將輸入的數字轉化為字符變量存入‘SHURU’和‘SHUZU'兩個數組中
- SHUZU[i]=SHURU[i];
- SHURU[i+1]='a'; //對"SHURU"數組的下一位賦值為a,避免在驗證密碼時出錯
- xianshi(); //顯示函數
- i++;
-
- P1=0xf0;
- while((P1&0xf0)!=0xf0)
- { P1=0xf0;
- Beep();
- }
- }
- }
-
- }
-
- }
- void Delay_500us(void)
- {
- u16 t;
- for(t=0;t<540;t++);
- }
- void Delay_nms(u16 nms)
- {
- u16 i,t;
- for(i=0;i<nms;i++)
- {
- for(t=0;t<1080;t++);
- }
- }
- void Beep(void)
- {
- u8 i;
- for(i=0;i<10;i++)
- {
- Delay_500us();
- FMQ=~FMQ;
- }
- FMQ=1;
- }
- void Pin_Mode(void)
- {
- P0M1 = 0x00; P0M0 = 0x00;
- P2M1 = 0x00; P2M0 = 0x00;
- P1M1 = 0x00; P1M0 = 0x00;
- P4M1 = 0x00; P4M0 = 0x00;
- }
- u8 Keys_Scan(void)
- {
- u8 j,temp,i;
- u8 t=0xfe;
- P1=0xf0;
- if((P1&0xf0)!=0xf0)
- { Beep();
- for(i=0;i<4;i++)
- { P1=t;
- temp=P1;
- for(j=0;j<16;j++)
- { if(temp==KeyCodeTable[j]) return(j);
- }
- t=_crol_(t,1);
- }
-
- }
- return(16);
- }
- //當有鍵按下時,確認所按下的鍵并賦值
- void LCD_Initial(void)
- {
- LCD_Write_Command(0x38); //顯示模式設置
- Delay_nms(5); //16*2,5*7點陣
- LCD_Write_Command(0x38); //8位數據接口
- Delay_nms(5);
- LCD_Write_Command(0x38);
- Delay_nms(5);
- LCD_Write_Command(0x38);
- LCD_Write_Command(0x08); //顯示關閉,見手冊4.1.2
- LCD_Write_Command(0x01); //顯示清屏
- LCD_Write_Command(0x06); //顯示光標移動設置
- Delay_nms(5);
- LCD_Write_Command(0x0C); //顯示開及光標設置
- }
- bit LCD_Check_Busy(void)
- {
- DataPort = 0xFF; //將端口置為全高(輸入)
- RS = 0; //指令(狀態)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
- </font>
復制代碼
所有資料51hei提供下載:
電子密碼鎖.rar
(1.58 MB, 下載次數: 364)
2018-7-10 21:02 上傳
點擊文件名下載附件
|