单片机密码锁,修改密码后不能掉电保存,复位后又变回初始密码

2019-07-15 13:44发布

QQ图片20160601074737.png
#include <reg51.h>#include <string.h> #include <intrins.h>#include<stdio.h>#define uchar unsigned char #define uint unsigned int #define NOP3() _nop_();_nop_();_nop_()uchar time_1s=0,i=0;uchar time_50ms=0;sbit rs=P2^2;sbit rw=P2^1;sbit e=P2^0;sbit SCL=P2^5;sbit SDA=P2^6;sbit P35=P3^5;sbit P36=P3^6;sbit P37=P3^7;uchar datakong[7]={'','','','','','',0};uchar datamima[7]={'1','2','3','4','5','6',0};uchar datamima0[7]={'','','','','','',0};uchar data mima1[7]={'','','','','','',0};uchar datamima2[7]={'','','','','','',0};uchar datamima3[7]={'','','','','','',0};uchar datatable1[7]={'1','9','9','0','1','0',0};uchar code table2[15]="EnterPassword:";uchar code table4[16]="PasswordError!";uchar code table5[14]="OldPassword:";uchar code table6[14]="NewPassword:";uchar code table7[12]="EnterAgain:";uchar code table8[12]="EnterError!";uchar code table9[15]="ModifySuccess!";uchar code table10[13]="Welcomeback!";//***********************************//相关函数的声明//***********************************void delay1ms();void delay(uchar n);void write_1602com(uchar com);void write_1602dat(uchar dat);void initinal(void);bit lcdbusy();uchar key_scan();void enter_password(void);   //功能:显示输入密码画面void password_error(void);//功能:显示输入密码错误后的画面void ok(void);//功能:显示输入密码正确后的画面void new_password(void);//功能:显示输入新密码的画面void enter_again(void);//功能:显示再次输入新密码的画面void enter_error(void);//功能:显示两次输入的密码不一样后的画面void modify_success(void);//功能:显示更改成功后的画面void welcome(void);  //功能:显示欢迎画面void wtite_1602com(uchar com);void write_1602dat(uchar dat); /*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/ voiddelay(uchar n) {    unsigned char i,x,y;       for(i=0;i<n;i++){for(x=0;x<10;x++)for(y=0;y<33;y++);} } /*****************************************************函数功能:延时1ms***************************************************/void delay1(uchar n){   unsigned char i,j;          for(i=0;i<n;i++){  for(j=0;j<10;j++)delay(10);}       } /*****************************************************函数功能:定时器子函数,调用该函数可以计时***************************************************/ voidtime( ){ TMOD = 0x01;        //定时器0,工作方式1                  TH0 = (65536-50000)/256;                  TL0 = (65536-50000)%256;   //50ms中断一次                  EA = 1;ET0 = 1;TR0 = 1;} /*****************************************************函数功能:定时函数,在一段时间内没有键按下则关闭显示器***************************************************/void time_1( ) interrupt 1{  TH0 = (65536-65536)/256;TL0 = (65536-65536)%256;time_50ms++;       if(time_50ms==20){time_1s++;time_50ms=0;}       if(time_1s==20){write_1602com(0x01);write_1602com(0x0c);                     time_1s=0;while(1);}} //***********************************//功能:使蜂鸣器发音//***********************************void warn(){P37=1;NOP3();NOP3();NOP3();              P37=0;NOP3();NOP3();NOP3();} //***********************************//函数名:bit lcdbusy()//功能:检测忙标志//***********************************bit lcdbusy(){bit result;  rs=0;rw=1;e=1;       delay(1);       result=(bit)(P0&0x80);e=0;       returnresult;}//************************************************//函数名:写命令函数//功能:调用该函数可能定义1602液晶显示器的各种命令//************************************************void write_1602com(uchar com){       while(lcdbusy());       e=0; rw=0;      rs=0;       P0=com; delay(1);       e=1; delay(1);e=0;}//*************************************************//函数名:写数据函数//功能:调入该函数可以向1602液晶显示器输入数据//*************************************************void write_1602dat(uchar dat){       while(lcdbusy());e=0;rw=0;rs=1;       P0=dat;delay(1);e=1;delay(1);e=0;}//**************************************************//函数名:初始化函数//功能:对1602液晶显示器进行初始化//**************************************************void initinal(void){       rs=0;e=0;       write_1602com(0x38);     //数据总线为8,显示2,0=5×7点阵/每字符       write_1602com(0x0f);    //显示功能开,有光标,光标不闪烁       write_1602com(0x06);    //显示光标       write_1602com(0x01);    //清屏       write_1602com(0x80);}//*********************************************//函数名:显示函数//功能:显示输入密码//*********************************************void enter_password(void){ uchar j;       initinal();write_1602com(0x80);       for(j=0;j<15;j++){write_1602dat(table2[j]);delay(10);}       write_1602com(0xc0+0x0a);}//********************************************//函数名:显示函数//功能:显示输入密码错误后的画面//********************************************void password_error(void){uchar j;       write_1602com(0x0c); //显示功能开,无光标       write_1602com(0x80);//显示位置第一行第一列       write_1602com(0x01);       for(j=0;j<15;j++){write_1602dat(table4[j]);delay(10);}}//******************************************//函数名:显示函数//功能:显示输入旧密码的画面//******************************************void old_password(void){uchar j;       initinal();write_1602com(0x80);       for(j=0;j<14;j++){write_1602dat(table5[j]);delay(10);}       write_1602com(0xc0+0x0a);}//******************************************//函数名:显示函数//功能:显示输入新密码的画面//******************************************void new_password(void){uchar j;initinal();       write_1602com(0x80);       for(j=0;j<14;j++){write_1602dat(table6[j]);delay(10);}       write_1602com(0xc0+0x0a);}//******************************************//函数名:显示函数//功能:显示再次输入新密码的画面//******************************************void enter_again(void){uchar j;initinal();       write_1602com(0x80);       for(j=0;j<12;j++){write_1602dat(table7[j]);delay(10);}       write_1602com(0xc0+0x0a);}//********************************************//函数名:显示函数//功能:显示两次输入的密码不一样后的画面//********************************************void enter_error(void){uchar j;       write_1602com(0x0c); //显示功能开,无光标       write_1602com(0x80);//显示位置第一行第一列       write_1602com(0x01);       for(j=0;j<12;j++){write_1602dat(table8[j]);delay(10);}}//******************************************//函数名:显示函数//功能:显示更改成功之后的画面//******************************************void modify_success(void){ucharj;write_1602com(0x0c);       write_1602com(0x80);write_1602com(0x01);       for(j=0;j<15;j++){write_1602dat(table9[j]);delay(10);}}//******************************************//函数名:显示函数//功能:显示欢迎画面//******************************************void welcome(void){       ucharj;       write_1602com(0x0c); //显示功能开,无光标       write_1602com(0x80);//显示位置第一行第4       write_1602com(0x01);       write_1602com(0x80);       for(j=0;j<13;j++){write_1602dat(table10[j]);delay(10);}}//**************************************************//函数名:键盘识别函数//功能:通过扫描对键盘进行识别//**************************************************uchar key_num(){uint temp,b;while(1){P1=0xfe;             //开始扫描第一行              temp=P1;              temp=temp&0xf0;              if(temp!=0xf0){delay(1);temp=P1;b=temp;temp=temp&0xf0;                     if(temp!=0xf0){                     while(temp!=0xf0){temp=P1;temp=temp&0xf0;}                     switch(b){case0xee: return '4';break;                            case0xde: return '3';break;                            case0xbe: return '2';break;                            case0x7e: return '1';break;}}}              P1=0xfd;             //扫描第二行              temp=P1;              temp=temp&0xf0;              if(temp!=0xf0){delay(1);temp=P1;b=temp;temp=temp&0xf0;                     if(temp!=0xf0){                     while(temp!=0xf0){temp=P1;temp=temp&0xf0;}                     switch(b){case0xed: return '8';break;                            case0xdd: return '7';break;                            case0xbd: return '6';break;                            case0x7d: return '5';break;}}}              P1=0xfb;             //扫描第三行              temp=P1;              temp=temp&0xf0;              if(temp!=0xf0){delay(1);temp=P1;b=temp;temp=temp&0xf0;                     if(temp!=0xf0){                            while(temp!=0xf0){temp=P1;temp=temp&0xf0;}                            switch(b){case 0xeb: return 'b';break;                                   case0xdb: return 'a';break;                                   case0xbb: return '0';break;                                   case0x7b: return '9';break;}}}}} /****************************************只扫描第四行,禁止数字键输入****************************************/uchar key_gn(){uint temp,b;while(1){P1=0xf7;             //扫描第四行              temp=P1;              temp=temp&0xf0;              if(temp!=0xf0){delay(1);temp=P1;b=temp;temp=temp&0xf0;                     if(temp!=0xf0){                     while(temp!=0xf0){temp=P1;temp=temp&0xf0;}                            switch(b){case0xe7: return 'f';break;                                   case0xd7: return 'e';break;                                   case0xb7: return 'd';break;                                   case0x77: return 'c';break;}}} }} /****************************************密码函数:将输入的密码写放进数组****************************************/uchar enter(uchar password[]){uchARM=0,j,back=0;       for(m=0;;){j=key_num();time_50ms=0;time_1s=0;              if(j>='0'&&j<='9'&&m<6){write_1602com(0x06);password[m]=j;    m++;                     write_1602dat('*');}                if(j=='a'){password[m+1]='';return1;}      if(j=='b'){if(m>0){write_1602com(0x11);write_1602dat(0x20);                     write_1602com(0x11);password[m]='';m--;}}}}/******************************************启动I2C总线函数******************************************/void Start(){   SCL=1;                     SDA=1;NOP3();                     SDA=0;NOP3();                     SCL=0;}/******************************************I2C停止******************************************/void Stop(){   SDA=0;                     SCL=1;NOP3();                     SDA=1;NOP3();}/******************************************发送应答位函数******************************************/void CHECK_ACK(){   SDA=0;NOP3();                            SCL=1;NOP3();                            SCL=0;NOP3();                            SDA=1;}/******************************************发送非应答位函数******************************************/void CHECK_NACK(){       SDA=1;NOP3();                            SCL=1;NOP3();                            SCL=0;NOP3();                            SDA=0;} /******************************************I2C初始化******************************************/void Init_24cxx(){        SDA=1;NOP3();                            SCL=1;NOP3();}/******************************************I2C函数******************************************/uchar I2C_Read(){       uchari,temp;temp=0;       SDA=1;SCL=0;       for(i=0;i<8;i++){                 temp=temp<<1;SCL=1;NOP3();              if(SDA==1){temp=temp+1;}NOP3();              SCL=0;          }              returntemp;}/******************************************I2C函数******************************************/void I2C_Write(uchardate1){       uchari,temp;temp=date1;       SCL=0;       for(i=0;i<8;i++){              SDA=(bit)(temp&0x80);              SCL=1;NOP3();SCL=0;              temp=temp<<1;}NOP3();}/******************************************写相应地址的数据******************************************/void Write_add(uint address,uchar date1){       ucharaddrh,addrl;       addrh=address>>8;       addrl=address%256;       EA=0;       Start();       I2C_Write(0xa0);//发送命令字+芯片编号+P0+W       CHECK_ACK();       I2C_Write(addrh);//发高位地址       CHECK_ACK();       I2C_Write(addrl);//发低位地址       CHECK_ACK();       I2C_Write(date1);//发送数据       CHECK_ACK();       Stop();//停止       EA=1;}/******************************************读相应地址的数据******************************************/uchar Read_add(uint address){       ucharaddrh,addrl,temp;       addrh=address>>8;       addrl=address%256;       EA=0;       Start();       I2C_Write(0xa0);       CHECK_ACK();       I2C_Write(addrh);//发高位地址       CHECK_ACK();       I2C_Write(addrl);//发低位地址       CHECK_ACK();       Start();       I2C_Write(0xa1);       CHECK_ACK();       temp=I2C_Read();       CHECK_NACK();       Stop();       EA=1;       returntemp;}/******************************************写数据函数:将数组写入AT24C02******************************************/void Write_nums(uchar table[]){               int x=10;while(x--){     Write_add(0x00,table[0]);Write_add(0x00,table[0]);                     Write_add(0x10,table[1]);Write_add(0x10,table[1]);                     Write_add(0x20,table[2]);Write_add(0x20,table[2]);                     Write_add(0x30,table[3]);Write_add(0x30,table[3]);                     Write_add(0x40,table[4]);Write_add(0x40,table[4]);                     Write_add(0x50,table[5]);Write_add(0x50,table[5]);}  }/****************************************主函数****************************************/void main(){   uchar k=0,j=0;                     //     Write_nums(mima);                     mima[0]=Read_add(0x00);mima[1]=Read_add(0x10);                     mima[2]=Read_add(0x20);mima[3]=Read_add(0x30);                     mima[4]=Read_add(0x40);mima[5]=Read_add(0x50);                     time();    initinal();       for(k=0;k<6;k++){mima0[k]=kong[k];}       for(;strcmp(mima,mima0)!=0;){enter_password();enter(mima0);       if(strcmp(mima,mima0)==0||strcmp(table1,mima0)==0){              welcome();P36=0;delay1(20);if(strcmp(table1,mima0)==0)break;}              else{password_error();for(k=0;k<6;k++){mima0[k]=kong[k];}        i++;delay1(20);                           if(i>=5){write_1602com(0x01);write_1602com(0x0c);while(1)warn();}}}       while(1){      j=key_gn();time_50ms=0;time_1s=0;                     if(j=='c'){  for(k=0;k<6;k++){mima1[k]=kong[k];}                            for(k=0;k<6;k++){mima2[k]=kong[k];}                            for(k=0;k<6;k++){mima3[k]=kong[k];}                            for(;strcmp(mima,mima1)!=0;){                            old_password();                            enter(mima1);              if(strcmp(mima,mima1)==0||strcmp(table1,mima1)==0){                            new_password();enter(mima2);                            enter_again();enter(mima3);                     if(strcmp(mima2,mima3)==0){                            modify_success();                     for(k=0;k<6;k++){mima[k]=mima2[k];}                            Write_nums(mima);welcome();break;}                     else{enter_error();delay1(20);welcome();break;}}                   else{password_error();delay1(20);i++;       if(i>=5){write_1602com(0x01);write_1602com(0x0c);while(1)warn();}} }}                     if(j=='d')P36=1;     }}
include.doc 下载积分: 积分 -1 分
69.5 KB, 下载次数: 22, 下载积分: 积分 -1 分 程序
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
17条回答
chenwei6991627
1楼-- · 2019-07-16 16:58
那只能说明是你的程序问题了
chinazhangfeng
2楼-- · 2019-07-16 18:47
THEB 发表于 2016-6-5 10:18
我存到at24c02里也不行吗?

        for(;strcmp(mima,mima0)!=0;)
        {
                 enter_password();
             enter(mima0);
            if(strcmp(mima,mima0)==0||strcmp(table1,mima0)==0)
                {
                   welcome();
                   P36=0;
                   delay1(20);
                   if(strcmp(table1,mima0)==0)
                break;
                }
                else
                {
                          password_error();
              for(k=0;k<6;k++)
                  {
                         mima0[k]=kong[k];
                  }
                  
         i++;
                 delay1(20);
                 if(i>=5){write_1602com(0x01);
                   write_1602com(0x0c);
                   while(1)
                         warn();
                   }
                }
        }

这段什么意思?没看懂,你这代码写的看着很累
chinazhangfeng
3楼-- · 2019-07-16 23:04
THEB 发表于 2016-6-5 10:17
我这不是有at24c02吗?怎么还存不住

我当时没注意看。
THEB
4楼-- · 2019-07-17 04:30
 精彩回答 2  元偷偷看……
THEB
5楼-- · 2019-07-17 04:56
chinazhangfeng 发表于 2016-6-6 00:25
for(;strcmp(mima,mima0)!=0;)
        {
                 enter_password();

开锁嘛,输入的跟读取的at24c里的一样时开锁,如果开锁一段时间后没操作,进入节能程序,
风之纱
6楼-- · 2019-07-17 06:22
写一段代码,上点以后匹配E2P rom 数值是否为 null ,如果!=null ,取值后再显示 ,试试看

一周热门 更多>