單片機數字密碼鎖:
360截圖-31929847.jpg (55.92 KB, 下載次數: 77)
下載附件
2017-3-9 19:24 上傳
360截圖-32021248.jpg (188.16 KB, 下載次數: 51)
下載附件
2017-3-9 19:24 上傳
程序源代碼:
- //************************************************************************************************************************************
- //庫調用.宏類型定義.位定義//
- //************************************************************************************************************************************
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define ushort unsigned short
- #define GPIO_KEY P1 //矩陣鍵盤燒掃描端口
- sbit RS = P2^2; //液晶顯示器控制端口
- sbit RW = P2^3;
- sbit E = P3^7;
- sbit shuchu=P2^0; //繼電器控制端口
- sbit beep=P2^1; //報警器端口
- sbit DoorBell=P3^6; //門鈴端口
- sbit SCL = P2^6; //AT24C04的時鐘
- sbit SDA = P2^7; //AT24C04的數據
- uchar idata upxs[16]={"Password:"}; //上排存放數組
- uchar idata dwxs[16]={""}; //下排存放數組
- uint idata tempword[6]={0}; //臨時密碼數組
- uint idata password[6]={1,1,1,1,1,1};//初始密碼
- uint idata now=0; //數組偽指針
- uint idata key=0; //密鑰
- uint idata keyboard=0; //鍵盤鎖定標志
- uint idata key1=0; //用于密碼修改
- uint idata KeyValue=16; //用來存放讀取到的鍵值
- uint idata warn=0; //錯誤累計
- uint idata time=0; //用于定時
- uint idata time1=0; //用于定時
- uint idata time2=0; //用于定時
- uint idata moshi=0; //定時器內部模式
- uchar idata BUF[8]; //掉電數據緩存區
- uchar idata TESTDATA[8]={0}; //掉電新密碼存儲
- uint idata menu=0; //menu用于密碼修改
- uint idata tempword1[8]={0}; //用于密碼修改
- //*********************************************************************************************************************************
- //函數聲明//
- //*********************************************************************************************************************************
- void delete(void);
- //*********************************************************************************************************************************
- /*模塊名稱:液晶驅動顯示模塊*/
- /*模塊功能:驅動LCD1602的顯示,并時時顯示按鍵值*/
- //*********************************************************************************************************************************
- void delay(uint dell)//毫秒延時//
- {
- uchar x;
- for(dell;dell>0;dell--)
- for(x=110;x>0;x--);
- }
- void wr_com(uchar temp)//寫指令//
- {
- RS=0;
- RW=0;
- P0=temp;
- E=1;
- E=0;
- }
- void wr_data(uchar num)//寫數據//
- {
- RS=1;
- RW=0;
- P0=num;
- E=1;
- E=0;
- }
- void disp_lcd(uchar addr,char *templ)//顯示函數//
- {
- uchar i;
- wr_com(addr);
- delay(50);
- for(i=0;i<16;i++)
- {
- wr_data(templ[i]);
- delay(50);
- }
- }
- void lcd_init()//初始化液晶//
- {
- wr_com(0x30);
- delay(50);
- wr_com(0x38);
- delay(50);
- wr_com(0x01);
- delay(50);
- wr_com(0x06);
- delay(50);
- wr_com(0x0c);
- delay(50);
- }
- void lcdxianshi(void)//液晶總顯示//
- {
- disp_lcd(0x80,upxs);
- disp_lcd(0xc0,dwxs);
- }
- //*********************************************************************************************************************************
- /*模塊名稱:矩陣鍵盤掃描模塊*/
- /*模塊功能:時時掃描按鍵值*/
- //*********************************************************************************************************************************
- void Delay10ms(void)//延時函數//
- {
- unsigned char a,b,c;
- for(c=1;c>0;c--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- void KeyDown(void)//鍵盤檢測函數//
- {
- char a=0;
- GPIO_KEY=0x0f;
- if(GPIO_KEY!=0x0f) //讀取按鍵是否按下
- {
- Delay10ms(); //延時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<10)&&(GPIO_KEY!=0xf0))//按鍵松手檢測
- {
- Delay10ms();
- a++;
- }
- }
- }
- }
- //*******************************************************************************************************************************
- /*模塊名稱:數據處理模塊*/
- /*模塊功能:(1)將按鍵值傳遞給各種緩存數祝(2)包含數據清除函數*/
- //*******************************************************************************************************************************
- void keysend(void)//鍵值傳遞//
- {
- switch(KeyValue)
- {
- case 0:{dwxs[now]='0';tempword[now]=0;TESTDATA[now]=0;now++;break;}
- case 1:{dwxs[now]='1';tempword[now]=1;TESTDATA[now]=1;now++;break;}
- case 2:{dwxs[now]='2';tempword[now]=2;TESTDATA[now]=2;now++;break;}
- case 3:{dwxs[now]='3';tempword[now]=3;TESTDATA[now]=3;now++;break;}
- case 4:{dwxs[now]='4';tempword[now]=4;TESTDATA[now]=4;now++;break;}
- case 5:{dwxs[now]='5';tempword[now]=5;TESTDATA[now]=5;now++;break;}
- case 6:{dwxs[now]='6';tempword[now]=6;TESTDATA[now]=6;now++;break;}
- case 7:{dwxs[now]='7';tempword[now]=7;TESTDATA[now]=7;now++;break;}
- case 8:{dwxs[now]='8';tempword[now]=8;TESTDATA[now]=8;now++;break;}
- case 9:{dwxs[now]='9';tempword[now]=9;TESTDATA[now]=9;now++;break;}
- case 11:{
- upxs[12]='S';
- upxs[13]='U';
- upxs[14]='R';
- upxs[15]='E'; break;
- }
- case 14:{
- menu++; //密碼修改模式啟動模式一
- if(menu>1) //再次按下跳出密碼修改模式
- {
- upxs[0]='P'; //顯示“password”
- upxs[1]='a';
- upxs[2]='s';
- upxs[3]='s';
- upxs[4]='w';
- upxs[5]='o';
- upxs[6]='r';
- upxs[7]='d';
- upxs[8]=':';
- delete();
- menu=0;
- }
- break;
- }
- case 15:{
- TR0=1; //定時器0打開
- moshi=1; //模式1為門鈴模式
- KeyValue=16; break;//鍵值緩存清零
- }
- }
- if(now==6) now=0; //只存儲8位,只顯示八位
- }
- void delete(void)//清除函數//
- {
- uchar i;
- for(i=0;i<16;i++)
- {
- dwxs[i]=0x20; //密碼字符清零
- }
- for(i=0;i<6;i++)
- {
- tempword[i]=0; //密碼緩存數組清零
- }
- upxs[11]=0x20;
- upxs[12]=0x20; //SURE顯示清零
- upxs[13]=0x20;
- upxs[14]=0x20;
- upxs[15]=0x20;
- now=0; //偽指針復位
- key=0; //密鑰清零
- KeyValue=16; //鍵值緩存初始
- }
- void condition_delete(void) //條件清除
- {
- if(KeyValue==10)
- {
- delete(); //按下DELE鍵清除數據
- }
- KeyValue=16; //鍵值緩存清零
- }
- //*********************************************************************************************************************************
- /*模塊名稱:定時器模塊*/
- /*模塊功能:定時器0用于產生門鈴效果,定時器1用于各種倒計時*/
- //*********************************************************************************************************************************
- void timer0() interrupt 1 //定時器0用于門鈴
- {
- switch(moshi)
- {
- case 1:{
- DoorBell=~DoorBell;
- time++;
- if(time<400) //若需要拖長聲音,可以調整 400 和 800
- {
- TH0=(8192-700)/32; //700us 定時
- TL0=(8192-700)%32;
- }
- else if(time<800)
- {
- TH0=(8192-1000)/32; //1ms 定時
- TL0=(8192-1000)%32;
- }
- else
- {
- time=0; //計數清零
- TR0=0; //關閉定時器
- moshi=0; //跳出模式1
- }
- break;
- }
- case 2:{
- beep=~beep;
- time++;
- if(time<400) //若需要拖長聲音,調整 400
- {
- TH0=(8192-700)/32; //700us 定時
- TL0=(8192-700)%32;
- }
- else
- {
- time=0; //計數清零
- }
- break;
- }
- }
- }
- void timer1() interrupt 3 //定時器1用于自動關門
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- time1++;
- if(time1==20)//一秒
- {
- time2++;
- time1=0;
- }
- }
- //**********************************************************************************************************************************
- /*模塊名稱幟:掉電模塊*/
- /*模塊功能:支持門鎖掉電后密碼可保存而不丟失*/
- //**********************************************************************************************************************************
- //延時5微秒(STC90C52RC@12M),此延時對于12M晶振
- void Delay5us()
- {
- _nop_();
- _nop_();
- }
- //延時5毫秒(STC90C52RC@12M)
- void Delay5ms()
- {
- ushort n = 560;
- while (n--);
- }
- //起始信號
- void AT24C04_Start()
- {
- SDA = 1; //拉高數據線
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SDA = 0; //產生下降沿
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- }
- //停止信號
- void AT24C04_Stop()
- {
- SDA = 0; //拉低數據線
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SDA = 1; //產生上升沿
- Delay5us(); //延時
- }
- //發送應答信號
- void AT24C04_SendACK(bit ack)
- {
- SDA = ack; //寫應答信號
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- //接收應答信號
- bit AT24C04_RecvACK()
- {
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- CY = SDA; //讀應答信號
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- return CY;
- }
- //向IIC總線發送一個字節數據
- void AT24C04_SendByte(uchar dat)
- {
- uchar i;
- for (i=0; i<8; i++) //8位計數器
- {
- dat <<= 1; //移出數據的最高位
- SDA = CY; //送數據口
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- AT24C04_RecvACK();
- }
- //向AT24C04寫1頁(16字節)數據,將TESTDATA開始的16個測試數據寫如設備的00~0F地址中
- void AT24C04_WritePage()
- {
- uchar i;
- AT24C04_Start(); //起始信號
- AT24C04_SendByte(0xa0); //發送設備地址+寫信號
- AT24C04_SendByte(0x00); //發送存儲單元地址
- for (i=0; i<16; i++)
- {
- AT24C04_SendByte(TESTDATA[i]);
- }
- AT24C04_Stop(); //停止信號
- }
- //從IIC總線接收一個字節數據
- uchar AT24C04_RecvByte()
- {
- uchar i;
- uchar dat = 0;
- SDA = 1; //使能內部上拉,準備讀取數據
- for (i=0; i<8; i++) //8位計數器
- {
- dat <<= 1;
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- dat |= SDA; //讀數據
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- return dat;
- }
- //從AT24C04讀取1頁(16字節)數據,將設備的00~0F地址中的數據讀出存放在DATA區的BUF中
- void AT24C04_ReadPage()
- {
- uchar i;
- AT24C04_Start(); //起始信號
- AT24C04_SendByte(0xa0); //發送設備地址+寫信號
- AT24C04_SendByte(0x00); //發送存儲單元地址
- AT24C04_Start(); //起始信號
- AT24C04_SendByte(0xa1); //發送設備地址+讀信號
- for (i=0; i<8; i++)
- {
- BUF[i] = AT24C04_RecvByte();
- if (i == 7)
- {
- AT24C04_SendACK(1); //最后一個數據需要會NAK
- }
- else
- {
- AT24C04_SendACK(0); //回應ACK
- }
- }
- AT24C04_Stop(); //停止信號
- }
- //********************************************************************************************************************************
- /*模塊名稱:菜單模塊*/
- /*模塊功能:用于密碼修改,先輸入舊密碼,密碼正確兩次輸入新密碼*/
- //********************************************************************************************************************************
- void new_password(void)//密碼修改函數
- {
- uchar i,j;
- uchar tempxs1[]={"old mima MENUi"};//提示:輸入舊密碼
- uchar tempxs2[]={"new mima FIRST"};//提示:輸入新密碼一次
- uchar tempxs3[]={"new mima AGAIN"};//提示:輸入新密碼二次
- uchar tempxs4[]={"password: "};//password顯示
- uchar tempxs5[]={"success change "};//修改成功顯示
- switch(menu)
- {
- case 1:{
- for(j=0;j<16;j++){
- upxs[j]=tempxs1[j];
- }
- if(tempword[5]!=0)
- {
- AT24C04_ReadPage();//讀取密碼
- for(i=0;i<8;i++)
- {
- if(BUF[i]!=0)//對比密碼,判斷是不是第一次使用
- {
- key1++;
- }
- }
- if(key1==0)//如果是第一次使用
- {
- for(i=0;i<6;i++)
- {
- if(password[i]!=tempword[i])//對比初始密碼
- {
- key++;
- }
- }
- if(key==0)//密碼正確進入菜單二輸入新密碼
- {
- delete();
- for(i=0;i<8;i++)
- {
- tempword[i]=0;//清空緩存數組
- }
- key=0;
- key1=0;
- menu=2;
- }
- }
- if(key1!=0)//如果不是第一次使用
- {
- for(i=0;i<8;i++)
- {
- password[i]=BUF[i];
- if(password[i]!=tempword[i])//對比密碼
- {
- key++;
- }
- }
- if(key==0)//密碼正確進入菜單二輸入新密碼
- {
- delete();
- for(i=0;i<8;i++)
- {
- tempword[i]=0;//清空緩存數組
- }
- key=0;
- key1=0;
- menu=2;
- }
- }
- }
- break;
- }
- case 2:{
- for(j=0;j<16;j++){
- upxs[j]=tempxs2[j];
- }
- if(tempword[5]!=0)
- {
- for(i=0;i<8;i++)
- {
- tempword1[i]=tempword[i];
- }
- delete();
- for(i=0;i<8;i++)
- {
- tempword[i]=0;//清空緩存數組
- }
- menu=3; //進入菜單三再次輸入新密碼
- }
- break;
- }
- case 3:{
- for(j=0;j<16;j++){
- upxs[j]=tempxs3[j];
- }
- if(tempword[5]!=0)
- {
- for(i=0;i<8;i++)
- {
- if(tempword1[i]!=tempword[i])//對比密碼
- {
- key++;
- }
- }
- if(key==0)//如果第二次輸入的密碼與第一次相同
- {
- AT24C04_WritePage(); //寫入新密碼
- for(i=0;i<8;i++)
- {
- tempword[i]=0;//清空緩存數組
- tempword1[i]=0;//清空緩存數組
- }
- for(j=0;j<16;j++){
- upxs[j]=tempxs4[j];
- dwxs[j]=tempxs5[j];
- }
- key=0;
- menu=0; //跳出密碼修改菜單
- TR1=1;
- if(time2==2) //顯示2秒
- {
- delete();
- TR1=0; //關閉定時器1
- }
- }
- if(key!=0)//如果第二次輸入的密碼與第一次不同
- {
- for(i=0;i<8;i++)
- {
- tempword[i]=0;//清空緩存數組
- tempword1[i]=0;//清空緩存數組
- }
- dwxs[15]='n';
- dwxs[14]='i';
- dwxs[13]='a';
- dwxs[12]='g';
- dwxs[11]='a';
- key=0;
- menu=2; //跳轉到菜單2
- }
- }
- }
- }
- KeyValue=16; //鍵值初始
- }
- //********************************************************************************************************************************
- /*模塊名稱:單函數區*/
- /*模塊功能:一些單獨功能的函數*/
- //********************************************************************************************************************************
- void sure(void)//密碼認證函數//
- {
- uchar i;
- if(KeyValue==11)
- {
- AT24C04_ReadPage();
- for(i=0;i<6;i++)
- { password[i]=BUF[i];
- if(password[i]!=tempword[i])//對比密碼
- {
- key++;
- }
- }
- if(key==0) //密碼正確,輸出OK
- {
- dwxs[13]='O';
- dwxs[14]='K';
- shuchu=1; //開門
- TR1=1; //定時器1打開,啟動倒計時
- moshi=0; //輸入正確密碼可關閉報警模式
- beep=0; //蜂鳴器復位
- TR0=0; //并且關閉定時器0
- }
- if(key!=0) //密碼錯誤,次數累加
- {
- dwxs[12]='E';
- dwxs[13]='R';
- dwxs[14]='O';
- dwxs[15]='R';
- warn++;
- if(warn==3) //輸入錯誤3次,報警
- {
- keyboard=1; //三次錯誤則鍵盤鎖住
- TR0=1; //定時器0啟動
- moshi=2; //模式2啟動蜂鳴器報警
- warn=0; //累計清零
- TR1=1; //啟動鍵盤鎖定倒計時
- }
- }
- }
- }
- //************************************************************************************************************************************
- //附功能函數//
- //************************************************************************************************************************************
- void Add_Function(void)
- {
- switch(time2)
- {
- case 4:{ //門鎖打開后4秒關閉
- shuchu=0; //關閉門鎖電源
- delete(); //自動清除
- if(keyboard==0) //如果不是密碼錯誤開啟的定時器則關閉定時器1
- {
- time2 =0; //time2復位
- TR1=0; //定時器1關閉
- }
- break;
- }
- case 60:{ //鍵盤鎖定一分鐘
- keyboard=0; //鍵盤解鎖
- time2 =0; //time2復位
- TR1=0; //定時器1關閉
- break;
- }
- }
- }
- //************************************************************************************************************************************
- //系統初始化函數//
- //************************************************************************************************************************************
- void System_init(void)
- {
- TMOD=0x10; //0001 0000//定時器1方式1,定時器0方式0
- TH0=(8192-700)/32; //定時器0 700us 定時
- TL0=(8192-700)%32;
- TH1=(65536-50000)/256; //定時器1 50ms
- TL1=(65536-50000)%256;
- EA=1;
- ET0=1;
- ET1=1;
- shuchu=0; //門鎖初始化
- beep=0; //警報初始化
- DoorBell=0; //門鈴初始化
- lcd_init(); //液晶初始化
- }
- //************************************************************************************************************************************
- /*模塊名稱:主函數*/
- /*模塊功能:程序入口*/
- //************************************************************************************************************************************
- void main(void)//主函數
- {
-
- //AT24C04_WritePage(); //密碼初始化(只需使用一次寫入初始密碼)
- System_init(); //系統初始化
- while(1)
- {
- if(keyboard==0) //如果密碼錯誤三次則鎖定鍵盤
- {
- KeyDown(); //按鍵檢測
- }
- keysend(); //數據傳遞
- lcdxianshi(); //輸入顯示
- sure(); //密碼認證
- condition_delete(); //按鍵清除
- new_password(); //密碼修改
- Add_Function(); //附功能函數
- }
- }
- //************************************************************************************************************************************
- //結束
- //************************************************************************************************************************************
復制代碼
0.png (66.12 KB, 下載次數: 68)
下載附件
2017-3-9 19:30 上傳
下載:
電子鎖源代碼.zip
(1.7 MB, 下載次數: 42)
2017-3-9 16:21 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|