
主要功能:当输入密码时,只显示“*”,当密码位数输入完毕按下确认键时,对输入的密码与设定的密码进行比较,若密码正确,则门开,此处用绿色LED发光二极管亮一秒钟做为提示,;若密码不正确,禁止按键输入3秒,同时绿色发光二极管亮;若在3秒之内仍有按键按下,则禁止按键输入3秒被重新禁止。
#include #define uint unsigned int #define uchar unsigned char #define KEY P3 //键盘输入端口 #define No_key 20 //无按键时的返回值 #define lcddata P2 //1602的数据输入端口 sbit lcden= P1^2; sbit lcdrs= P1^0; sbit lcdrw= P1^1; sbit light= P1^3; sbit light1= P1^4; uchar j ; //用来统计输入 个数的全局变量 uchar aa; //用来在定时器中计数的 全局变量 uchar code table[]= " Hello!"; uchar code table1[]=" OK! " ; uchar code table2[]="Enter please:" ; uchar code key_table[16] = { 1,2,3,10, 4,5,6,11, 7,8,9,12, 0,13,14,15 }; uchar password[]={2,0,1,0,9,3} ; //设定初始密码 uchar save[6]; //保存输入的数据 uchar conflag ; //确认标志 uchar lockflag; //锁键盘标志 uchar startflag; //开始标志 void delay(uint z); //延时子函数 void wright_com(uchar com); //写指令函数 void wright_data(uchar date) ; //写数据函数 void init(); //初始化 void display_OK(); // 显示OK void delete(); //删除输入的最后一个数 uchar keyscan() ; //带返回值的键盘扫描程序 void enter_code(uchar t); //输入密码函数,把输入的数据存入数组中并在屏幕上显示相应的东西, void confirm(); //确认密码对不对,把输入的数据与密码逐一对比,完全一样刚正确, void succeed_an(); //输入密码成功时的 响应, void fail_an(); //输入密码 失败时 响应 void lockkey(); //锁键盘三秒 void alarm(); //发出警报声 void reset(); //复位函数 void display_enter(); //显示输入 void main(void) { uchar temp; init(); while(1) { if(lockflag) { temp=keyscan(); // 锁键期间也要进行键盘扫描 if(temp!=No_key) //重新记时三秒 { aa=0; //重新在定时器中计数 } } else { temp=keyscan(); //反复扫描输入,等待随时输入 if(temp!=No_key) //有按键按下才进行下面的操作 { if(temp==10) { reset(); startflag=1; //开始标志置位 } if(startflag) { enter_code(temp); //每扫描一次键盘就要进行一次处理,保存输入的数值 if(temp==13) //按下确认键盘就要进行密码确认 { confirm(); //进行确认判断 if(conflag) //密码确认为正确 { succeed_an(); //密码正确,作出相应的反应 } else { fail_an(); //密码错误,作相应反应 } } if(temp==14) { delete(); //作删除操作 } } } } } } /****** 显示enter********/ void display_enter() { uchar num; wright_com(0x80); for(num=0;num<13;num++) { wright_data(table2[num]); } } /****** 显示OK********/ void display_OK() { uchar num; wright_com(0x80); for(num=0;num<13;num++) { wright_data(table1[num]); } } /****** 删除最后一个********/ void delete() { wright_com(0x80+0x40+j); //确定删除对象 wright_data(' '); //显示空格即为删除 save[--j]=0; //删除后数据清零 wright_com(0x80+0x40+j); //为下次输入数据时写好位置,必须是在最后一个后面 } /****** 对各种变量进行复位********/ void reset() { uchar num; display_enter(); wright_com(0x80+0x40); //擦除屏幕上的显示 for(num=0;num<6;num++) { save[num]=0; //对输入的数值进行清零 wright_data(' '); //显示的是空格 } wright_com(0x80+0x40); //下次再输入时可以又从起始位置输入 lockflag=0; //各种变量要清零回起始状态 conflag=0; j=0; } /****** 输入密码正确进行响应********/ void succeed_an() { light=0; //灯亮 display_OK(); //显示成功 delay(1000); light=1; //灯灭 } /****** 输入密码错误进行响应********/ void fail_an() { alarm(); lockkey(); } /****** 发出警报声**********/ void alarm() //这个以后再扩展它 { } /******锁键盘三秒************/ void lockkey() { lockflag=1; } /******输入密码并在屏幕上显示星号******/ void enter_code(uchar t) { if(t>=0&&t<10) { if(j==0) { wright_com(0x80+0x40) ; //第一输入时要先写入地址指令,否则无法显示 wright_data('*') ; } else { wright_data('*') ;//不是第一个输入则不用再写地址 } save[j++]=t; //保存输入的数据 } } /******校对密码以确定是不是正确的**********/ void confirm() { uchar k; for(k=0;k<6;k++) { if(password[k]!=save[k]) //对数组中的内容进行逐一比较,一旦有数据不对马上退出循环 { break; } } if(k==6) //要是条件退出的话说明六个数全对密码 { conflag=1; // 进行标志密码正确 } } /******中断服务程序**********/ void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; //重装初值 if(lockflag) { aa++; light1=0; if(aa>=60) //三秒到了 { aa=0; //清零可以方便下次再使用 light1=1; //关闭警报 lockflag=0; //标志清零解除键锁,方便下次使用 } } } /******初始化***********/ void init() { uchar num; /*****定时器初始化****/ TMOD=1; TH0=(65536-50000)/256; TL0=(65536-50000)%256; ET0=1; EA=1; //开启总中断 TR0=1;//把定时器关闭 /****1602初始化******/ lcdrw=0; //这个必须要置 零,否则无法正常显示 lcden=0; wright_com(0x38) ; //初始化 wright_com(0x0c) ; //打开光标 0x0c不显示光标 0x0e光标不闪,0x0f光标闪 wright_com(0x01) ; //清显示 wright_com(0x80) ; for(num=0;num<9;num++) { wright_data(table[num]); delay(1); } } /******1602写入指令************/ void wright_com(uchar com) { lcdrs=0; lcddata=com; delay(1); lcden=1; delay(1); lcden=0; } /******1602写入数据***********/ void wright_data(uchar date) { lcdrs=1; lcddata=date; delay(1); lcden=1; delay(1); lcden=0; } /******延时函数************/ void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--) ; } /**********4x4矩阵键盘扫描函数*********/ uchar keyscan() { uchar temp,num=No_key; //num的初值要为无键盘按下时的返回值 /*********扫描第一行****************/ KEY=0xfe; temp=KEY; temp=temp&0xf0; //读出高四位 while(temp!=0xf0) { delay(5); //延时消抖 temp=KEY; temp=temp&0xf0; while(temp!=0xf0) //确认确实有按键按下 { temp=KEY; switch(temp) //根据这八个电平可以确定是哪个按键按下 { case 0xee:num=1; break; case 0xde:num=2; break; case 0xbe:num=3; break; case 0x7e:num=10; break; } while(temp!=0xf0) //等待松手 { temp=KEY; temp=temp&0xf0; } } } /*********扫描第二行***************/ KEY=0xfd; temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { temp=KEY; switch(temp) { case 0xed:num=4; break; case 0xdd:num=5; break; case 0xbd:num=6; break; case 0x7d:num=11; break; } while(temp!=0xf0) { temp=KEY; temp=temp&0xf0; } } } /*********扫描第三行****************/ KEY=0xfb; temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { temp=KEY; switch(temp) { case 0xeb:num=7; break; case 0xdb:num=8 ; break; case 0xbb:num=9; break; case 0x7b:num=12; break; } while(temp!=0xf0) { temp=KEY; temp=temp&0xf0; } } } /*********扫描第四行****************/ KEY=0xf7; temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=KEY; temp=temp&0xf0; while(temp!=0xf0) { temp=KEY; switch(temp) { case 0xe7:num=0; break; case 0xd7:num=13; break; case 0xb7:num=14; break; case 0x77:num=15; break; } while(temp!=0xf0) { temp=KEY; temp=temp&0xf0; } } } return num; } . .
