單片機紅外遙控密碼鎖課程設(shè)計2_第1頁
已閱讀1頁,還剩25頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、<p><b>  1 設(shè)計目的意義</b></p><p>  隨著人們生活水平的提高,如何實現(xiàn)家庭防盜這一問題也變得尤其重要。目前國內(nèi),大部分人使用的還是傳統(tǒng)的機械鎖。傳統(tǒng)的機械鎖由于其構(gòu)造的簡單,被撬的事件屢見不鮮。即使是一把質(zhì)量過關(guān)的機械鎖,通過急開鎖,甚至可以在不損壞鎖的前提下將鎖打開。而且,在日常的生活和工作中,若使用傳統(tǒng)的機械式鑰匙開鎖,人們常需攜帶多把鑰匙,使用極不

2、方便,且鑰匙丟失后安全性即大打折扣。為此,本系統(tǒng)試著設(shè)計具有防盜報警功能的紅外線遙控電子密碼鎖來代替?zhèn)鹘y(tǒng)的機械式密碼鎖,克服了機械式密碼鎖密碼量少、安全性能差的缺點。而且還添加了紅外遙控、遙控器學(xué)習(xí)識別和LCD顯示等功能,可以實現(xiàn)遠(yuǎn)距離開關(guān)鎖、修改密碼等,系統(tǒng)靈活性強,操作簡單直觀、使用非常方便。由于這是一次學(xué)生的實習(xí)項目,本產(chǎn)品未必能盡善盡美,但基本的要求還是可以滿足。</p><p>  2 在線編程電路和實

3、物圖</p><p>  2.1在線編程電路(詳見附錄1)</p><p><b>  2.2實物圖</b></p><p><b>  圖1 實物圖</b></p><p><b>  3 設(shè)計方案</b></p><p>  3.1 發(fā)射模塊的方案&

4、lt;/p><p>  使用NEC編碼格式紅外線遙控編碼芯片uPD6122G等作為主芯片再加上外圍電路完成發(fā)射部分,或直接購買紅外線遙控編碼芯片的遙控器成品作為系統(tǒng)的發(fā)射部分。因為是紅外線遙控編碼專用芯片,其內(nèi)部已經(jīng)集成了按鍵檢測、處理和紅外編碼模塊。而且無須編程,使用十分方便。故市面上的絕大多數(shù)的紅外遙控器都是使用類似的方案,可見這方面的技術(shù)已經(jīng)相當(dāng)成熟。在抗干擾能力上,因為沒有涉及到軟件,故其抗干擾能力強。<

5、;/p><p>  3.2 接收模塊的方案</p><p>  發(fā)射模塊使用型號為HZ-FT007的20鍵車載MP3紅外遙控器和創(chuàng)維RC-585型DVD遙控器,因為它們都是采用NEC編碼格式的紅外遙控芯片作為主要芯片;使用一體化紅外接收頭SM0038和單片機STC89C52RC結(jié)合的方式完成接收解碼模塊,學(xué)習(xí)識別NEC編碼格式的不同遙控器;使用單片機內(nèi)部eeprom作為存儲模塊;使用LCD16

6、02A實現(xiàn)系統(tǒng)的顯示模塊。系統(tǒng)的總框圖如圖3所示。這樣的選擇使系統(tǒng)在較低成本的情況下較好地實現(xiàn)系統(tǒng)的功能,而且系統(tǒng)有著較高的抗干擾性和穩(wěn)定性。</p><p>  圖2 選用方案系統(tǒng)框圖</p><p><b>  4硬件分析及設(shè)計</b></p><p>  4.1 發(fā)射模塊原理</p><p>  4.1.1紅外發(fā)送

7、系統(tǒng)原理</p><p>  紅外遙控信號是一連串的二進制脈沖碼。為了使其在無線傳輸過程中免受其他紅外信號的干擾,通常都是先將其調(diào)制在特定的載波頻率上,然后再經(jīng)紅外發(fā)光二極管發(fā)射出去,紅外線接收裝置則會濾除其它雜波只接收該特定頻率的信號并將其還原成二進制脈沖碼。在本紅外遙控系統(tǒng)中,紅外信號的載波頻率為38KHz。</p><p>  通常,紅外遙控系統(tǒng)中所采用的編碼方式有兩種:通過脈沖寬度

8、來實現(xiàn)信號調(diào)制的脈寬調(diào)制(PWM)和通過脈沖串之間的時間間隔來實現(xiàn)信號調(diào)制的脈時調(diào)制(PPM)。本系統(tǒng)是采用PPM方法,即用兩個脈沖之間的時間間隔來表示二進制信息。</p><p>  為了確保發(fā)送端和接收端之間數(shù)據(jù)傳輸?shù)臏?zhǔn)確無誤,紅外線信號還要按照特定的傳輸協(xié)議來進行信號傳輸。常用的紅外線信號傳輸協(xié)議有NEC協(xié)議、RC-5協(xié)議、RC-6協(xié)議、Sharp協(xié)議等。</p><p>  4.1

9、.2 NEC編碼格式介紹</p><p>  本系統(tǒng)使用的型號為HZ-FT007的20鍵車載MP3紅外遙控器和創(chuàng)維RC-585型DVD遙控器請參看前面的實物圖,它們主要芯片都是NEC編碼格式的紅外遙控芯片。NEC編碼廣泛應(yīng)用于電視機,DVD,PC電腦,音響等,是比較常用的一種紅外編碼格式。</p><p>  下面以NEC編碼標(biāo)準(zhǔn)的紅外編碼芯片uPD6122G作為例子介紹。NEC遙控編碼是

10、連續(xù)的32位二進制碼組,其中的前十六位是用戶碼,后16位為8位的數(shù)據(jù)碼及其反碼。在每次編碼之前還會發(fā)送9ms高電平和4.5ms低電平組成的引導(dǎo)碼(或稱起始碼)。而且第二段的用戶碼也可以在遙控應(yīng)用電路中被設(shè)置為第一段用戶碼的反碼。它的幀結(jié)構(gòu)如下圖所示。</p><p><b>  圖3 幀結(jié)構(gòu)</b></p><p>  NEC編碼標(biāo)準(zhǔn)是以用不同脈沖的時間間隔來區(qū)分‘0

11、’和‘1’的,uPD6122G以脈寬為0.56ms、間隔0.565ms、周期為1.125ms的組合表示二進制的‘0’;以脈寬為0.56ms、間隔1.69ms,周期為2.25ms的組合表示二進制的‘1’。其波形如下圖所示。</p><p><b>  圖4 脈沖波形圖</b></p><p>  使用455KHz晶振時各代碼所占的時間如下圖所示:</p>

12、<p>  圖5 晶振時各代碼所占時間</p><p>  uPD6122G按鍵輸出有兩種方式:一種是每次按鍵都輸出完整的一幀數(shù)據(jù);另一種是按下按鍵不松開時,發(fā)送完整的一幀數(shù)據(jù)后再發(fā)送重復(fù)碼,直到按鍵被松開。其波形如下圖所示。</p><p><b>  圖6 按鍵輸出波形</b></p><p><b>  4.2接收模塊

13、原理</b></p><p>  4.2.1接收解碼原理</p><p>  接收解碼的關(guān)鍵是如何識別‘0’和‘1’,本系統(tǒng)使用的是一體化紅外接收頭進行紅外信號接收,在沒有信號的時候其輸出端是高電平,而有信號的時候是低電平,所以其輸出信號電平正好和遙控發(fā)射端相反。從上面的討論可以發(fā)現(xiàn)在遙控發(fā)射端‘0’和‘1’均以0.56ms的高電平開始,不同的是低電平的寬度,‘0’為0.565

14、ms,‘1’為1.69ms,所以必須根據(jù)低電平的寬度區(qū)別‘0’和‘1’。本系統(tǒng)用中斷的方式實現(xiàn)從接收頭到MCU的信號傳輸。如圖9所示,紅外接收頭的輸出端連接到單片機的INT0腳。接收頭輸出端有低電平信號輸出時引起單片機的中斷。單片機響應(yīng)中斷并進行信號的接收解碼。解碼后的信號就變成相應(yīng)的遙控器按鍵代碼,從而可以成為密碼鎖的密碼。</p><p>  圖7 中斷接收示意圖</p><p>  

15、4.2.2該模塊的硬件電路</p><p>  接收解碼電路由一體化紅外接收頭SM0038和單片機STC89C52RC組成。 </p><p>  STC系列單片機具有在系統(tǒng)中直接可編程特性,其好處是:省去購買通用編程器,單片機在用戶系統(tǒng)上即可下載/燒錄用戶程序,而無須將單片機從已生產(chǎn)好的產(chǎn)品上拆下,再用通用編程器將程序代碼燒錄進單片機內(nèi)部。有些程序尚未定型的產(chǎn)品可以一邊生產(chǎn),一邊完善,加

16、快了產(chǎn)品進入市場的速度,減小了新產(chǎn)品由于軟件缺陷帶來的風(fēng)險。由于可以在用戶的目標(biāo)系統(tǒng)上將程序直接下載進單片機看運行結(jié)果對錯,故無須仿真器,因此選擇使用這款單片機。</p><p>  一體化紅外接收頭SM0038是集信號放大、濾波、檢波、整形于一體的紅外接收器,電路內(nèi)置PIN二極管和前置放大器,采用可以紅外濾波的環(huán)氧樹脂材料封裝,可靠性高,不易受環(huán)境影響并可以防止非控制信號的輸出脈沖出現(xiàn)。它的內(nèi)部電路如圖10所示

17、。</p><p>  圖8 SM0038內(nèi)部結(jié)構(gòu)圖</p><p>  SM0038內(nèi)置帶通濾波器、積分器、和自動增益控制電路以抑制各種干擾和噪音。數(shù)據(jù)信號和干擾信號的主要區(qū)別在于載波頻率、脈沖波長和工作周期上。所以數(shù)據(jù)信號應(yīng)該滿足載波信號的頻率盡量接近帶通濾波器的中心頻率(38KHZ);脈沖長度在300us以上;數(shù)據(jù)的編碼類型相兼容。而本系統(tǒng)選用的SM0038在這三方面和NEC編碼格式

18、是相配的。</p><p>  4.3 存儲模塊原理</p><p>  STC89C51、52內(nèi)部都自帶有2K字節(jié)的EEPROM,54、55和58都自帶有16K字節(jié)的EEPROM,STC單片機是利用IAP技術(shù)實現(xiàn)的EEPROM,內(nèi)部Flash擦寫次數(shù)可達100,000 次以上,先來介紹下ISP與IAP的區(qū)別和特點。</p><p>  STC單片機內(nèi)部有幾個專門的

19、特殊功能寄存器負(fù)責(zé)管理ISP/IAP功能的,見表1。</p><p>  表1 ISP/IAP相關(guān)寄存器列表</p><p>  ISP_DATA:ISP/IAP操作時的數(shù)據(jù)寄存器。</p><p>  ISP/IAP從Flash讀出的數(shù)據(jù)放在此處,向Flash寫入的數(shù)據(jù)也需放在此處。</p><p>  ISP_ADDRH:ISP/IAP操

20、作時的地址寄存器高八位。</p><p>  ISP_ADDRL:ISP/IAP操作時的地址寄存器低八位。</p><p>  ISP_CMD:ISP/IAP操作時的命令模式寄存器,須命令觸發(fā)寄存器觸發(fā)方可生效。命令模式如表2所示。</p><p>  表2 ISP_CMD寄存器模式設(shè)置</p><p>  程序在系統(tǒng)ISP程序區(qū)時可以對用戶

21、應(yīng)用程序區(qū)/數(shù)據(jù)Flash區(qū)(EEPROM)進行字節(jié)讀/字節(jié)編程/扇區(qū)擦除;程序在用戶應(yīng)用程序區(qū)時,僅可以對數(shù)據(jù)Flash區(qū)(EEPROM)進行字節(jié)讀/字節(jié)編程/扇區(qū)擦除。STC89C51RC/RD+系列單片機出廠時已經(jīng)固化有ISP引導(dǎo)碼,并設(shè)置為上電復(fù)位進入ISP程序區(qū),并且出廠時就已完全加密。</p><p>  ISP_TRIG:ISP/IAP操作時的命令觸發(fā)寄存器。</p><p>

22、;  在ISPEN(ISP_CONTR.7) =1時,對ISP_TRIG 先寫入46h,再寫入B9h,ISP/IAP命令才會生效。</p><p>  STC89C52RC,STC89LE52RC單片機內(nèi)部可用Data Flash(EEPROM)的地址如表3所示,其它型號單片機請查閱相關(guān)資料。</p><p>  表3 STC89C52RC、STC89LE52RC單片機內(nèi)部EEPROM地址

23、表</p><p>  每個扇區(qū)為512字節(jié),建議大家在寫程序時,將同一次修改的數(shù)據(jù)放在同一個扇區(qū), 方便修改,因為在執(zhí)行擦除命令時,一次最少要擦除一個扇區(qū)的數(shù)據(jù),每次在更新數(shù)據(jù)前都必須要擦除原數(shù)據(jù)方可重新寫入新數(shù)據(jù),不能直接在原來數(shù)據(jù)基礎(chǔ)上更新內(nèi)容。</p><p>  4.4 液晶顯示模塊原理</p><p>  系統(tǒng)中采用LCD1602作為顯示器件輸

24、出信息。與傳統(tǒng)的LED數(shù)碼管顯示器件相比,液晶顯示模塊具有體積小、功耗低、顯示內(nèi)容豐富等優(yōu)點,而且不需要外加驅(qū)動電路,現(xiàn)在液晶顯示模塊已經(jīng)是單片機應(yīng)用設(shè)計中最常用的顯示器件了。LCD1602可以顯示2行×16個字符,具有8位數(shù)據(jù)總線D0-D7,和RS、R/W、E三個控制端口,工作電壓為5V,并且?guī)в凶址麑Ρ榷日{(diào)節(jié)和背光設(shè)置。LCD1602與單片機的連接電路圖參考附錄1。</p><p>  其管腳功能簡

25、介如下:</p><p>  VL:LCD對比度調(diào)節(jié)端,電壓調(diào)節(jié)范圍為0-5V。接正電源時對比度最弱,接地電源時對比度最高,可以用一個10K的電位器來調(diào)整對比度;</p><p>  RS:數(shù)據(jù)或者指令選擇端。處理器寫入指令時,RS為低電平,寫入數(shù)據(jù)時,RS為高電平;</p><p>  R/W:讀寫控制端。R/W為高電平時,讀取數(shù)據(jù);R/W為低電平時,寫入數(shù)據(jù);&

26、lt;/p><p>  E:LCD模塊使能信號控制端。寫數(shù)據(jù)時,需要下降沿觸發(fā)模塊;</p><p>  D0-D7:8位數(shù)據(jù)總線,三態(tài)雙向;</p><p>  BLA: LED背光正極。需要背光時,BLA串接一個限流電阻接VCC;</p><p>  BLK: LED背光負(fù)極。</p><p><b>  5

27、軟件設(shè)計</b></p><p><b>  5.1 編程語言</b></p><p>  目前,對單片機的編程主要采用匯編和C語言。匯編語言有執(zhí)行效率高、速度快、與硬件結(jié)合緊密等特點。尤其在進行I/O端口管理時,使用匯編語言有快捷、直觀的優(yōu)點。但是使用匯編語言相對于使用高級語言編程難度要大一些,且程序可讀性低,開放性差,從系統(tǒng)開發(fā)時間來看,效率不是很高。

28、</p><p>  C語言是一種結(jié)構(gòu)化語言,可產(chǎn)生緊湊代碼。C語言可以用許多機器級函數(shù)直接控制操作8051硬件。與匯編語言相比,C語言有如下的優(yōu)點:</p><p>  不要求了解單片機的指令系統(tǒng),僅要求對8051的存儲結(jié)構(gòu)有初步了解;</p><p>  寄存器分配,不同存儲器的尋址及數(shù)據(jù)類型等細(xì)節(jié)可由編譯器管理;</p><p>  程

29、序有規(guī)范的結(jié)構(gòu),可分為不同的函數(shù),這種方式可使程序結(jié)構(gòu)化;</p><p>  具有將可變的選擇與特殊操作組合在一起的能力,改善了程序的可讀性;</p><p>  關(guān)鍵字及運算符可用近似人的思維方式使用;</p><p>  編程及程序調(diào)試時間顯著縮短,從而提高效率;</p><p>  提供的庫包含許多標(biāo)準(zhǔn)子程序,具有較強的數(shù)據(jù)處理能力;

30、</p><p>  已編好的程序可容易地植入新程序,因為它具有方便的模塊化編程技術(shù)。</p><p>  當(dāng)然,采用混編模式,就能結(jié)合兩者的優(yōu)點。本著學(xué)習(xí)的目的,本系統(tǒng)均采用C51語言編寫。</p><p>  5.2 主要程序說明及流程圖</p><p>  本系統(tǒng)的軟件程序主要包括主程序、接收解碼程序、密碼判斷和報警程序、密碼修改程序、

31、遙控器學(xué)習(xí)識別程序幾個大的模塊程序。</p><p><b>  5.2.1主程序</b></p><p>  主程序首先是初始化程序,然后就等待紅外接收頭輸出端的低電平,低電平出現(xiàn)說明遙控有鍵按下,外部中斷設(shè)定為下降沿觸發(fā),故單片機進入中斷服務(wù)程序進行信號的接收解碼。當(dāng)接收到遙控器識別按鍵時,單片機查找AT24C02并判斷此遙控器ID是否已存在。當(dāng)ID不存在時,系統(tǒng)

32、進入遙控器學(xué)習(xí)模式,保存新ID及其鍵碼;當(dāng)遙控器ID已存在時,系統(tǒng)進入密碼輸入界面,并且接收到八位的密碼以后就開始運行密碼核對程序,當(dāng)密碼輸入正確后,就可以進行開鎖、上鎖或修改密碼的操作。當(dāng)密碼輸入錯誤的時候就會進入密碼輸入提醒程序提醒用戶重新輸入密碼,密碼輸入累積到3次時系統(tǒng)會報警并鎖定。</p><p><b>  圖9主程序流程圖</b></p><p>  5

33、.2.2接收解碼程序</p><p>  紅外接收解碼的關(guān)鍵是如何識別‘0’和‘1’碼,我的做法是根據(jù)‘0’和‘1’碼的高電平寬度不一樣的特點來進行識別。接收程序的流程圖如圖10所示。</p><p>  進入紅外接收程序后先關(guān)閉中斷。接著的工作是避開9ms高電平、4.5ms的低電平的引導(dǎo)碼,并且判斷是否干擾信號或者重復(fù)信號。正如前面所說,一體化紅外接收頭的輸出端電平跟遙控發(fā)射端電平相反。

34、如圖14所示。</p><p>  所以只要遙控有鍵按下單片機就會馬上產(chǎn)生中斷接收數(shù)據(jù)。跟在引導(dǎo)碼后面的是32位用戶碼和數(shù)據(jù)碼,也就是我們想要的數(shù)據(jù),單片機把它接收并保存。當(dāng)接收完8位的數(shù)據(jù)時要更換另外一個數(shù)據(jù)緩沖區(qū),當(dāng)32位的鍵碼都接收完的時候就意味這一幀的數(shù)據(jù)已經(jīng)接收完畢。然后根據(jù)接收到的數(shù)據(jù)碼和數(shù)據(jù)反碼是否對應(yīng)位相反來確定接收的這一幀數(shù)據(jù)是否正確,最后退出接收解碼程序。</p><p&g

35、t;  圖10 接收頭前導(dǎo)碼信號變相圖</p><p>  而單片機的接收端的‘0’‘1’波形圖如圖15所示。在保存‘0’碼和‘1’碼的時候還有一個保存時機的問題,如果從0.56ms低電平過后開始延時,0.56ms以后若讀到為低電平,說明該位為‘0’,反之則為‘1’。為安全起見,延時必須比0.56ms長一些,但又不能超過1.12ms,否則如果該位為‘0’讀到的已是下一位的高電平,因此取( 1.12ms + 0.5

36、6ms )/2=0.84ms 較為可靠,一般取0.84ms左右均可。</p><p>  圖11 單片機接收端的‘0’‘1’波形圖</p><p><b>  接收解碼中斷程序:</b></p><p>  void IR_IN() interrupt 0 using 0</p><p><b>  {<

37、/b></p><p>  unsigned char j,k,N=0;</p><p>  EX0 = 0; </p><p>  delay(15);</p><p>  if (IRIN==1) </p><p><b>  { EX0 =1;</b></p><

38、;p><b>  return;</b></p><p>  } //確認(rèn)IR信號出現(xiàn)</p><p>  while (!IRIN) //等IR變?yōu)楦唠娖?,跳過9ms的前導(dǎo)低電平信號。</p><p>  {delay(1);}</p><p>  for (

39、j=0;j<4;j++) //收集四組數(shù)據(jù)</p><p><b>  { </b></p><p>  for (k=0;k<8;k++) //每組數(shù)據(jù)有8位</p><p><b>  {</b></p><p>  while (IRIN) /

40、/等 IR 變?yōu)榈碗娖?,跳過4.5ms的前導(dǎo)高電平信號。</p><p>  {delay(1);}</p><p>  while (!IRIN) //等 IR 變?yōu)楦唠娖?lt;/p><p>  {delay(1);}</p><p>  while (IRIN) //計算IR高電平時長</p>

41、;<p><b>  {</b></p><p><b>  delay(1);</b></p><p>  N++; </p><p>  if (N>=30)</p><p><b>  { EX0=1;</b></p>

42、<p>  return;} //0.14ms計數(shù)過長自動離開。</p><p>  } //高電平計數(shù)完畢 </p><p>  IRCOM[j]=IRCOM[j] >> 1; //數(shù)據(jù)最高位補“0”</p>

43、<p>  if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //數(shù)據(jù)最高位補“1”</p><p><b>  N=0;</b></p><p>  } //end for k</p><p>  } //end for j</p><p>  if (I

44、RCOM[2]!=~IRCOM[3])</p><p><b>  { EX0=1;</b></p><p><b>  return; }</b></p><p>  IRCOM[5]=IRCOM[2] & 0x0F; //取鍵碼的低四位</p><p>  IRCOM[6]=IR

45、COM[2] >> 4; //右移4次,高四位變?yōu)榈退奈?lt;/p><p>  if(IRCOM[5]>9)</p><p>  { IRCOM[5]=IRCOM[5]+0x37;}</p><p><b>  else</b></p><p>  IRCOM[5]=IRCOM[5]+0x30

46、;</p><p>  if(IRCOM[6]>9)</p><p>  { IRCOM[6]=IRCOM[6]+0x37;}</p><p><b>  else</b></p><p>  IRCOM[6]=IRCOM[6]+0x30;</p><p><b>  LED3=0

47、;</b></p><p><b>  beep();</b></p><p><b>  LED3=1;</b></p><p>  ir_data=IRCOM[2];</p><p>  ir_flag=1; //信號接收成功標(biāo)志位</p><p>&

48、lt;b>  EX0 = 1; </b></p><p><b>  } </b></p><p>  5.2.3密碼判斷、報警及修改程序</p><p>  電子密碼鎖的軟件編程主要分為兩方面,分別是接收密碼后判斷及報警部分和密碼修改控制部分。</p><p>  首先介紹密碼判斷及報警程序。顯示收到

49、的鍵碼并保存到接收緩存receive_code[8],直到8位鍵碼接收完畢。然后和原密碼緩存origin_code[8]比較,判斷密碼是否正確。若密碼正確則將標(biāo)志位code_right=1;若不正確則報警并使密碼輸入錯誤次數(shù)wrong_num++,再判斷錯誤次數(shù)是否已達3次,若是則程序進入死循環(huán)鎖定。程序流程圖所示。</p><p>  圖12 密碼判斷、報警大致程序流程</p><p>

50、  接著介紹密碼修改控制程序。當(dāng)密碼輸入正確以后用戶按下“密碼修改鍵”就會進入密碼修改操作,單片機也就會運行密碼修改程序。</p><p>  圖13 密碼修改流程圖</p><p>  進入密碼修改程序首先等待新密碼的第一次輸入。第一次輸入的新密碼放在接收緩存receive_code[8]中,當(dāng)輸入完第八個密碼后系統(tǒng)會提示再次輸入密碼,第二次輸入的新密碼放在密碼比較緩存com_code[

51、8]中。第二次輸入密碼完成后就檢驗兩次輸入的新密碼是否相同,如果相同的話就更換密碼,將新密碼儲存到芯片的eeprom中。</p><p>  Eeprom存儲子程序:</p><p>  /* ================ 打開 ISP,IAP 功能 ================= */</p><p>  void ISP_IAP_enable(void)

52、</p><p><b>  {</b></p><p>  EA = 0; /* 關(guān)中斷 */</p><p>  ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */</p><p>  ISP_CONTR = ISP_CONTR | Wait

53、Time; /* 寫入硬件延時 */</p><p>  ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */</p><p><b>  }</b></p><p>  /* =============== 關(guān)閉 ISP,IAP 功能 ================== */</p>

54、;<p>  void ISP_IAP_disable(void)</p><p><b>  {</b></p><p>  ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */</p><p>  ISP_TRIG = 0x00;</p><p>  EA

55、 = 1; /* 開中斷 */</p><p><b>  }</b></p><p>  /* ================ 公用的觸發(fā)代碼 ==================== */</p><p>  void ISPgoon(void)</p><p><b>  {</b>

56、;</p><p>  ISP_IAP_enable(); /* 打開 ISP,IAP 功能 */</p><p>  ISP_TRIG = 0x46; /* 觸發(fā)ISP_IAP命令字節(jié)1 */</p><p>  ISP_TRIG = 0xb9; /* 觸發(fā)ISP_IAP命令字節(jié)2 */</p><p><b>  _no

57、p_();</b></p><p><b>  }</b></p><p>  /* ==================== 字節(jié)讀 ======================== */</p><p>  unsigned char byte_read(unsigned int byte_addr)</p>&l

58、t;p><b>  {</b></p><p>  ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址賦值 */</p><p>  ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);</p><p>  ISP_CMD

59、= ISP_CMD & 0xf8; /* 清除低3位 */</p><p>  ISP_CMD = ISP_CMD | RdCommand; /* 寫入讀命令 */</p><p>  ISPgoon(); /* 觸發(fā)執(zhí)行 */</p><p>  ISP_IAP_disable(); /* 關(guān)閉ISP,IAP功能 */<

60、/p><p>  return (ISP_DATA); /* 返回讀到的數(shù)據(jù) */</p><p><b>  }</b></p><p>  /* ================== 扇區(qū)擦除 ======================== */</p><p>  void SectorErase(unsign

61、ed int sector_addr)</p><p><b>  {</b></p><p>  unsigned int iSectorAddr;</p><p>  iSectorAddr = (sector_addr & 0xfe00); /* 取扇區(qū)地址 */</p><p>  ISP_ADDRH =

62、 (unsigned char)(iSectorAddr >> 8);</p><p>  ISP_ADDRL = 0x00;</p><p>  ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */</p><p>  ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */<

63、;/p><p>  ISPgoon(); /* 觸發(fā)執(zhí)行 */</p><p>  ISP_IAP_disable(); /* 關(guān)閉ISP,IAP功能 */</p><p><b>  }</b></p><p>  /* ==================== 字節(jié)寫 ================

64、======== */</p><p>  void byte_write(unsigned int byte_addr, unsigned char original_data)</p><p><b>  {</b></p><p>  ISP_ADDRH = (unsigned char)(byte_addr >> 8);

65、/* 取地址 */</p><p>  ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);</p><p>  ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */</p><p>  ISP_CMD = ISP_CMD | PrgCommand; /* 寫命令2 */&

66、lt;/p><p>  ISP_DATA = original_data; /* 寫入數(shù)據(jù)準(zhǔn)備 */</p><p>  ISPgoon(); /* 觸發(fā)執(zhí)行 */</p><p>  ISP_IAP_disable(); /* 關(guān)閉IAP功能 */</p><p><b>  }</b></

67、p><p><b>  5.2.4主函數(shù)</b></p><p>  void main() //主函數(shù)</p><p><b>  {</b></p><p>  uchar m,a,b=0,c=0,e,f,k,i=0,j=0,wrong_num=0;</p><p>

68、  uchar code_right=0;</p><p>  uchar new1_code,new2_code;</p><p>  uchar receive_code[8],com_code[8];</p><p>  uint addr;</p><p>  IE = 0x81; //允許總中斷中斷,

69、使能 INT0 外部中斷</p><p>  TCON = 0x01; //觸發(fā)方式為脈沖負(fù)邊沿觸發(fā)</p><p>  IRIN=1; //I/O口初始化</p><p>  BEEP=1; //蜂鳴器初始化</p><p>  if(byte_read(0x2

70、200)==0x11) //初始密碼讀取</p><p><b>  {</b></p><p>  origin_code[0]=byte_read(0x2000);</p><p>  origin_code[1]=byte_read(0x2001);</p><p>  origin_code[2]=byt

71、e_read(0x2002);</p><p>  origin_code[3]=byte_read(0x2003);</p><p>  origin_code[4]=byte_read(0x2004);</p><p>  origin_code[5]=byte_read(0x2005);</p><p><b>  }

72、</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  SectorErase(0x2000);</p><p>  byte_write(0x2000,0x0C);</p><p>  byte_wri

73、te(0x2001,0x18);</p><p>  byte_write(0x2002,0x5E);</p><p>  byte_write(0x2003,0x08);</p><p>  byte_write(0x2004,0x1C);</p><p>  byte_write(0x2005,0x5A);</p><

74、p>  origin_code[0]=0x0C;</p><p>  origin_code[1]=0x18;</p><p>  origin_code[2]=0x5E;</p><p>  origin_code[3]=0x08;</p><p>  origin_code[4]=0x1C;</p><p>

75、  origin_code[5]=0x5A;</p><p><b>  }</b></p><p>  delay1(10); //延時</p><p>  lcd_init(); //初始化LCD </p><p>  delay1(10);

76、 //延時</p><p>  lcd_init(); </p><p>  delay1(10);</p><p>  EX0=0;//關(guān)中斷</p><p>  lcd_wcmd(0x01); </p><p>  lcd_pos(0); //設(shè)

77、置顯示位置為第一行的第1個字符</p><p>  for(m=0;m<16;m++)</p><p><b>  {</b></p><p>  lcd_wdat(welc[m]);</p><p>  delay1(10); //字符顯示延時</p><p><b>

78、  }</b></p><p>  lcd_pos(0x40); //設(shè)置顯示位置為第二行的第1個字符</p><p>  for(m=0;m<16;m++)</p><p><b>  { </b></p><p>  lcd_wdat(cdis2[m]);</p

79、><p>  delay1(10);</p><p><b>  }</b></p><p>  EX0=1; //開中斷</p><p>  delay1(500);</p><p><b>  beep();</b></p><p>

80、  lcd_wcmd(0x01); //密碼輸入</p><p>  delay1(10);</p><p>  lcd_pos(0);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(ent_sign[m]);</p><p>  ir_flag=0;&l

81、t;/p><p>  for(;;) //密碼接收、確認(rèn)、顯示</p><p><b>  { </b></p><p>  if(ir_flag==0) continue;</p><p>  ir_flag=0;</p><p>  //按鍵屏蔽if(ir_data==

82、num_1||ir_data==num_2||ir_data==num_3||ir_data==num_4||ir_data==num_5||ir_data==num_6||ir_data==num_7||ir_data==num_8||ir_data==num_9||ir_data==num_0)</p><p>  { if(code_right==1) continue;</p><

83、;p>  receive_code[i]=ir_data; //按下一個鍵,顯示一個星號</p><p>  lcd_pos(0x40+j);</p><p><b>  j++;</b></p><p>  lcd_wdat(codestar[i]);</p><p><b>  i++;<

84、/b></p><p>  ir_data=0;</p><p><b>  }</b></p><p>  if(ir_data==num_voldec) //密碼輸入修改鍵</p><p><b>  {</b></p><p><b>  i--;

85、</b></p><p>  if(i<0) i=0;</p><p><b>  j--;</b></p><p>  if(j<0) j=0;</p><p>  lcd_pos(0x40+j); </p><p>  lcd_wdat(ent_empty[0]);&

86、lt;/p><p><b>  } </b></p><p><b>  if(i>0)</b></p><p><b>  { </b></p><p>  if(ir_data==num_play) // 密碼輸入完畢確認(rèn)鍵 play</p>&l

87、t;p><b>  { </b></p><p><b>  a=0;</b></p><p>  if(i<6||i>6) a=1; //判斷密碼是否為六位數(shù)</p><p>  while(i--)</p><p><b>  {</b>&

88、lt;/p><p>  if(origin_code[i]!=receive_code[i])//與原密碼比較</p><p><b>  a++;</b></p><p><b>  } </b></p><p>  if(a>0) wrong_num++; </p>&l

89、t;p><b>  for(;;)</b></p><p><b>  {</b></p><p>  if(wrong_num==1&&b==0&&c==0) //第一次輸入錯誤顯示</p><p>  { lcd_wcmd(0x01);</p><p

90、>  lcd_pos(0);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(wrong_code1[m]);</p><p>  lcd_pos(0x40); </p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat

91、(ent_aga[m]);</p><p><b>  LED1=0;</b></p><p><b>  beep();</b></p><p><b>  EX0=0;</b></p><p>  delay1(1000);</p><p><

92、b>  EX0=1;</b></p><p>  lcd_wcmd(0x01);</p><p>  lcd_pos(0);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(ent_sign[m]);</p><p><b>  i=0;&

93、lt;/b></p><p><b>  j=0;</b></p><p><b>  b=1;</b></p><p>  lcd_pos(0x40);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(ent_emp

94、ty[m]);</p><p><b>  break;</b></p><p><b>  }</b></p><p>  else if(wrong_num==2&&b==1&&c==0)//第二次密碼輸入錯誤顯示</p><p>  {lcd_wcmd(0

95、x01);</p><p>  lcd_pos(0);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(wrong_code2[m]);</p><p>  lcd_pos(0x40); </p><p>  for(m=0;m<16;m++)</p>

96、;<p>  lcd_wdat(ent_aga[m]);</p><p><b>  LED2=0;</b></p><p><b>  beep();</b></p><p>  delay1(20);</p><p><b>  beep(); </b>&l

97、t;/p><p><b>  EX0=0;</b></p><p>  delay1(1000);</p><p><b>  EX0=1;</b></p><p>  lcd_wcmd(0x01);</p><p>  lcd_pos(0);</p><p&

98、gt;  for(m=0;m<16;m++)</p><p>  lcd_wdat(ent_sign[m]);</p><p><b>  i=0;</b></p><p><b>  j=0;</b></p><p><b>  c=1;</b></p>

99、<p>  lcd_pos(0x40);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(ent_empty[m]);</p><p><b>  break;</b></p><p><b>  }</b></p><

100、;p>  else if(wrong_num==3&&b==1&&c==1) //第三次密碼輸入錯誤顯示、鎖定</p><p>  {lcd_wcmd(0x01);</p><p>  lcd_pos(0);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_

101、wdat(wrong_code3[m]);</p><p>  lcd_pos(0x40); </p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(lock_[m]);</p><p><b>  LED3=0;</b></p><p><b&

102、gt;  BEEP=0;</b></p><p><b>  EX0=0;</b></p><p>  while(1);</p><p>  } //3次錯誤進入死循環(huán)鎖定</p><p>  else //密碼正確,開鎖成功</p><p><b>  

103、{</b></p><p>  lcd_wcmd(0x01);</p><p>  lcd_pos(0);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(succ[m]); </p><p>  lcd_pos(0x40); </p>&

104、lt;p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(ent_agao[m]); </p><p><b>  i=0; </b></p><p><b>  j=0; </b></p><p><b>  b=0;</b>&l

105、t;/p><p>  c=0; </p><p>  code_right=1; //密碼正確標(biāo)識位 </p><p>  ir_flag=0;</p><p>  for(;ir_flag==0;); </p><p><b>  }<

106、/b></p><p>  if(code_right==1) break;</p><p><b>  } </b></p><p><b>  }</b></p><p><b>  }</b></p><p>  if(ir_data=

107、=num_eq&&code_right==1) break; //進入修改密碼鍵 eq</p><p><b>  }</b></p><p>  for(;;) </p><p><b>  { </b></p><p>  lcd_wcmd(0x01);&

108、lt;/p><p>  lcd_pos(0);</p><p>  ir_flag=0;</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(new_code0[m]);</p><p><b>  for(;;)</b></p><

109、p><b>  { </b></p><p>  if(ir_flag==0) continue;</p><p>  //按鍵屏蔽if(ir_data==num_1||ir_data==num_2||ir_data==num_3||ir_data==num_4||ir_data==num_5||ir_data==num_6||ir_data==nu

110、m_7||ir_data==num_8||ir_data==num_9||ir_data==num_0)</p><p><b>  { </b></p><p>  receive_code[i]=ir_data;//第一次輸入修改密碼</p><p>  lcd_pos(0x40+j);</p><p>&l

111、t;b>  j++;</b></p><p>  lcd_wdat(codestar[i]);</p><p><b>  i++;</b></p><p>  ir_data=0;</p><p><b>  }</b></p><p>  if(ir_

112、data==num_voldec) </p><p><b>  {</b></p><p><b>  i--;</b></p><p>  if(i<0) i=0;</p><p><b>  j--;</b></p><p>  if(

113、j<0) j=0;</p><p>  lcd_pos(0x40+j); </p><p>  lcd_wdat(ent_empty[0]);</p><p><b>  }</b></p><p>  if(i==6)new1_code=1;</p><p>  if(ir_data=

114、=num_eq&&new1_code==1&&code_right==1) </p><p>  break; //判斷第一次新密碼是否接收完</p><p><b>  }</b></p><p>  lcd_wcmd(0x01);</p><p>  lcd_pos(0);<

115、/p><p>  ir_flag=0;</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(new_code1[m]);</p><p><b>  i=0;</b></p><p><b>  j=0;</b></p>

116、<p><b>  for(;;)</b></p><p><b>  { </b></p><p>  if(ir_flag==0) continue;</p><p>  ir_flag=0;</p><p><b>  //按鍵屏蔽</b></p

117、><p>  if(ir_data==num_1||ir_data==num_2||ir_data==num_3||ir_data==num_4||ir_data==num_5||ir_data==num_6||ir_data==num_7||ir_data==num_8||ir_data==num_9||ir_data==num_0)</p><p><b>  { </

118、b></p><p>  com_code[i]=ir_data; //第二次輸入修改密碼</p><p>  lcd_pos(0x40+j);</p><p><b>  j++;</b></p><p>  lcd_wdat(codestar[i]);</p><p><b&

119、gt;  i++;</b></p><p>  ir_data=0;</p><p><b>  }</b></p><p>  if(ir_data==num_voldec) </p><p><b>  {</b></p><p><b> 

120、 i--;</b></p><p>  if(i<0) i=0;</p><p><b>  j--;</b></p><p>  if(j<0) j=0;</p><p>  lcd_pos(0x40+j); </p><p>  lcd_wdat(ent_empty[

121、0]);</p><p><b>  }</b></p><p><b>  if(i>0)</b></p><p><b>  { </b></p><p>  if(ir_data==num_eq) // 兩次密碼輸入完畢確認(rèn)鍵 eq</p>

122、<p><b>  { </b></p><p><b>  e=0;</b></p><p>  if(i<6||i>6) e=1; </p><p>  while(i--)</p><p><b>  {</b></p><

123、p>  if(com_code[i]!=receive_code[i])//與原密碼比較</p><p><b>  e++;</b></p><p><b>  } </b></p><p>  if(e>0) wrong_num++; </p><p><b>  

124、for(;;)</b></p><p><b>  {</b></p><p>  if(wrong_num==1) //兩次輸入密碼不一樣</p><p>  { lcd_wcmd(0x01);</p><p>  lcd_pos(0);</p><p>  for(m

125、=0;m<16;m++)</p><p>  lcd_wdat(not_sam[m]);</p><p>  lcd_pos(0x40); </p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(ent_aga[m]);</p><p><b>  LED1

126、=0;</b></p><p><b>  beep();</b></p><p><b>  LED1=1;</b></p><p><b>  EX0=0;</b></p><p>  delay1(1000);</p><p><

127、b>  EX0=1;</b></p><p>  lcd_wcmd(0x01);</p><p>  lcd_pos(0);</p><p>  for(m=0;m<16;m++)</p><p>  lcd_wdat(ent_sign[m]);</p><p><b>  i=0;&

128、lt;/b></p><p><b>  j=0;</b></p><p><b>  b=1;</b></p><p>  wrong_num=0;</p><p>  lcd_pos(0x40);</p><p>  for(m=0;m<16;m++)<

129、/p><p>  lcd_wdat(ent_empty[m]);</p><p><b>  break;</b></p><p><b>  }</b></p><p>  else //密碼一致,開始修改密碼</p><p><b>  {</b>

130、;</p><p>  SectorErase(0x2000); //擦除扇區(qū)</p><p>  delay1(10);</p><p>  byte_write(0x2200,0x11); //密碼被存儲過的標(biāo)志信號</p><p>  for(k=0;k<6;k++)</p><p><b>

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論