基于AT89C51单片机电子密码锁#includemain.h/********************LCDPARTSTART*******************************///5ms延时voidDelay5Ms(void){unsignedintTempCyc=5552;while(TempCyc--);}//读状态unsignedcharReadStatusLCM(void){LCM_Data=0xFF;LCM_RS=0;LCM_RW=1;LCM_E=0;LCM_E=0;LCM_E=1;Delay5Ms();while(LCM_Data&Busy);//检测忙信号return(LCM_Data);}//写数据voidWriteDataLCM(unsignedcharWDLCM){ReadStatusLCM();//检测忙LCM_Data=WDLCM;LCM_RS=1;LCM_RW=0;LCM_E=0;//若晶振速度太高可以在这后加小的延时LCM_E=0;//延时LCM_E=1;}//写指令voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测{if(BuysC)ReadStatusLCM();//根据需要检测忙LCM_Data=WCLCM;LCM_RS=0;LCM_RW=0;LCM_E=0;LCM_E=0;LCM_E=1;}//读数据unsignedcharReadDataLCM(void){LCM_RS=1;LCM_RW=1;LCM_E=0;LCM_E=0;LCM_E=1;return(LCM_Data);}voidLCMInit(void)//LCM初始化{LCM_Data=0;WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,1);//显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1);//关闭显示WriteCommandLCM(0x01,1);//显示清屏WriteCommandLCM(0x06,1);//显示光标移动设置WriteCommandLCM(0x0C,1);//显示开及光标设置}//按指定位置显示一个字符,x表示列,Y表示行voidLCD_write_char(unsignedcharX,unsignedcharY,unsignedcharDData){Y&=0x1;X&=0xF;//限制X不能大于15,Y不能大于1if(Y)X|=0x40;//当要显示第二行时地址码+0x40;X|=0x80;//算出指令码WriteCommandLCM(X,0);//这里不检测忙信号,发送地址码WriteDataLCM(DData);}//按指定位置显示一串字符voidLCD_write_string(unsignedcharX,unsignedcharY,unsignedcharcode*DData){unsignedcharListLength;ListLength=0;Y&=0x1;X&=0xF;//限制X不能大于15,Y不能大于1while(*DData)//若到达字串尾则退出'\0'就是0{if(X=0xF)//X坐标应小于0xF{LCD_write_char(X,Y,*DData);//显示单个字符DData++;X++;}}}/************/#includereg52.h#includemath.h#defineucharunsignedchar#defineuintunsignedint/********************LCDPARTSTART*******************************/voiddelay(uintz)//延时{uintx,y;for(x=z;x0;x--)for(y=124;y0;y--);}sbite=P2^5;sbitrw=P2^6;sbitsr=P2^7;ucharcodename[]=zxs;ucharcodename1[]=zcf;ucharcodename2[]=zx;voidwrite_com(ucharcom){intrs;rs=0;P0=com;delay(5);e=1;delay(5);e=0;}voidwrite_data(uchardate){intrs;rs=1;P0=date;delay(5);e=1;delay(5);e=0;}voidinit(){e=0;rw=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);}voiddisplay(){uchari;for(i=0;i3;i++){write_data(name[i]);}write_com(0x80+0x40);for(i=0;i3;i++){write_data(name1[i]);}}voidmain(){init();display();}#includeAT89X51.h#defineucharunsignedcharucharstarbuf[10];ucharwordbuf[8];ucharpw[8]={1,2,3,4,5,6,7,8};ucharpwbuf[8];ucharcount=0;//初始没有输入密码,计数器设为0ucharinputflag=0;//先处于密码输入状态,非密码修改状态bitenterflag=0;//没有按下确认键bitpwflag=0;//密码标志先置为0sbitwarn=P3^6;#definelcd_dataP0sbitrs=P2^7;sbitrw=P2^6;sbite=P2^5;///////////////////////LCD1602驱动程序///////////////////////voiddelay_1602(unsignedinti){while(i--);}voidenrw(){rs=0;rw=0;e=0;delay_1602(250);e=1;}write_data(ucharc){lcd_data=c;rs=1;rw=0;e=0;delay_1602(250);e=1;}init_lcd(void)//初始化{lcd_data=0x01;//清屏幕enrw();lcd_data=0x38;//数据长度为8位,双行显示,5*7字符。enrw();lcd_data=0x0c;//打开显示开关enrw();lcd_data=0x06;//地址计数递增,显示屏不移动enrw();}write_cmd(ucharm)//写命令,注意与写数据的区别{lcd_data=m;enrw();}display(ucharrow,ucharcolum,uchar*s)//行列字符写字符串,简单的指针应用{ucharp;if(row==1)p=0x82+colum-1;elsep=0xC0+colum-1;write_cmd(p);for(;*s!='\0';s++)write_data(*s);}voidlcd_display(unsignedchara,unsignedcharb,unsignedchari)//行列数{switch(i){case0:display(a,b,0);break;/*0*/case1:display(a,b,1);break;/*1*/case2:display(a,b,2);break;/*2*/case3:display(a,b,3);break;/*3*/case4:display(a,b,4);break;/*4*/case5:display(a,b,5);break;/*5*/case6:display(a,b,6);break;/*6*/case7:display(a,b,7);break;/*7*/case8:display(a,b,8);break;/*8*/case9:display(a,b,9);break;/*9*/default:break;}}/*键消抖延时函数*/voiddelay(unsignedinti){intj;for(;i0;i--)for(j=0;j100;j++);}/*键扫描函数*/ucharkeyscan(void){ucharscancode,tmpcode;P1=0xf0;//发全0行扫描码if((P1&0xf0)!=0xf0)//若有键按下{delay(2);//延时去抖动if((P1&0xf0)!=0xf0)//延时后再判断一次,去除抖动影响{scancode=0xfe;//第一行变低while((scancode&0x10)!=0)//逐行扫描{P1=scancode;//输出行扫描码if((P1&0xf0)!=0xf0)//本行有键按下{tmpcode=(P1&0xf0)|0x0f;/*返回特征字节码,为1的位即对应于行和列*/return((~scancode)+(~tmpcode));}elsescancode=(scancode1)|0x01;//行扫描码左移一位}}}return(0);//无键按下,返回值为0}/*密码比较函数*/bitpwcmp(void){bitflag;uchari;for(i=0;i8;i++){if(pw[i]==pwbuf[i])flag=1;else{flag=0;i=8;}}return(flag);}/*密码清除函数*/voidpwclk(unsignedchark){unsignedchari;for(i=0;i8;i++){wordbuf[i]=0;//数码管显示00000000starbuf[i]=0;if(k==0)pwbuf[i]=0;//用FFFFFF清除已经输入的密码elsepw[i]=0;//用FFFFFF清除已经输入的密码}}/*按键声响函数*/voidalarm(){unsignedchari;for(i=0;i200;i++){warn=!warn;delay(1);}}/*密码报警函数*/voidalarm1(){unsignedinti;for(i=0;i2000;i++){warn=!warn;delay(1);}}/*呼叫报警函数*/voidalarm2(){unsignedchari=12;unsignedchara,b;while(i0){for(a=0;a150;a++){warn=!warn;delay(1);}for(b=0;b150;b++){warn=!warn;delay(2);}i--;}}/*按键处理函数*/voidkey_conduct(unsignedchara,unsignedcharb){switch(a){case0x11://1行1列,数字0if(count8){if(b==0){starbuf[count]='*';//对应密码位上显示'*'pwbuf[count]=0;}else{pw[count]=0;wordbuf[count]=0;lcd_display(2,count+1,wordbuf[count]);}count++;}alarm();break;case0x21://1行2列,数字1if(count8){if(b==0){starbuf[count]='*';//对应密码位上显示'*'pwbuf[count]=1;}else{pw[count]=1;wordbuf[count]=1;lcd_display(2,count+1,wordbuf[count]);}count++;}alarm