能否有大神解答一下,如何設定密碼鎖的初始密碼呢???!!!要想將初始密碼設置為123456應該如何操作呢?
//-----------------------------------------------------------------
// 名稱: 基于單片機的電子密碼鎖設計
//-----------------------------------------------------------------
// 說明: 初始密碼由24C04.BIN設定為"123456".
// 按下數字鍵0-9可輸入密碼,不超過6位,輸入完成后按下A
// 鍵開鎖,密碼正確時LED點亮,液晶屏顯示開鎖成功.
// 其他鍵功能是:B-上鎖 C-重新輸入密碼 D-保存新密碼 E-清除
// 重設密碼時要求先輸入正確的密碼成功開鎖.
//
//-----------------------------------------------------------------
- #include <reg51.h>
- #include <string.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- //上次按鍵和當前按鍵序號,該矩陣中序號范圍為0-15,16表示無按鍵
- INT8U Pre_KeyNo = 16, keyNo = 16 ;
- INT8U DSY_BUFFER[10] = ""; //顯示緩沖
- INT8U UserPassword[7] = ""; //用戶輸入的密碼
- INT8U IIC_Password[7]; //從IIC存儲器讀取的密碼
- extern void Initialize_LCD(); //液晶初始化
- extern void LCD_ShowString(INT8U, INT8U ,INT8U*); //顯示字符串
- extern void IIC_Init(); //IIC初始化
- extern INT8U Random_Read(INT8U,INT16U); //從指定地址讀取1字節
- extern void Write_IIC(INT8U,INT16U,INT8U); //向指定地址寫入1字節
- extern void delay_ms(INT16U x); //延時函數
- //INT8U Keys_Scan(); //掃描鍵盤返回鍵值
- void Beep(); //蜂鳴器
- sbit LED_OPEN = P2^7; //開鎖亮燈
- sbit BEEP = P3^7; //蜂鳴器
- // void delay_ms(INT16U ms)
- // {
- // INT8U i;
- // while(ms--)
- // for(i=0;i<120;i++);
- // }
- INT8U Keys_Scan()
- {
- //高四位置0,放入四行,掃描四列
- P1=0x0F;delay_ms(1);
- if(P1==0x0F){keyNo=0xFF; return 16;} //無按鍵時提前返回
- //按鍵后00001111將變成0000XXXX,X中1個為0,3個仍為1
- //下面判斷按鍵發生于0-3列中的哪一列
- switch(P1)
- {
- case 0x0E:keyNo=0;break; //按鍵在第0列
- case 0x0D:keyNo=1;break; //按鍵在第1列
- case 0x0B:keyNo=2;break; //按鍵在第2列
- case 0x07:keyNo=3;break; //按鍵在第3列
- default: keyNo=16;return 16; //無按鍵按下,提前返回
- }
- //低四位置0,放入四列,掃描四行
- P1=0xF0;delay_ms(1);
- //按鍵后11110000將變成XXXX0000,X中1個為0,3個仍為1
- //下面判斷按鍵發生于0-3列中的哪一行
- //對0-3行分別附加的起始值為:0,4,8,12
- switch(P1)
- {
- case 0xE0:keyNo+=0;break; //按鍵在第0行
- case 0xD0:keyNo+=4;break; //按鍵在第1行
- case 0xB0:keyNo+=8;break; //按鍵在第2行
- case 0x70:keyNo+=12;break; //按鍵在第3行
- default: keyNo=16; //無按鍵按下
- }
- return keyNo;
- }
- //-----------------------------------------------------------------
- // 蜂鳴器子程序
- //-----------------------------------------------------------------
- void Beep()
- {
- INT8U i;for (i = 0; i < 100; i++) { delay_ms(1); BEEP = ~BEEP; }
- BEEP = 0;
- }
- //-----------------------------------------------------------------
- // 清除密碼
- //-----------------------------------------------------------------
- void Clear_Pwd() {UserPassword[0]='\0'; DSY_BUFFER[0]='\0'; }
- //-----------------------------------------------------------------
- // 讀取密碼字符串(以'\0'為結束標志)
- //-----------------------------------------------------------------
- void Read_IIC_Pwd()
- {
- INT8U i=-1; //因為只限于讀取存儲器前半部分,故;類型可設為INT8U
- //從0x0000地址開始讀取I2C存儲器保存的密碼,長度不超過6個字符
- //下面的循環最多讀取7個字符(0~6:包括密碼字符串最末尾的'\0')
- do {i++;IIC_Password[i]=Random_Read(0xA0,i);}
- while (IIC_Password[i]!='\0' && i<6);
- //如果循環結束后未遇到結束標志,則直接在字符串末尾補上結束標志
- if(IIC_Password[i]!='\0')
- IIC_Password[i]='\0';
- }
- //-----------------------------------------------------------------
- // 寫密碼字符串(結束標志'\0'注意一并寫入)
- //-----------------------------------------------------------------
- void Write_IIC_Pwd()
- {
- INT8U i=0;
- //循環寫入密碼字符,字符串末尾的'\0'也要寫入,最多7個字符(0~6)
- while(i<=6)
- { Write_IIC(0xA0,i,UserPassword[i]); delay_ms(5);
- if(UserPassword[i]=='\0') break;
- i++;
- }
- //如果循環結束時密碼字符串末尾未遇到'\0'則直接向I2C補充寫入'\0'
- if(UserPassword[i]!='\0') Write_IIC(0xA0,i,'\0');
- }
- //-----------------------------------------------------------------
- // 主程序
- //-----------------------------------------------------------------
- void main()
- {
- INT8U i=0;
- INT8U IS_Valid_User=0;
- P0=0xFF; P1=0xFF; P2=0xFF;
- delay_ms(10);
- Initialize_LCD(); //初始化LCD
- LCD_ShowString(0,0,"Your Password...");
- Read_IIC_Pwd(); //將密碼讀入IIC_Password
- while(1)
- { P1=0xF0;
- if(P1!=0xF0) keyNo=Keys_Scan(); //掃描鍵盤或許鍵序號
- switch(keyNo)
- { case 0: case 1: case 2: case 3: case 4:
- case 5: case 6: case 7: case 8: case 9:
- if(i<=5) //密碼不超過6位
- { //如果i為0則執行一次清屏
- if(i==0) LCD_ShowString(1,0," ");
- UserPassword[i]=keyNo+'0';
- UserPassword[i+1]='\0';
- DSY_BUFFER[i]='*';
- DSY_BUFFER[i+1]='\0'; i++;
- LCD_ShowString(1,0,DSY_BUFFER);
- }
- break;
- case 10://按A鍵開鎖
- Read_IIC_Pwd(); //從I2C存儲器讀取密碼
- if(strcmp(UserPassword,IIC_Password)==0)
- { LED_OPEN=0; //點亮LED
- Clear_Pwd();
- LCD_ShowString(1,0,"UNLOCK OK ! ");
- IS_Valid_User=1;
- }
- else
- { LED_OPEN=1; //關閉LED
- Clear_Pwd();
- LCD_ShowString(1,0,"ERROR ! ");
- IS_Valid_User=0;
- }
- i=0;break;
- case 11://按B鍵上鎖
- LED_OPEN=1;
- Clear_Pwd();
- LCD_ShowString(0,0,"YOUR PASSEORD...");
- LCD_ShowString(1,0," ");
- i=0; IS_Valid_User=0;break;
- case 12://按C鍵設置新密碼
- //如果是合法用戶則提示輸入新密碼
- if(!IS_Valid_User)
- LCD_ShowString(1,0,"NO RIGHTS !");
- else
- { i=0; //密碼輸入緩沖索引歸零
- LCD_ShowString(0,0,"NEW PASSEORD:...");
- LCD_ShowString(1,0," ");
- }
- break;
- case 13://按D鍵保存新密碼
- if(!IS_Valid_User)
- LCD_ShowString(1,0,"NO RIGHTS !");
- else
- { //寫入新設置的新密碼,并重新讀回
- Write_IIC_Pwd();delay_ms(5);Read_IIC_Pwd();
- i=0; //密碼輸入緩沖索引歸0
- LCD_ShowString(0,0,"YOUR PASSEORD...");
- LCD_ShowString(1,0,"PASSWORD SAVED! ");
- }
- break;
- case 14://按E鍵清除所有輸入
- i=0; Clear_Pwd();
- LCD_ShowString(1,0," ");
- }
- Beep();delay_ms(100); P1=0xF0;
- while(P1!=0xF0); //如果有鍵未釋放則等待
- while(P1==0xF0); //如果沒有再次按下按鍵則等待
- }
- }
- //-----------------------------------------------------------------
- // 液晶控制與顯示程序
- //-----------------------------------------------------------------
- #include <reg51.h>
- #include <intrins.h>
- #define INT8U unsigned char
- #define INT16U unsigned int
- sbit RS = P2^0; //寄存器選擇線
- sbit RW = P2^1; //讀/寫控制線
- sbit EN = P2^2; //使能控制線
- //-----------------------------------------------------------------
- // 延時
- //-----------------------------------------------------------------
- void delay_ms(INT16U ms){INT8U i; while(ms--) for(i = 0; i < 120; i++);}
- //-----------------------------------------------------------------
- // 忙等待
- //-----------------------------------------------------------------
- void Busy_Wait()
- {
- INT8U LCD_Status;
- do
- {
- P0=0XFF; //液晶屏端口初始置高電平
- EN=0;RS=0;RW=1; //LCD禁止,選擇狀態寄存器,準備讀
- EN=1;LCD_Status=P0; //LCD使能,從P0端口讀取液晶屏狀態字節
- EN=0; //LCD禁止
- }while(LCD_Status & 0x80); //液晶屏忙繼續循環
- }
- //-----------------------------------------------------------------
- // 寫LCD命令
- //-----------------------------------------------------------------
- void Write_LCD_Command(INT8U cmd)
- {
- Busy_Wait(); //LCD忙等待
- EN=0;RS=0;RW=0; //LCD禁止,選擇命令寄存器,準備寫
- P0=cmd; //命令字節放到LCD端口
- EN=1;_nop_();EN=0; //使能LCD,寫入后禁止LCD
- }
- //-----------------------------------------------------------------
- // 發送數據
- //-----------------------------------------------------------------
- void Write_LCD_Data(INT8U dat)
- {
- Busy_Wait(); //LCD忙等待
- EN=0;RS=1;RW=0; //LCD禁止,選擇數據寄存器,準備寫
- P0=dat; //數據字節放到LCD端口
- EN=1;_nop_();EN=0; //使能LCD,寫入后禁止LCD
- }
- //-----------------------------------------------------------------
- // LCD初始化
- //-----------------------------------------------------------------
- void Initialize_LCD()
- {
- Write_LCD_Command(0x38);delay_ms(1); //置功能,8位,雙行,5*7
- Write_LCD_Command(0x01);delay_ms(1); //清屏
- Write_LCD_Command(0x06);delay_ms(1); //字符進入模式:屏幕不動,字符后移
- Write_LCD_Command(0x0C);delay_ms(1); //顯示開,關光標
- }
- //-----------------------------------------------------------------
- // 顯示字符串
- //-----------------------------------------------------------------
- void LCD_ShowString(INT8U r, INT8U c,INT8U *str)
- {
- INT8U i=0;
- code INT8U DDRAM[]={0x80,0xC0}; //1602LCD兩行的起始DDRAM地址
- Write_LCD_Command(DDRAM[r] | c); //設置顯示起始位置
- for(i=0;str[i]&&i<16;i++) //輸出字符串
- Write_LCD_Data(str[i]);
- for(;i<16;i++) //不足一行時用空格填充
- Write_LCD_Data(' ');
- }
- //-----------------------------------------------------------------
- // 名稱: 24C04 IIC讀寫程序
- //-----------------------------------------------------------------
- #define INT8U unsigned char
- #define INT16U unsigned int
- #include <reg51.h>
- #include <intrins.h>
- sbit SCL = P3^2; //串行時鐘
- sbit SDA = P3^3; //串行數據
- #include "I2C.h" //IIC總線通用宏及函數
- //-----------------------------------------------------------------
- // 向指定的地址寫數據
- // 器件選擇碼字節格式 (其中E2,E1為片選位,A8為塊地址位)
- // 位: B7 B6 B5 B4 B3 B2 B1 B0
- // 值: 1 0 1 0 E2 E1 A8 RW
- //-----------------------------------------------------------------
- void Write_IIC(INT8U Dev_Addr,INT16U mem_addr,INT8U dat)
- {
- IIC_Start(); //啟動總線
- //發送器件地址
- if(mem_addr<0x0100) IIC_WriteByte(Dev_Addr);
- else IIC_WriteByte(Dev_Addr | 0x02);
- //寫內存地址,或寫成:IIC_WriteByte(men_addr&0xFF);
- IIC_WriteByte(mem_addr);
- IIC_WriteByte(dat); //寫數據字節
- IIC_Stop(); //總線停止
- }
- //-----------------------------------------------------------------
- // 從任意地址讀取數據(器件選擇碼字節參上一函數說明)
- //-----------------------------------------------------------------
- INT8U Random_Read(INT8U Dev_Addr,INT16U mem_addr)
- {
- INT8U d;
- IIC_Start(); //總線啟動
- //發送器件地址
- if(mem_addr<0x0100) IIC_WriteByte(Dev_Addr);
- else IIC_WriteByte(Dev_Addr | 0x02);
- IIC_WriteByte(mem_addr); //寫器件內存地址
- IIC_Start(); //總線重新啟動
- //內存地址mem_addr小于256(0x0100)時,讀器件內存前半部分
- //否則讀器件內存的后半部分,故而有器件地址有:
- //Dev_Addr|0x01及Dev_Addr|0x03這兩種寫法
- if(mem_addr<0x0100) IIC_WriteByte(Dev_Addr | 0x01);//前半部分
- else IIC_WriteByte(Dev_Addr | 0x03);//后半部分
- d=IIC_ReadByte(); IIC_NAck(); IIC_Stop();//讀取一字節,非應答,停止
- return d;
- }
復制代碼
|