由于放假沒有準備,現在做了發現IIC總線不會用,對1602液晶和同類的手冊可以看懂也會使用。不用24存儲,所以就沒有密碼更改的功能。還有,看其他的資料,在使用IIC總線14芯片時,有的使用 .BIN文件,不理解。
24C04密碼鎖仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (29.45 KB, 下載次數: 49)
下載附件
2018-10-12 15:54 上傳
根據設定好的密碼, 采用六個按鍵實現密碼的輸入功能
當密碼輸入完后,按確認鍵驗證,正確之后,鎖就打開
如果輸入的三次的密碼不正確, 就鎖定按鍵 3 秒鐘
同時發出報警聲,直到沒有按鍵按下 3 秒后
才打開按鍵鎖定功能否則在 3 秒鐘內仍有按鍵按下,就重新鎖
初值密碼2 0 1 6 5 7
重置密碼在輸入正確的原始密碼后
提示輸入新密碼后按重置保存按鍵保存密碼
單片機源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #include<string.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define NOP4() {_nop_();_nop_();_nop_();_nop_();}
- sbit lcdrs=P2^0; //1602液晶控制端
- sbit lcdrw=P2^1;
- sbit lcden=P2^2;
- sbit Beep=P2^3;
- sbit Red=P2^4;
- sbit Green=P2^5;
- sbit Lamp=P2^6;
- sbit SCL=P3^0;
- sbit SDA=P3^1;
- uchar num=0; //按鍵次數
- uchar Wrong=0; //錯誤次數
- uchar Count=0; //開鎖次數
- uchar Timer=0; //中斷計數器
- uchar k=0; //數組累加
- uchar Sure_temp,Cancel_temp;//保存按下確認鍵和取消鍵P1的值
- /**************************各數組定義*******************************/
- //按鍵次數碼表
- uchar code Count_Table[]="123456789";
- //鍵盤特征碼
- uchar code Key_Table[]={0xee,0xde,0xbe,0x7e,
- 0xed,0xdd,0xbd,0x7d,
- 0xeb,0xdb,0xbb,0x7b,
- 0xe7,0xd7,0xb7,0x77};
- uchar Buffer[]={0,0,0,0,0,0}; //按鍵數值緩存數組
- uchar Buffer_Reset[]={0,0,0,0,0,0}; //重置密碼緩存
- uchar Passedword[]={0,0,0,0,0,0};//密碼數組 (這里開始出廠密碼為比賽日期201657)
- /*************************************************/
- //聲光報警
- void Alarm()
- {
- uchar i;
- Red=0;
- for(i=0;i<120;i++)
- {
- Beep=~Beep;
- Delay(2);
- }
- }
- void Delay(uchar z)
- {
- uchar x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /**********************1602液晶顯示器初始化函數********************/
- void write_com(uchar com)
- {
- lcdrs=0; //發送指令RS置低電平
- lcdrw=0;
- P0=com;
- Delay(5);
- lcden=1;
- Delay(5);
- lcden=0;
- }
- void write_data(uchar dat)
- {
- lcdrs=1; //發送數據RS置高電平
- lcdrw=0;
- P0=dat;
- Delay(5);
- lcden=1; //EN向下脈沖
- Delay(5);
- lcden=0;
- }
- void lcd_initial()
- {
- lcden=0;
- lcdrw=0;
- write_com(0x38); //設置16*2顯示,5*7點陣,8為顯示
- Delay(1);
- write_com(0x0c); //設置開顯示,不顯示光標
- Delay(1);
- write_com(0x06); //寫一個字符后地址指針加1
- Delay(1);
- write_com(0x01); //顯示清0,數據指針清0
- Delay(1);
- }
- void write_string(uchar *str)
- {
- uchar i;
- write_com(0x80); //第一行顯示,主要用于密碼重置時的提示
- for(i=0;i<strlen(str);i++)
- {
- write_data(str[i]);
- }
- }
- /****************IIC24C04A初始化函數****************************/
- void Start()
- {
- SDA=1;SCL=1;NOP4();SDA=0;NOP4();SCL=0;
- }
- void Stop()
- {
- SDA=0;SCL=0;NOP4();SCL=1;NOP4();SDA=1;NOP4();
- }
- void RACK()
- {
- SDA=1;NOP4();SCL=1;NOP4();SCL=0;
- }
- void NO_ACK()
- {
- SDA=1;SCL=1;NOP4();SCL=0;SDA=0;
- }
- void Write_A_Byte(uchar b)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- b<<=1;SDA=CY;_nop_();SCL=1;NOP4();SCL=0;
- }
- RACK();
- }
- uchar Receive_A_Byte()
- {
- uchar i,d;
- for(i=0;i<8;i++)
- {
- SCL=1;d<<=1;d|=SDA;SCL=0;
- }
- return d;
- }
- void Write_Random_Address_Byte(uchar add,uchar dat)
- {
- Start();
- Write_A_Byte(0xa0);
- Write_A_Byte(add);
- Write_A_Byte(dat);
- Stop();
- Delay(10);
- }
- uchar Read_Current_Address_Data()
- {
- uchar d;
- Start();
- Write_A_Byte(0xa1);
- d=Receive_A_Byte();
- NO_ACK();
- Stop();
- return d;
- }
- uchar Random_Read(uchar addr)
- {
- Start();
- Write_A_Byte(0xa0);
- Write_A_Byte(addr);
- Stop();
- return Read_Current_Address_Data();
- }
- /********************按鍵處理函數***********************/
- //確認鍵處理 按鍵檢測
- void Sure_Key()
- {
- uchar flag;
- uchar i;
- write_com(0x80); //第一行0x80+0x00
- write_data(Count_Table[Count++]); //顯示輸入次數
- Delay(200);
- if(Count>=10){P0=0XC0;Count=0;}
- for(i=0;i<6;i++)
- {
- if(Buffer[i]==Passedword[i]){flag=1;continue;}
- else {flag=0;break;}
- }
- //結果處理
- if(flag==1){k=0;Green=0;Lamp=0;Red=1;write_com(0x80+0x40);for(i=0;i<16;i++)write_data('\0');Delay(200);} //正確綠燈亮,鎖打開
- else {k=0;Alarm();Wrong++;Green=1;Lamp=1;write_com(0x80+0x40);for(i=0;i<16;i++)write_data('\0');Delay(200);} //錯誤則聲光報警
- if(Wrong==3) {Sure_temp=P1;TR0=1;Wrong=0;} //錯誤三次則鎖定鍵盤3秒鐘
- }
- //取消鍵處理
- void Cancel_Key()
- {
- uchar i;
- k=0;
- for(i=0;i<6;i++)Buffer[i]=0;Delay(100);
- write_com(0x80+0x40);
- for(i=0;i<16;i++)write_data('\0');
- }
- //鎖定鍵
- void Lock()
- {
- uchar i;
- k=0;Alarm();Green=1;Lamp=1;Delay(200);
- Cancel_Key();
- }
- //清屏鍵
- void Clear_Lcd()
- {
- k=0;Cancel_Key();
- write_com(0x01);
- }
- //重置鍵
- void Reset_Key()
- {
- uchar i;
- k=0;
- write_com(0x10);
- write_string("Input Passedword:");
- }
- //重置確認鍵
- void Reset_Sure_Key()
- {
- uchar i,flag;
- for(i=0;i<6;i++){if(Buffer[i]==Passedword[i]){flag=1;continue;} else {flag=0;break;}}//輸入老密碼并判斷
- if(flag==1) {write_com(0x01);write_string("Input Newword:");Cancel_Key();}
- else {Reset_Key();}
- /* 最初的想法是用一個按鍵來進行重置鍵處理
- uchar state=1; //重置按鍵第一次為判斷是否與老密碼一樣,第二次進行新密碼的保存
- state=~state; //初始為state=1;
- k=0;
- switch(state)
- {
- case 0: for(i=0;i<6;i++) //輸入老密碼并判斷
- {if(Buffer[i]==Passedword[i]){flag=1;continue;}
- else {flag=0;break;}}
- if(flag==1) {write_com(0x01);write_string("Input Newword:");}
- else {state=~state;Reset_Key();}break;
- case 1: if(flag==1) {for(i=0;i<6;i++) //老密碼正確再保存新密碼
- Write_Random_Address_Byte(i,Buffer[i]);}
- }
- */
- }
- //重置保存
- void Reset_Save()
- {
- uchar i;
- k=0;
- for(i=0;i<6;i++) Write_Random_Address_Byte(i,Buffer[i]); //老密碼正確再保存新密碼
- for(i=0;i<6;i++)Passedword[i]=Random_Read(i);
- write_com(0x01);write_string("Succeed!");Delay(1000);write_com(0x01);
-
-
- }
- /**************************按鍵掃描函數***********************************/
- //按鍵掃描
- void Key_Play()
- {
- uchar i=0;
- uchar num;
- uchar temp;
- uchar Key,c;
- P1=0xf0;
- if(P1!=0xf0)
- {
- Delay(5);
- if(P1!=0xf0)
- {
- temp=P1;
- P1=0x0f;
- Key=temp|P1;
- for(i=0;i<16;i++)
- if(Key==Key_Table[i]) {num=i;break;}
- Buffer[k++]=num;
- switch(num)
- {
- case 10:Sure_Key();break; //確認
- case 11:Cancel_Key();break; //取消
- case 12:Reset_Key();break; //重置
- case 13:Reset_Sure_Key();break;//重置確認
- case 14:Reset_Save();break; //上鎖
- case 15:Lock();; //清屏
- }
- write_com(0x80+0x40); //第二行0x80+0x40
- for(i=0;i<k;i++)
- write_data('*');
- }
- do{ //等待按鍵抬起
- temp=P1;
- temp=temp&0x0f;
- }
- while(temp!=0x0f);
- }
- }
-
- //************************主函數************************//
- void main()
- {
- uchar i;
- lcd_initial();
- P0=0x3f;//次數默認為0
- P2=0XFF;//初始全關
- TMOD=0X01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- EA=1;
- ET0=1; //密碼錯誤定時器中斷0
- for(i=0;i<6;i++)Passedword[i]=Random_Read(i);
- while(1)
- {
- Key_Play();
- Delay(2);
- }
- }
- //定時器0中斷 鍵盤鎖定3秒
- void Inter_Timer0() interrupt 1
- {
- uchar temp;
- Timer++;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- Beep=~Beep;Delay(20);
- P1=0xf0;
- if(P1!=0xf0)
- {
- Delay(5);
- Timer=0;
- }
- //如果3秒內無按鍵則回復正常
- if(Timer==60){Timer=0;Beep=0;Red=1;TR0=0;}
- }
復制代碼
0.png (54.15 KB, 下載次數: 43)
下載附件
2018-10-12 15:56 上傳
所有資料51hei提供下載:
實訓任務-3.zip
(1.33 MB, 下載次數: 98)
2018-10-12 15:52 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|