仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
3.6 開鎖機構
在基于單片機的電子密碼鎖設計中,用戶需要輸入密碼,密碼正確則發出開鎖信號開鎖。
在這次基于單片機的電子密碼鎖設計中,通過控制蜂鳴器的發音來指示系統的開鎖功能。蜂鳴器是一種采用直流電壓供電的電子訊響器。圖3-9是用蜂鳴器指示的開鎖機構仿真圖。因為在設計中是以蜂鳴器發生來指示開鎖是否成功,當密碼輸入正確時蜂鳴器響起來,代表鎖開了。
圖3-9開鎖機構指示電路
3.7 報警機構
在這次基于單片機的電子密碼鎖設計中,通過控制報警顯示LED來指示系統的報警功能。圖3-10是用基于LED的報警機構仿真圖。控制RELAY輸出高低電平,即P3.4引腳,就可以控制報警顯示LED的亮滅,從而指示相關信息。
圖3-10報警機構模擬仿真圖
當用戶輸入密碼錯誤次數達到預設警告次數時,系統調用報警子程序,使LED亮起來,同時禁止鍵盤輸入。
3.8 硬件綜合設計
根據電路原理,在PROTEUS中畫出各功能模塊的仿真圖,各個功能模塊驗證正確后,將所有模塊集合到一個電路設計圖中,畫出具有所有功能的總體硬件仿真圖。
待程序編寫好后,將KEIL和PROTEUS聯調,觀察此電路設計圖可以知道各個功能模塊和器件的工作情況。屆時,根據實際情況可以適當修改電路圖或者程序,以達到設計的目的。
單片機源程序如下:
- #include<reg51.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
- #include"lcd1602.h"
- #include"i2c.h"
- sbit LED=P3^3; //繼電器控制引腳
- sbit RELAY=P3^4; //繼電器控制引腳
- sbit BUZZER=P3^5; //蜂鳴器控制引腳
- sbit SET=P0^7; //設置
- sbit LCK=P0^6; //關鎖
- #define LOCK_TIME_second 10
- #define SU 1/256
- #define GPIO_KEY P1 //4X4矩陣鍵盤輸入
- unsigned char KeyValue; //用來存放讀取到的鍵值
- unsigned char saved_Value[4]={6,7,6,7}; //初始密碼
- unsigned char input_Value[4];
- unsigned char Right_flg=0,Right_flg0=0;
- unsigned char set_flg=0,LOCK_flg=0;
- unsigned char temp00;
- unsigned int time_cnt,time_remember,delay_ddll;
- long int DECvalue=0;
- //存儲芯片存儲的內容
- /*===============================================
- 地址: 0 1 2 3 4 5 6
- 數據:無 密碼 密碼 密碼 密碼 無 錯誤次數
- =================================================*/
- void TimerConfiguration(void); //定時中斷
- void KeyDown(); //檢測按鍵函數
- void At24c02Write(unsigned char addr,unsigned char dat);
- unsigned char At24c02Read(unsigned char addr);
- //====主函數入口======
- void main()
- {
- char i=0,j=0;
- //unsigned char aa;
- char k=0;
- LcdInit(); //液晶初始化
- clear_window();
- TimerConfiguration(); //初始化定時器
- Lcd1602_Delay1ms(5);
- At24c02Write(1,6); //初始化存儲芯片,實際電路中就不需要
- At24c02Write(2,7);
- At24c02Write(3,6);
- At24c02Write(4,7);
- At24c02Write(6,0); ////清除錯誤輸入次數
- RELAY=1;
- BUZZER=1;
- while(1)
- {
- KeyDown(); ////按鍵掃描
- ///===========正常輸入密碼操作======================
- if (KeyValue<=9 && !set_flg && !LOCK_flg) //有按鍵按下
- {
- input_Value[i]=KeyValue;
- if (Right_flg0)
- { clear_window();
- Right_flg0=0;
- }
- LcdWriteCom(0x80+i); //顯示當前按鍵的值
- LcdWriteData('*');
- i++;
- if(i>=4) //判斷
- {
- Right_flg0=0;
- for (j=0;j<4;j++)
- {
- if (input_Value[j]!=saved_Value[j])
- Right_flg0=1;
- }
- clear_window();
- if(!Right_flg0) ////密碼輸入正確
- {
- BUZZER=0; //聲音報警
- delay_ddll = 1;
- LcdWriteCom(0x80+i+2);
- LcdWriteData('O');
- LcdWriteData('K');
- At24c02Write(6,0); ////清除錯誤輸入次數
- }
- else
- {
- BUZZER=1;
- LcdWriteCom(0x80+i+2);
- LcdWriteData('E');
- LcdWriteData('R');
- temp00=At24c02Read(6); ////存儲輸入錯誤次數
- if (temp00>=2) //連續輸入錯誤超過3次
- {
- LOCK_flg=1;
- RELAY=0; /////指示燈起來
- LcdWriteCom(0x80+i+2);
- LcdWriteData('L');
- LcdWriteData('K');
- }
- At24c02Write(6,temp00+1);
- }
- i=0;
- }
- }
- ///===========正常輸入密碼操作 end======================
- ///===========修改密碼操作======================
- if (KeyValue<=9 && set_flg && !LOCK_flg) //有按鍵按下 KeyValue!=66
- {
- input_Value[k]=KeyValue;
-
- LcdWriteCom(0x80+k); //顯示當前按鍵的值
- LcdWriteData('*');
- k++;
- if(k>=4) //判斷
- {
- if (set_flg==2)
- {
- for (j=0;j<4;j++)
- {
- saved_Value[j]=input_Value[j];
- At24c02Write(j+1,saved_Value[j]);
- }
- clear_window();
- set_flg=0;
- LED = 0; //設置狀態指示燈亮起來
- delay_ddll =1;
- // LcdWriteCom(0x80+k+2);
- // LcdWriteData('O');
- // LcdWriteData('K');
- }
- if (set_flg==1)
- {///============================================
- Right_flg=0;
- for (j=0;j<4;j++)
- {
- if(input_Value[j]!=saved_Value[j])
- Right_flg=1;
- }
- clear_window();
- if(!Right_flg) ///舊密碼輸入正確
- {
- set_flg=2; ///可以進行下一步操作
- LcdWriteCom(0x80+0x40); //
- LcdWriteData('N');
- LcdWriteData('E');
- LcdWriteData('W');
- }
- else
- {
- LcdWriteCom(0x80+k+2);
- LcdWriteData('E');
- LcdWriteData('R');
-
- temp00=At24c02Read(6); ////存儲輸入錯誤次數
- if (temp00>=2)
- {
- LOCK_flg=1;
- RELAY=0; /////指示燈起來
- LcdWriteCom(0x80+i+2);
- LcdWriteData('L');
- LcdWriteData('K');
- }
- At24c02Write(6,temp00+1);
- }
- } ///============================================
-
- k=0;
- }
- }
- ///===========修改密碼操作 end======================
- if (KeyValue==0x0A && !LOCK_flg) //有按鍵按下
- {
- clear_window();
- set_flg=1;
- LcdWriteCom(0x80+0x40); //
- LcdWriteData('O');
- LcdWriteData('L');
- LcdWriteData('D');
- k=0; //=================
- }
- ////=============############================================
- else if (KeyValue==0x0B && !LOCK_flg) //有按鍵按下,關上鎖,清除窗口!LCK
- {
- BUZZER=1;
- clear_window();
- }
-
- if (delay_ddll)
- {
- delay_ddll++;
- if (delay_ddll>2000)
- {
- LED = 1;
- BUZZER = 1;
- delay_ddll = 0;
- }
- }
- ////=============================================
- Lcd1602_Delay1ms(1);
- }
- }
- /*******************************************************************************
- * 函 數 名 : KeyDown
- * 函數功能 : 檢測有按鍵按下并讀取鍵值
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void KeyDown(void)
- {
- unsigned char a=0;
-
- KeyValue=66;
- GPIO_KEY=0x0f;
- if(GPIO_KEY!=0x0f)//讀取按鍵是否按下
- {
- Lcd1602_Delay1ms(10); //延時10ms進行消抖
- if(GPIO_KEY!=0x0f) //再次檢測鍵盤是否按下
- {
- //測試列
- GPIO_KEY=0X0F;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=1;break;
- case(0X0d): KeyValue=2;break;
- case(0X0e): KeyValue=3;break;
- }
- //測試行
- GPIO_KEY=0XF0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue;break;
- case(0Xb0): KeyValue=KeyValue+4;break;
- case(0Xd0): KeyValue=KeyValue+8;break;
- case(0Xe0): KeyValue=KeyValue+12;break;
- }
- while((a<250)&&(GPIO_KEY!=0xf0)) //檢測按鍵松手檢測
- {
- Lcd1602_Delay1ms(2);
- a++;
- }
- }
- }
- }
- /*******************************************************************************
- * 函數名 : void At24c02Write(unsigned char addr,unsigned char dat)
- * 函數功能 : 往24c02的一個地址寫入一個數據
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void At24c02Write(unsigned char addr,unsigned char dat)
- {
- I2cStart();
- I2cSendByte(0xa0);//發送寫器件地址
- I2cSendByte(addr);//發送要寫入內存地址
- I2cSendByte(dat); //發送數據
- I2cStop();
- }
- /*******************************************************************************
- * 函數名 : unsigned char At24c02Read(unsigned char addr)
- * 函數功能 : 讀取24c02的一個地址的一個數據
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- unsigned char At24c02Read(unsigned char addr)
- {
- unsigned char num;
- I2cStart();
- I2cSendByte(0xa0); //發送寫器件地址
- I2cSendByte(addr); //發送要讀取的地址
- I2cStart();
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
仿真代碼.7z
(398.91 KB, 下載次數: 2407)
2021-11-5 00:48 上傳
點擊文件名下載附件
電子密碼鎖仿真電路+程序
演示視頻.7z
(9.91 MB, 下載次數: 286)
2021-11-5 00:48 上傳
點擊文件名下載附件
|