找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3338|回复: 10
打印 上一主题 下一主题
收起左侧

完善我2017年发布的DIY电子密码锁 原理图设计,Proteus仿真和单片机源程序

[复制链接]
跳转到指定楼层
楼主
自行DIY电磁密码锁  在我的设计中有24c02存储器,在程序没用到。程序在仿真中是没有问题 我也做过实物 实物也实验成功,继电器和蜂鸣器还没有实验。按键和显示功能实现实现了。还有我的程序还有不足的地方 大家就一起讨论  我后续用密码存储器来设计,等我搞出来了在分享 我会上传我的PCB设计、仿真设计和程序!可以去抖音看实物视频:https://v.douyin.com/vWdd7F/


IMG_7651(20200401-153207).JPG (349.62 KB, 下载次数: 49)

PCB印制电路板

PCB印制电路板

IMG_7670(20200402-215553).JPG (208.14 KB, 下载次数: 51)

1602显示

1602显示

IMG_7689(20200404-080736).JPG (378.9 KB, 下载次数: 45)

PCB

PCB

IMG_7690(20200404-080746).JPG (291.65 KB, 下载次数: 57)

原理图

原理图

2020.4.3新改密码锁.7z

4.15 MB, 下载次数: 41, 下载积分: 黑币 -5

自行DIY电磁密码锁 在我的设计中没有用密码存储器 程序在仿真中是没有问题 我也做过实物 但是由于封装的问 ...

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:188940 发表于 2020-4-4 08:14 | 只看该作者
我这里还有多余的印制电路板,感兴趣的小伙伴可以联系我,我免费送板子,你只需付运费即可!
回复

使用道具 举报

板凳
ID:188940 发表于 2020-4-10 08:01 | 只看该作者
更正一下PCB设计:
1、10K可调电阻的2脚和3脚接反了,需要反过来接。
2、继电器的的1.2引脚接反了,需要反接。
3、蜂鸣器电路需要重新设计。
回复

使用道具 举报

地板
ID:188940 发表于 2020-4-10 08:06 | 只看该作者
4、还有1602的接口反了,液晶需要反插。
5、矩阵键盘的键值需要更改!(现在的程序里已修改过来)
6、液晶显示的程序后面的注释未修改,不影响程序的运行。

改天把24C02和定时模块添加到程序后,再继续更新。
回复

使用道具 举报

5#
ID:188940 发表于 2020-5-19 11:04 | 只看该作者
最近几天会更新新的PCB电路图和加了注释的程序。
回复

使用道具 举报

6#
ID:443348 发表于 2020-5-21 01:23 | 只看该作者
老哥还有板子吗?
回复

使用道具 举报

7#
ID:188940 发表于 2020-5-21 07:44 | 只看该作者

有的  你需要 我可以给你
回复

使用道具 举报

8#
ID:188940 发表于 2020-5-21 07:46 | 只看该作者
更新程序:#include<reg51.h>
#define         uchar unsigned        char
#define uint unsigned int

uchar code szjianzhibiao[]={0x77,0x7b,0x7d,
                             0xb7,0xbb,0xbd,   //矩阵数字键盘键值
                                                 0xd7,0xdb,0xdd,
                                                         0xeb};

uchar code gnjianzhibiao[]={0x7e,0xbe,0xde,          //矩阵功能键盘键值
                                                         0xee,0xed,0xe7};
                                                          
uchar code           mima[]={0x77,0x7d,0x77,0xb7,  //设定的密码
                             0x77,0x7d,0x77,0xb7};

uchar code table[]="HOLLE!  User";
uchar code table1[]="Password";
uchar code table2[]="********";
uchar code table3[]="  error!";
uchar code table4[]="  OK!   ";
uchar code table5[]="        ";         //抹除输入痕迹的空字符串
uchar code table6[]="0123456789";
uchar code table7[]="012345";

sbit  green=P3^2;  //绿灯
sbit  blue=P3^3;  //蓝灯
sbit  red=P3^4;  //红灯
sbit  bao=P1^3; //蜂鸣器
sbit  jdq=P3^7; //继电器
sbit  en=P1^2; //定义LCD1602使能端
sbit  rw=P1^1;//定义LCD1602读/写选择端
sbit  rs=P1^0;//定义LCD1602数据/命令选择端

uchar T1_NUM=0,T1_NUM1=0,T0_NUM=0,T0_NUM1=0;
uchar j=0,k=0,h=0,y=0,l=0,z=0,flag=0,flag1=0,flag2=0,p=0,d=0;

void delay (uchar del)
{
    uint i,j;
        for(i=0;i<del;i++)                   //延时程序
           for(j=0;j<130;j++)
           ;

}


void lcd_wcom(uchar com)
{       rs=0;            //选择指令寄存器      
        rw=0;            //选择写      
        P0=com;            //把命令字送入P0      
        delay(10);
                en=0;
                delay(10);            //延时一小会儿,让1602准备接收数据      
        en=1;
                delay(10);          //使能线电平变化,命令送入1602的8位数据口      
        en=0;  
}
void lcd_wdat(uchar dat)        //1602写数据函数        
{      
        rs=1;        //选择数据寄存器      
        rw=0;        //选择写      
        P0=dat;        //把要显示的数据送入P2      
        delay(10);
                en=0;
                delay(10);       //延时一小会儿,让1602准备接收数据      
        en=1;
        delay(10);         //使能线电平变化,数据送入1602的8位数据口  
        en=0;
}
void lcd_init()  
{      
lcd_wcom(0x38);       //8位数据,双列,5*7字形            
lcd_wcom(0x0c);      //开启显示屏,关光标,光标不闪烁      
lcd_wcom(0x06);    //显示地址递减,即写一个数据后,显示位置右移一位      
lcd_wcom(0x01);    //清屏
}
void xianshi()  
{
uchar n,m=0;                              
lcd_wcom(0x80+0x02);   //显示地址上排第三位            
for(m=0;m<12;m++)     //将table[]中的数据依次写入1602显示  
{               
lcd_wdat(table[m]);                        
delay(5);     
}
lcd_wcom(0x80+0x40);//显示地址为0xc4,即下排第1位     
for(n=0;n<8;n++)   //将table1[]中的数据依次写入1602显示     
  {                  
  lcd_wdat(table1[n]);            
  delay(5);      
  }
}

void xianshi1(uchar s)  
{
uchar m;                              
lcd_wcom(0x80+0x48);   //显示地址上排第九位,显示输入的*号         
for(m=0;m<s;m++)     //将table[]中的数据依次写入1602显示      
{               
lcd_wdat(table2[m]);                        
delay(1);     
}
}

void xianshi2()  
{
uchar m;                              
lcd_wcom(0x80+0x48);   //显示地址上排第九位,显示OK           
for(m=0;m<8;m++)     //将table[]中的数据依次写入1602显示      
{               
lcd_wdat(table4[m]);                        
delay(100);     
}
}

void xianshi3()  
{
uchar m;                              
lcd_wcom(0x80+0x48);   //显示地址上排第九位,显示error            
for(m=0;m<8;m++)     //将table[]中的数据依次写入1602显示      
{               
lcd_wdat(table3[m]);                        
delay(100);     
}
}


void xianshi5()
{
uchar m=0;                              
lcd_wcom(0x80+0x48);   //显示地上排第九位,清除显示                             
for(m=0;m<8;m++)     //将table[]中的数据依次写入1602显示      
{               
lcd_wdat(table5[m]);                        
delay(1);     
}   
}

void jishuqi( )
{
    TMOD=0x10;
        TH1=(65536-40000)/256;
        TL1=(65536-40000)%256;         //定时器T1,设置40ms
        ET1=1;
        EA=1;
        TR1=1;
               
}

void time1() interrupt 3
{
    TH1=(65536-40000)/256;
        TL1=(65536-40000)%256;
        T1_NUM++;
        if(T1_NUM==25)              //定时1S
        {
          T1_NUM=0;
          T1_NUM1++;  
          p++;
          lcd_wcom(0x80+0x0f);           //显示个位秒
      lcd_wdat(table6[p]);          
          }
        if(T1_NUM1==5)                           //定时5S
        {
         T1_NUM1=0;
        if(flag==1)                                  
           {
                red=~red;
            bao=1;                                  //红灯状态反转
            flag=0;
                TR1=0;
                lcd_wcom(0x80+0x0e);
      lcd_wdat(table6[d]);                  //显示十位秒
           }
          }
          if(p==10)
           {
           p=0;                                        //计时秒开始
           d++;
           if(d==6)                                //计时分开始
           d=0;
           }

}

void jishuqi1( )
{
    TMOD=0x10;
        TH0=(65536-40000)/256;
        TL0=(65536-40000)%256;                 //定时器T1
        ET0=1;
        EA=1;
        TR0=1;
       
                       
}

void time0() interrupt 1
{
    TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;          //设置50ms
        T0_NUM++;
        if(T0_NUM==100)                          //定时1S(正常来说T0_NUM应该=20就是1S,由于有误差,所以设置为100)
        {
          
           T0_NUM=0;                         
           T0_NUM1++;
           l++;
           if(l==10)
           {
           l=0;                                        //个位定时
           z++;
           if(z==6)                                //十位定时
           z=0;
           }
           if(j-1!=flag2)           //每1S检测是否有按键按下
           flag1=1;                           //没有按下,则赋值为1;
          
          
        }
        if(T0_NUM1==50)                   //定时50S
        {
           T0_NUM1=0;
                     if(flag1>0&&flag1==1)         //按键没有按下
                  {
                  flag1=0;                                 //清零
                  if(j==flag2&&P2==0xf0) //按键未操作且键盘按下次数未增加
                   {
                    red=0;
                        delay(30);
                        red=1;                                //超过50S未动作,清除数据并且清屏
                    xianshi5();
                        j=0;
                        k=0;
                   }
                  }       
        }
         
   
   
}

void key ()
{
    uchar lie,jianzhi,szjianhao,szjianpan1,gnjianhao,caijimima[7],szjianhao2[7],sign,i;
          if(flag==1)
           {
           xianshi3();
           delay(100);        //锁定键盘并且报警
           xianshi5();
          
           }
          else
          {
          P2=0xf0;
          if(P2!=0xf0)
           {                                  //按键去抖动
           delay(10);
           if(P2!=0xf0)
            {
                j=j+1; //数字按键计数
                k=k+1; //功能按键计数
                lie=P2;
                P2=0x0f;
                jianzhi=lie|P2;
                 for(i=0;i<10;i++)
                  {
                   if(jianzhi==szjianzhibiao[i])
                    {
                          szjianhao=szjianzhibiao[i];                 //对比数字按键
                          szjianpan1=i;                                                 //具体按键数字保存起来,可作用数码管显示,此可以不用理会
                          sign=0;                                                         //是数字按键按下标记
                          break;
                        }
                  }
                  for(i=0;i<6;i++)
                   {
                    if(jianzhi==gnjianzhibiao[i])
                     {
                          gnjianhao=i;                                                //对比功能按键
                          sign=1;                                                        //是功能按键按下标记
                          break;
                         }
                        }
                        while(P2!=0x0f);
                        delay(10);
                       
           }
           if(sign==0)                                                           //数字按键按下判断
                        {
                         bao=0;
                 delay(30);                                                  //蜂鸣器提示音
                 bao=1;
                         if(j==9)                                                 //连续九次输入数字按键
              {
                                xianshi3();
                                delay(30000);
                                xianshi5();
                j=0;
                                k=0;                                                 //错误提示、报警并且清除数据
                                red=0;
                                delay(150);
                                red=1;
                                for(i=0;i<8;i++)
                   caijimima[i]=0;
                          }
             else
              {
            
                           for(i=j-1;i<j;i++)
                {
                  caijimima[i]=szjianhao;                //正确输入并且暂存储密码
                                  szjianhao2[i]=szjianpan1;                //具体按键数字保存起来,可作用数码管显示,此可以不用理会
                                  green=0;
                                  delay(150);
                                  green=1;

                }
                                xianshi1(i);
              }
                         }
                        if(sign==1)                                                   //功能按键判断
                        {
                         flag1=0;
                         if(gnjianhao==3) //确认键判断
              {                          
               if(k==9)
                {
                 for(i=0;i<8;i++)
                                 {
                                  if(mima[i]==caijimima[i])
                                   {
                                   h=h+1; //对比计数
                                   }
                                   else
                                    {
                                      h=1;
                                      break;
                                    }
                                  }
                                  
                                 
                                  if(h==8)          //密码正确
                                   {
                                     k=0;
                                     j=0;
                                     h=0;
                                         blue=0;
                                         delay(150);
                                         blue=1;
                                         for(i=0;i<8;i++)
                                           caijimima[i]=0;
                                           xianshi2();
                                           delay(10000);
                                           xianshi5();                                //开锁
                                           jdq=0;
                                           delay(100);
                                           jdq=1;

                                          
                                     
                                  }

                                  if(h==1)           //密码错误
                                   {
                                     bao=0;
                                         delay(200);
                                         bao=1;
                                         y++;            //密码错误次数标记
                                         h=0;
                                         k=0;
                                         j=0;
                                         red=0;
                                         delay(150);
                                         red=1;
                                         for(i=0;i<8;i++)
                                           caijimima[i]=0;
                                           xianshi3();
                                           delay(30000);
                                           xianshi5();
                                           if(y==3)                  
                                            {
                                                  y=0;
                                                  red=0;
                                      flag=1;                 //三次密码错误,锁定键盘参数赋值
                                                  bao=0;
                              jishuqi();        //锁定10S计数开始
                                            }
                                         
                                   }
                }
               else
                            {
                                  k=0;
                                  j=0;
                                  xianshi3();//请继续输入8位完整密码后在按确认键!
                                  delay(30000);
                                  xianshi5();
                               
                                }
               }

              if(gnjianhao==2) //清零键判断
               {
                for(i=0;i<7;i++)
                 {
                   caijimima[i]=0;
                 }
                                 lcd_wcom(0x01);
                                 xianshi();
                                 k=0;
                                 j=0;
               }

              if(gnjianhao==1) //退格键判断
               {
                if(k==1&&j==1)
                 {
                                  xianshi3();//错误,请输入8位完整密码!
                                  delay(30000);
                                  xianshi5();
                               
                                   red=0;
                                   delay(200);
                                   red=1;
                                   delay(200);
                                   red=0;
                                   delay(200);
                                   red=1;
                   j=j-1;
                   k=k-1;
                 }
                if(j!=0&&k!=0)
                 {
                                   j=j-2;
                   k=k-2;
                                   xianshi5();
                                   xianshi1(j);

                 }
               }
                          if(gnjianhao==4)
                          ;
                          if(gnjianhao==5)
                          ;

                          }
                 }
       
                        
        }
}



void main ()
{  
   lcd_init();                                 //液晶初始化
   delay(30);
   xianshi();
   jishuqi1();
  while (1)
   {
   key();                                          //按键子程序
   flag2=j;                                          //将按键次数参数赋值给flag2
   if(flag2==9)                                  //超过九次,清零
   flag2=0;
   lcd_wcom(0x80+0x01);
   lcd_wdat(table6[flag2]);         //显示按键次数
   if(P2==0xf0)                                  //判断有没有按键按下
   {
   lcd_wcom(0x80+0x0f);
   lcd_wdat(table6[l]);                  //没按键按下,就显示倒计时
   lcd_wcom(0x80+0x0e);
   lcd_wdat(table6[z]);
   }
   else
   {
   l=0;
   z=0;                                                  //有按键按下,这停止倒计时并且清零
   T0_NUM=0;
   T0_NUM1=0;
   }
   }
}
回复

使用道具 举报

9#
ID:188940 发表于 2020-5-21 07:49 | 只看该作者
我会在单独开个帖子 重新发布修改后的PCB、原理图和程序。
回复

使用道具 举报

10#
ID:188940 发表于 2020-5-21 08:52 | 只看该作者
更新:PCB
回复

使用道具 举报

11#
ID:188940 发表于 2020-5-21 08:53 | 只看该作者
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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