单片机电子密码锁设计,采用4×4键盘实现密码的输入功能,当密码输入正确之后,锁就打开,如果输入的密码

2024-11-25 18:55:34
推荐回答(2个)
回答1:

  #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;
  }

回答2:

我有,你QQ多少,可以加我