找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4962|回复: 8
收起左侧

基于51单片机密码锁程序,C语言(汇编写不出)

[复制链接]
ID:71922 发表于 2015-1-10 02:13 | 显示全部楼层 |阅读模式
软件部分(程序清单):
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned  int
#define SET  10
#define ENTER 11
#define AT  0 // 密码保存在E2PROM中的地址
//#define PASSWORD_NUM 6
#define PWY 0xA8 // 密码存在标志
typedef struct{
uchar flag;
uchar codes[6];
}PASSWORD;
PASSWORD password;
uchar buf[6];
uchar code table[]="______";
sbit rs=P2^5; //LCD1602
sbit rw=P2^6;
sbit en=P2^7;
sbit scl=P1^5;   //24C02
sbit sda=P3^6;
sbit buzz=P2^3;   //buzz  
//uchar temp;
void delay2(uint cnt);
void delay1();
void delay(uint z);
void buzzer();
#include <keyscan.h>
#include <LCD1602.h>
#include<EEPROM(24C02).h>

/***********蜂鸣器发声************/
void buzzer()
{
  uint i;
  for(i=0;i<80;i++)
  {
    buzz=~buzz;
delay2(80);
  }
  buzz=1;
}
/***********输入密码************/
void input_password(uchar *buf)
{
uchar i,k_num;
write_com(0x80+0x40);
for(i=0;i<6;i++)  //速度很快,底下写密码时不用for循环
    {
    write_data(table[ i]);
    delay(20);
    }
    i=0;    //  密码的初始位置
while(i<6)
   {
    k_num=keyscan();
      if(k_num==-1)
       continue;
   else
      if((k_num>=0)&&(k_num<=9))
     {
     buf[ i]=k_num;
      write_string(0x80+0x40+i,"*");
      i++;
         }
     }
   while(keyscan()!=ENTER);
}
/***********检测密码************/
bit check_buf(uchar *buf1,uchar *buf2)
{
uchar i;
for(i=0;i<6;i++)
{
  if(buf1[ i]!=buf2[ i])
     return 1;   
}
return 0;
}
/***********主程序************/
void main()
{
lcd1602_init();
i2c_init();
  read_buf((uchar *)&password,AT,sizeof(PASSWORD));
    if(password.flag==PWY)
   {
   while(1)
     {
  write_string(0x80,"input password: ");
  write_string(0x80+0x40,"         ");
  input_password(buf);
  /*if(!check_buf(buf,password.codes))
     break;
  write_string(0x80,"Password Error! ");
  write_string(0x80+0x40,"         ");*/
  while(keyscan()==-1);
  }
   }
   while(1)
{
  write_string(0x80, "Hello, welcome! ");
  write_string(0x80+0x40, "Please set code");
  while (keyscan()!= SET);
  
  write_string(0x80, "New password:   ");
  write_string(0x80+0x40, "                ");
  input_password(buf);
  
  write_string(0x80, "Input again:    ");
  write_string(0x80+0x40, "                ");
  input_password(password.codes);
  if (!check_buf(buf, password.codes))
  {
   password.flag = PWY;
   if (!write_buf((uchar *)&password, AT, sizeof(PASSWORD)))
   {
    write_string(0x80, "Password        ");
    write_string(0x80+0x40, "Successfully set");
    while (keyscan()==-1);
    continue;
   }
  }
  
  write_string(0x80, "Password        ");
  write_string(0x80+0x40, "set failed      ");
  while(keyscan()==-1);
}
}
void delay2(uint cnt)//cnt是计数器(counter)
{
while(cnt--);
}
void delay1() //微秒级延时函数,大概4~5微秒
{;;}
void delay(uint z)
{
  uint x,y;
   for(x=z;x>0;x--)
     for(y=110;y>0;y--);
}
/***********EEPROM(24C02)存储器************/
void start()  //开始信号
{
  sda=1;
  delay1();
  scl=1;
  delay1();
  sda=0;
  delay1();
}
void stop()  //停止
{
  sda=0;
  delay1();
  scl=1;
  delay1();
  sda=1;
  delay1();
}
void respons()//应答
{
  uchar i;
  scl=1;   //高电平期间读取信号
  while((sda==1)&&(i<250))i++;//同时满足SDA等于1和i小于250两个条件的时候i=i+1,即i自动加1.否则跳出循环
  scl=0;
  delay1();
}

void i2c_init()
{
sda=1;
delay1();
scl=1;
delay1();
}
void write_byte(uchar dat)
{
uchar i,temp2;
temp2=dat;
for(i=0;i<8;i++)
   {
    temp2=temp2<<1;
scl=0;
delay1();
sda=CY;   //PSW中的最高位
delay1();
scl=1;
delay1();
   }
   scl=0;
   delay1();
   sda=1;
   delay1();
}
uchar  read_byte()
{
  uchar i,j,k;
  scl=0;
  delay1();
  sda=1;
  delay1();
  for(i=0;i<8;i++)
      {
   scl=1;
   delay1();
   if(sda==1)
      j=1;
   else
       j=0;
  k=(k<<1)|j;
  scl=0;
  delay1();
   }
return k;
}
bit write_add(uchar address,uchar dat)
{
start();
write_byte(0xa0);//控制字节
respons();
write_byte(address);   //地址
respons();
write_byte(dat);      //数据
respons();
stop();
return 0;
}
uchar read_add(uchar address)
{
uchar dat;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
dat=read_byte();
stop();
return 0;
}
uchar write_buf(uchar *buf,uchar address,uchar length)
          //*buf--代写数据 ,address--eeprom地址,length--数据长度
{
  while(length--)
     {
     if(write_add(address++,*buf++))
     return 1;
  }
   return 0;
}
uchar read_buf(uchar *buf,uchar address,uchar length)
          //*buf--代写数据 ,address--eeprom地址,length--数据长度
{
while(length--)
     {
     if(read_add(address++))
       buf++;
     return 1;
  }
   return 0;
}
/********键盘扫描*********/
uchar keyscan()
{
  uchar temp;
  uchar num=-1;
  P1=0xfe;
  temp=P1;
  temp=temp&0xf0;
   if(temp!=0xf0)
     {
    delay(5);
    temp=P1;
       temp=temp&0xf0;
    if(temp!=0xf0)
       {
     temp=P1;
     switch(temp)
       {
      case 0xee:num=1;break;
      case 0xde:num=2;break;
               case 0xbe:num=3;break;
      case 0x7e:num=-1;break;
    }
     while(temp!=0xf0)
       {
      temp=P1;
      temp=temp&0xf0;
    }
   if(num>=0)
           buzzer();
    }
  }
   P1=0xfd;
  temp=P1;
  temp=temp&0xf0;
   if(temp!=0xf0)
     {
    delay(5);
    temp=P1;
       temp=temp&0xf0;
    if(temp!=0xf0)
       {
     temp=P1;
     switch(temp)
       {
      case 0xed:num=4;break;
      case 0xdd:num=5;break;
               case 0xbd:num=6;break;
      case 0x7d:num=-1;break;
    }
     while(temp!=0xf0)
       {
      temp=P1;
      temp=temp&0xf0;
    }
   if(num>=0)
           buzzer();
    }
  }
P1=0xfb;
  temp=P1;
  temp=temp&0xf0;
   if(temp!=0xf0)
     {
    delay(5);
    temp=P1;
       temp=temp&0xf0;
    if(temp!=0xf0)
       {
     temp=P1;
     switch(temp)
       {
      case 0xeb:num=7;break;
      case 0xdb:num=8;break;
               case 0xbb:num=9;break;
      case 0x7b:num=-1;break;
    }
     while(temp!=0xf0)
       {
      temp=P1;
      temp=temp&0xf0;
    }
     if(num>=0)
           buzzer();
    }
  }
  P1=0xf7;
  temp=P1;
  temp=temp&0xf0;
   if(temp!=0xf0)
     {
    delay(5);
    temp=P1;
       temp=temp&0xf0;
    if(temp!=0xf0)
       {
     temp=P1;
     switch(temp)
       {
      case 0xe7:num=0;break;
      case 0xd7:num=SET;break;
               case 0xb7:num=ENTER;break;
      case 0x77:num=-1;break;
    }
     while(temp!=0xf0)
       {
      temp=P1;
      temp=temp&0xf0;
    }
     if(num>=0)
           buzzer();
    }
  }
  return num;
}
/***********LCD1602液晶写指令************/
write_com(uchar com)
{
  rs=0;
  rw=0;
  P0=com;
  delay(5);
  en=1;
  delay(5);
  en=0;
}
/***********LCD1602液晶写数据************/
write_data(uchar date)
{
  rs=1;
  rw=0;
  P0=date;
  delay(5);
  en=1;
  delay(5);
  en=0;
}
/***********LCD1602液晶初始化************/
void lcd1602_init()
{
   en=0;
   write_com(0x38);
   write_com(0x0c);
   write_com(0x06);
   write_com(0x01);
}
void write_string(uchar add_start,uchar *p)
{
  write_com(add_start);
  while(*p!='\0') // '\0'就是空操作符
    {
  write_data(*p++);//字符串没结束,继续指向下一个地址
}  
}


回复

使用道具 举报

ID:76140 发表于 2015-4-4 22:34 | 显示全部楼层
仿真图有不?
回复

使用道具 举报

ID:208740 发表于 2017-6-7 11:38 | 显示全部楼层
仿真图就很强了
回复

使用道具 举报

ID:393296 发表于 2018-9-4 09:35 | 显示全部楼层
LCD1602和LCD12864有什么区别吗
回复

使用道具 举报

ID:395557 发表于 2018-9-10 17:51 | 显示全部楼层
请问这个是独立按键使用的吗?
回复

使用道具 举报

ID:476644 发表于 2019-2-15 11:57 | 显示全部楼层
仿真图
回复

使用道具 举报

ID:397287 发表于 2019-2-26 11:36 | 显示全部楼层
请问有数码管显示的吗
回复

使用道具 举报

ID:690948 发表于 2020-2-9 21:24 来自手机 | 显示全部楼层
学习了
回复

使用道具 举报

ID:690948 发表于 2020-2-13 08:32 来自手机 | 显示全部楼层
又看了好几遍,不懂指针
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表