永发信息网

基于51单片机的密码锁程序

答案:2  悬赏:40  手机版
解决时间 2021-02-01 16:45
  • 提问者网友:火车头
  • 2021-02-01 03:10
基于51单片机的密码锁程序,
三个子程序:4*4的矩阵键盘、I2C芯片、液晶屏
最好是用Keil uVision2编写的。。
要求是4*4的矩阵键盘,其中10个是数字键,还包括一个确认、一个更改密码、一个退出
最佳答案
  • 五星知识达人网友:神也偏爱
  • 2021-02-01 03:48
7a686964616fe78988e69d8331333262383637用STC52编的,下面是C程序,调试已经成功,自己看程序吧……
  #include<reg52.h>
  #include <intrins.h>

  #define uchar unsigned char
  #define uint unsigned int

  #define LCD_data P0
  sbit SDA=P3^5;
  sbit SCL=P3^4;//24C08控制口设置
  sbit LCD_RS = P3^3; //寄存器选择输入
  sbit LCD_RW = P3^6; //液晶读/写控制
  sbit LCD_EN = P3^7; //液晶使能控制
  sbit LCD_PSB = P3^2; //串/并方式控制
  sbit FM=P2^4;//蜂鸣器控制口
  sbit RS=P2^5;
  sbit T_CLK = P2^0; //实时时钟时钟线引脚 //
  sbit T_IO = P2^1; //实时时钟数据线引脚 //
  sbit T_RST = P2^2; //实时时钟复位线引脚 //
  sbit ds=P2^3;
  sbit EN=P2^6;
  sbit ZZ=P2^7;
  sbit FZ=P3^1;
  sbit ACC0=ACC^0;
  sbit ACC7=ACC^7;

  uint temp1,s_temp; //定义整形变量
  float f_temp; //定义浮点型变量

  uchar time[]=" : : ";
  uchar day[]=" 20 / / ( ) ";
  uchar temp0[]=" 温度: . 度 ";
  uchar num,num1,flag,count,a,b;
  uchar unlock_i;//解密标志位

  uchar t[4];
  uchar t1[4];

  void delay_ms(uint z)//长延时
  {
  uint x,y;
  for(x=z;x>0;x--)
  for(y=110;y>0;y--);
  }

  void delay() //短延时,大约5us
  {
  ; ;
  }
  void reshi()
  {
  if(RS==1)
  { unlock_i=1;
  }
  else
  {
  unlock_i=0;
  }
  }
  uchar code mima[]={'0','1','2','3','4','5','6','7','8','9','0','*'};

  void lcd_xieping0(uchar x,uchar y,uchar date);
  void lcd_xieping(uchar x,uchar y,uchar *str);
  /
  v_WTInputByte(ucDa);
  T_CLK = 1;
  T_RST =0;
  }
  uchar uc_R1302(uchar ucAddr)
  {
  uchar ucDa;
  T_RST = 0;
  T_CLK = 0;
  T_RST = 1;
  v_WTInputByte(ucAddr); // 地址,命令 //
  ucDa = uc_RTOutputByte(); // 读1Byte数据 //
  T_CLK = 1;
  T_RST =0;
  return(ucDa);
  }
  void Init1302(void)
  {
  v_W1302(0x8e,0x00); //控制写入WP=0
  v_W1302(0x80,0x80);
  v_W1302(0x90,0xa9);
  v_W1302(0x80,0x00); //秒
  v_W1302(0x82,0x24); //分
  v_W1302(0x84,0x12); //时
  v_W1302(0x86,0x29); //日
  v_W1302(0x88,0x10); //月
  v_W1302(0x8a,0x05); //星期
  v_W1302(0x8c,0x10); //年 //
  v_W1302(0x8e,0x80);
  }
  void donetime(void)
  {
  uchar d;
  d=uc_R1302(0x87);
  day[10]=(d&0x0f)+48;
  day[9]=((d>>4)&0x03)+48;
  d=uc_R1302(0x89);
  day[7]=(d&0x0f)+48;
  day[6]=((d>>4)&0x01)+48;
  d=uc_R1302(0x8b);
  day[13]=(d&0x07)+48;
  d=uc_R1302(0x8d);
  day[4]=(d&0x0f)+48;
  day[3]=(d>>4)+48;
  d=uc_R1302(0x81);
  time[15]=(d&0x0f)+48;
  time[14]=(d>>4)+48;
  d=uc_R1302(0x83);
  time[12]=(d&0x0f)+48;
  time[11]=(d>>4)+48;
  d=uc_R1302(0x85);
  time[9]=(d&0x0f)+48;
  time[8]=(d>>4)+48;
  }
  //**************************************************************
  // 温度检测函数
  //**************************************************************
  void dsreset(void) //18B20复位,初始化函数
  {
  uint i;
  ds=0;
  i=103;
  while(i>0)i--;
  ds=1;
  i=4;
  while(i>0)i--;
  }
  bit tempreadbit(void) //读1位函数
  {
  uint i;
  bit dat;
  ds=0;i++; //i++ 起延时作用
  ds=1;i++;i++;
  dat=ds; //读数据
  i=8;while(i>0)i--;
  return (dat);
  }
  uchar tempread(void) //读1个字节
  {
  uchar i,j,dat;
  dat=0;
  for(i=1;i<=8;i++)
  {
  j=tempreadbit();
  dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
  }
  return(dat);
  }
  void tempwritebyte(uchar dat) //向18B20写一个字节数据
  {
  uint i;
  uchar j;
  bit testb;
  for(j=1;j<=8;j++)
  {
  testb=dat&0x01; //判断最后一位是1还是0
  dat=dat>>1;
  if(testb) //写 1
  {
  ds=0;
  i++;i++;
  ds=1;
  i=8;while(i>0)i--;
  }
  else
  {
  ds=0; //写 0
  i=8;while(i>0)i--;
  ds=1;
  i++;i++;
  }
  }
  }

  void tempchange(void) //DS18B20 开始获取温度并转换
  {
  dsreset(); //初始化,每次对18B20的操作都首先要初始化
  delay_ms(1);
  tempwritebyte(0xcc); // 写跳过读ROM指令
  tempwritebyte(0x44); // 写温度转换指令
  }
  void get_temp() //读取寄存器中存储的温度数据
  {
  uchar a,b;
  dsreset(); //初始化
  delay_ms(1);
  tempwritebyte(0xcc); // 写跳过读ROM指令
  tempwritebyte(0xbe); //写读指令
  a=tempread(); //读低8位
  b=tempread(); //读高8位
  temp1=b;
  temp1<<=8; //两个字节组合为1个字
  temp1=temp1|a;
  f_temp=temp1*0.0625; //温度在寄存器中为12位 分辨率位0.0625°
  }
  //**************************************************************
  // 解密函数
  //**************************************************************
  void unlock()
  {
  uchar in,i;
  if(num==0)
  {
  lcd_xieping(0,0,"**密码锁系统** ");
  lcd_xieping(1,0,"—————————");
  lcd_xieping(2,0," 请输入密码: ");
  lcd_xieping(3,0," ");
  for(i=0;i<4;i++)
  {
  t1[i]=keyscan1();
  lcd_xieping(3,i,"*");
  num=0;
  }//输密码
  }
  in=keyscan1();
  if(in==12)//in-确定键标志位
  {
  in=0;
  num=0;
  if((t1[0]==t[0])&&(t1[1]==t[1])&&(t1[2]==t[2])&&(t1[3]==t[3]))
  {
  flag=1;//解密成功与否标志位
  //unlock_i=1;
  a=0;//功能键标志
  lcd_xieping(0,0,"**密码锁系统** ");
  lcd_xieping(1,0,"——————————");
  lcd_xieping(2,0," 密码正确! ");
  lcd_xieping(3,0," 您的身份已确认");
  delay_ms(1500);
  lcd_xieping(1,0,"————————");
  lcd_xieping(2,0,"功能 I 开锁 ");
  lcd_xieping(3,0," II修改密码");
  }
  else
  {
  flag=0;
  count++;
  if(count==3)
  {
  count=0;
  num=1;
  lcd_xieping(1,0,"——————————");
  lcd_xieping(2,0,"您的机会已用完 ");
  lcd_xieping(3,0,"对不起**无法进入");
  FM=0;
  delay_ms(1000);
  FM=1;
  }
  }
  }
  }
  //**************************************************************
  // 修改密码函数
  //**************************************************************
  void xiugaimima()
  { uchar i,j,l,im,ib;
  uchar t2[4];
  uchar t3[4];
  num=0;
  lcd_xieping(1,0,"————————");
  lcd_xieping(2,0,"请输入新密码: ");
  lcd_xieping(3,0," ");
  for(i=0;i<4;i++)
  {
  t2[i]=keyscan1();
  lcd_xieping0(3,i,mima[num]);
  num=0;
  }
  im=keyscan1();
  if(im==12)//im,in,ib,同为确定键标志位
  {
  im=0;
  num=0;
  lcd_xieping(1,0,"————————");
  lcd_xieping(2,0,"请再次输入新密码");
  lcd_xieping(3,0," ");
  for(i=0;i<4;i++)
  {
  t3[i]=keyscan1();
  lcd_xieping0(3,i,mima[num]);
  num=0;
  }
  }
  ib=keyscan1();
  if(ib==12)
  {
  ib=0;
  num=0;
  if(t2[0]==t3[0]&&t2[1]==t3[1]&&t2[2]==t3[2]&&t2[3]==t3[3])
  {
  t[0]=t3[0];
  t[1]=t3[1];
  t[2]=t3[2];
  t[3]=t3[3];
  lcd_xieping(1,0,"————————");
  lcd_xieping(2,0," 祝贺您! ");
  lcd_xieping(3,0," 密码修改成功 ");
  flag=0;
  for(j=0;j<4;j++)
  {
  l=j+1;
  write(l,t[j]);
  delay_ms(10);
  }//24C08写数据
  delay_ms(1000);
  }
  else
  {
  lcd_xieping(2,0,"两次输入密码不同");
  lcd_xieping(3,0," 密码修改失败 ");
  flag=1;
  delay_ms(500);
  }
  }
  }
  //**************************************************************
  // 显示函数
  //**************************************************************
  void xianshi()
  {
  donetime();
  tempchange();
  get_temp();
  s_temp=f_temp*100;
  temp0[7]=(s_temp/1000)+48;
  temp0[8]=(s_temp%1000/100)+48;
  temp0[10]=(s_temp%100/10)+48;
  temp0[11]=(s_temp%10)+48;
  lcd_xieping(0,0,"**密码锁系统** ");
  lcd_xieping(1,0,temp0);
  lcd_xieping(2,0,day);
  lcd_xieping(3,0,time);
  num=0;
  }
  //**************************************************************
  // 开锁函数
  //**************************************************************
  void kaisuo()
  {
  uchar i;
  lcd_xieping(2,0," 开锁中…… ");
  lcd_xieping(3,0,"——耐心等待——");
  for(i=3;i>0;i--)
  {
  FM=0;
  delay_ms(100);
  FM=1;
  delay_ms(100);
  flag=0;
  }
  dianjiZZ();
  delay_ms(10000);
  dianji_stop();
  lcd_xieping(2,0,"—开锁过程结束—");
  lcd_xieping(3,0," 请开门 ");
  delay_ms(5000);
  dianjiFZ();
  delay_ms(10000);
  dianji_stop();
  flag=0;
  }
  //**************************************************************
  // 主函数
  //**************************************************************
  void main()
  {
  uchar m;
  unlock_i=1;
  lcd_init(); //液晶初始化
  //Init1302();
  kjxs(); //开机显示
  for(m=0;m<4;m++)
  {
  t[m]=read(m+1);
  delay_ms(10);
  }//24C08读数据
  while(1)
  {
  reshi();
  if(!unlock_i)
  {
  unlock();//解密函数
  }
  else
  {
  xianshi();//时间、日期、温度显示函数
  }
  if(flag==1)
  {
  num1=0;
  a=keyscan2();
  if(a==1)
  {
  kaisuo();//开锁函数
  }
  if(a==2)
  {
  xiugaimima();//修改密码函数
  }
  }
  }
  }
全部回答
  • 1楼网友:玩世
  • 2021-02-01 04:31
  用stc52编的,下面是c程序,调试已经成功,自己看程序吧……
  #include<reg52.h>
  #include <intrins.h>

  #define uchar unsigned char
  #define uint unsigned int

  #define lcd_data p0
  sbit sda=p3^5;
  sbit scl=p3^4;//24c08控制口设置
  sbit lcd_rs = p3^3; //寄存器选择输入
  sbit lcd_rw = p3^6; //液晶读/写控制
  sbit lcd_en = p3^7; //液晶使能控制
  sbit lcd_psb = p3^2; //串/并方式控制
  sbit fm=p2^4;//蜂鸣器控制口
  sbit rs=p2^5;
  sbit t_clk = p2^0; //实时时钟时钟线引脚 //
  sbit t_io = p2^1; //实时时钟数据线引脚 //
  sbit t_rst = p2^2; //实时时钟复位线引脚 //
  sbit ds=p2^3;
  sbit en=p2^6;
  sbit zz=p2^7;
  sbit fz=p3^1;
  sbit acc0=acc^0;
  sbit acc7=acc^7;

  uint temp1,s_temp; //定义整形变量
  float f_temp; //定义浮点型变量

  uchar time[]=" : : ";
  uchar day[]=" 20 / / ( ) ";
  uchar temp0[]=" 温度: . 度 ";
  uchar num,num1,flag,count,a,b;
  uchar unlock_i;//解密标志位

  uchar t[4];
  uchar t1[4];

  void delay_ms(uint z)//长延时
  {
  uint x,y;
  for(x=z;x>0;x--)
  for(y=110;y>0;y--);
  }

  void delay() //短延时,大约5us
  {
  ; ;
  }
  void reshi()
  {
  if(rs==1)
  { unlock_i=1;
  }
  else
  {
  unlock_i=0;
  }
  }
  uchar code mima[]={'0','1','2','3','4','5','6','7','8','9','0','*'};

  void lcd_xieping0(uchar x,uchar y,uchar date);
  void lcd_xieping(uchar x,uchar y,uchar *str);
  /
  v_wtinputbyte(ucda); 
  t_clk = 1;
  t_rst =0;
  }
  uchar uc_r1302(uchar ucaddr)
  {
  uchar ucda;
  t_rst = 0;
  t_clk = 0;
  t_rst = 1;
  v_wtinputbyte(ucaddr); // 地址,命令 //
  ucda = uc_rtoutputbyte(); // 读1byte数据 //
  t_clk = 1;
  t_rst =0;
  return(ucda);
  }
  void init1302(void)
  {
  v_w1302(0x8e,0x00); //控制写入wp=0
  v_w1302(0x80,0x80);
  v_w1302(0x90,0xa9);
  v_w1302(0x80,0x00); //秒
  v_w1302(0x82,0x24); //分
  v_w1302(0x84,0x12); //时
  v_w1302(0x86,0x29); //日
  v_w1302(0x88,0x10); //月
  v_w1302(0x8a,0x05); //星期
  v_w1302(0x8c,0x10); //年 //
  v_w1302(0x8e,0x80);
  }
  void donetime(void)
  {
  uchar d;
  d=uc_r1302(0x87);
  day[10]=(d&0x0f)+48;
  day[9]=((d>>4)&0x03)+48;
  d=uc_r1302(0x89);
  day[7]=(d&0x0f)+48;
  day[6]=((d>>4)&0x01)+48;
  d=uc_r1302(0x8b);
  day[13]=(d&0x07)+48;
  d=uc_r1302(0x8d);
  day[4]=(d&0x0f)+48;
  day[3]=(d>>4)+48;
  d=uc_r1302(0x81);
  time[15]=(d&0x0f)+48;
  time[14]=(d>>4)+48;
  d=uc_r1302(0x83);
  time[12]=(d&0x0f)+48;
  time[11]=(d>>4)+48;
  d=uc_r1302(0x85);
  time[9]=(d&0x0f)+48;
  time[8]=(d>>4)+48;
  }
  /
//写指令
void write_com( uchar com )
{
 rs = 0;
 rw = 0;
 P0 = com;
 delaynms( 10 );
 en = 1;
 delaynms( 5 );
 en = 0;
}


//写数据
void write_data( uchar udata )
{
 rs = 1;
 rw = 0;
 P0 = udata;
 delaynms( 10 );
 en = 1;
 delaynms( 5 );
 en = 0;
}


//初始化LCD
void LCD_init( void )
{
 light = 0;
 en = 0;
 write_com( 0x38 );   //显示模式设置,16X2显示
 write_com( 0x0e );   //开显示,636f70797a686964616f31333262383636显示光标,光标不闪烁 
 write_com( 0x01 );   //显示清屏
 write_com( 0x06 );   //显示光标移动设置
 write_com( 0x80 );   //初始地址 
}
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯