找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1847|回复: 1
收起左侧

单片机电子密码锁

[复制链接]
ID:300430 发表于 2018-4-7 16:06 | 显示全部楼层 |阅读模式
电路原理图:
QQ图片20180408005407.png QQ图片20180408005424.png

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrinS.h>
  3. #include<absacc.h>
  4. #include "keyc1.h" //见3.12
  5. #include "LCD1602.h"
  6. #include "24C02.h"   //见2.2
  7.    //见4.1
  8. #define unchar unsigned char
  9. #define uint unsigned int

  10. #define C02_write 0xa0
  11. #define C02_read 0xa1

  12. //----------------------------------------------------------------------------------------------
  13. #define enter 0x0c    //确定
  14. #define backspace 0x0f   //退格
  15. #define A 0x0a           //输入密码
  16. #define B 0x0b           //修改密码
  17. //-----------------------------------------------------------------------------------------------
  18. unchar idata temp5_password[6]=
  19. {0,0,0,0,0,0};           //设置初始密码为"123456"
  20. unchar num;//错误次数
  21. uint  M1,M2=0,M3,M4,M5,M6;
  22. //-----------------------------------------------------------------------------------------------
  23. sbit SET=P3^2;               //恢复出厂密码设置键
  24. sbit Lock_BIT=P2^0;          //锁控制信号,输出低电平
  25. sbit SPK=P2^2;             //报警信号输出端
  26. //-----------------------------------------------------------------------------------------------
  27. unchar int_count_1;
  28. unsigned int int_count_2;
  29. void SPKdelay(uint z)  //蜂鸣器延时
  30. {         uint i;
  31.    for(i=z;i>0;i--);
  32. }

  33. //===============================================================================================
  34. void Longdelay(unsigned int i)  //长时间延时函数
  35. {
  36.         unsigned int j;
  37.         for (;i>0;i--)
  38.         for(j=10000;j>0;j--);

  39. }

  40. //================================================================================================
  41. bit compare_string(unchar *string1,unchar *string2)//密码对比函数
  42. {
  43.         unchar count;//设置循环对比计数器
  44.         for(count=0;count<6;count++)//设置要对比的密码为六位
  45.         {
  46.                 if(string1[count]!=string2[count])
  47.                 return(0);//输入密码与原密码不相同时返回出错函数0

  48.         }
  49.         return(1);//输入密码正确返回正确参数1
  50. }
  51. //---------------------------------------------------------------------------------------------------
  52. unchar step_choose(void)//选择输入密码或修改密码处理函数
  53. {
  54.         unsigned int i;
  55.         unchar key;
  56.         do{
  57.                   WR_CMD(0x01);//清屏
  58.                 WR_CMD(0x06);//AC递增,画面不动
  59.                 GotoXY(0,0);//设置显示“input password”的地址
  60.                 Show_Char("Input Password");//显示"输入密码"
  61.                 GotoXY(0,1);//设置显示plaese press A的首地址
  62.                 Show_Char("Please Press A");//显示请输入A
  63.                 for(i=0;i<30000;i++)//循环读键盘
  64.                         {
  65.                                 key=key1();//读键盘
  66.                                 if((key==A)||(key==B)) break;//如果是A或B就退出
  67.                         }
  68.                 if((key!=A)&&(key!=B))//如果不是A也不是B,就执行下列程序
  69.                   {
  70.                           WR_CMD(0x01);//清屏
  71.                         WR_CMD(0x06);//        AC递增,画面不动
  72.                         GotoXY(0,0);//设置显示“input password”的地址
  73.                         Show_Char("Change Password");//显示修改密码
  74.                         GotoXY(0,1);//设置显示“please press B”的首地址
  75.                         Show_Char("Please Press B");//显示请输入B
  76.                         for(i=0;i<30000;i++)//循环读键盘
  77.                         {         
  78.                                 key=key1();//读键盘
  79.                                 if((key==A)||(key==B)) break;//如果是A或B就退出
  80.                         }
  81.                   }
  82.           }
  83.           while((key!=A)&&(key!=B));//如果不是A也不是B,就循环读键盘
  84.           return (key);//是A或B就带参数返回
  85. }
  86. //=================================================================================================
  87. bit input_password(unchar *password)//输入密码函数
  88. {
  89.      unchar count,count1;//设置输入密码位数计数器
  90.         unchar key;//设置键值变量
  91.         GotoXY(0,1);
  92.         for(count=0;count<7;count++)
  93.         {
  94.                 Longdelay(3);//延时
  95.                 if(count<6);//输入密码小于六位吗?
  96.                 {        
  97.                         do{key=key1();}//是的,读键盘
  98.                         while(key==0xff);//如果键盘值为0xff,继续读键盘
  99.                     if(key==0x0d) break;   //退出键,回到初始界面
  100.                         if((key!=backspace)&&(key!=enter)&&(key>=0)&&(key<=9))//不是退格或确认键吗?
  101.                         {         
  102.                                 Show_1_Char('*');//不是,是数字键就显示'*'号
  103.                                 password[count]=key;//键值送入输入密码数组对应位
  104.                         }
  105.                 if(key==backspace)//是退格键吗?
  106.                         {
  107.                                 if(count>0)//输入位数大于0吗?
  108.                                 {
  109.                                         GotoXY(--count,1);//是的,送删除位的显示地址
  110.                                         Show_1_Char(' '); //删除位显示空白
  111.                                         password[count]=' '; //输入密码数组对应位置空白
  112.                                         GotoXY(count,1); //送闪烁位
  113.                                         count--;//密码位计数器减1

  114.                                 }

  115.                         }
  116.                  if(key==enter)//是确认键吗
  117.                         {
  118.                                 GotoXY(0,0);//是的,改变显示首地址
  119.                                 return(0);//返回出错参数0                        

  120.                         }
  121.                 }
  122.                 if(count==6)//密码位计数器等于6吗
  123.                 {
  124.                         do{key=key1();}//等于6,读键盘
  125.                         while((key!=backspace)&&(key!=enter));//不是退格键或确认键,继续读键盘
  126.                         if(key==backspace)//是退格键吗
  127.                         {
  128.                                 GotoXY(--count,1);//是的,送删除位的显示地址
  129.                                 Show_1_Char(' ');//删除位显示空白
  130.                                 GotoXY(count,1);//送闪烁位
  131.                                 count--;//密码位计数器减1
  132.                         }
  133.                            if(key==enter)//是确认键吗
  134.                         {return(1);}//是的,输入密码完成,返回正确参数1
  135.                 }
  136.         }
  137. }
  138. //===================================================================================================
  139. void password()//密码处理函数
  140. {
  141.     uchar key,key2;
  142.         uint kscount=0;
  143.         unchar idata temp1_password[6]={' ',' ',' ',' ',' ',' '};//设置4组6位密码变量
  144.         unchar idata temp3_password[6]={' ',' ',' ',' ',' ',' '};        //初始化为空白
  145.         unchar idata temp2_password[6]={' ',' ',' ',' ',' ',' '};
  146.         unchar idata temp4_password[6]={' ',' ',' ',' ',' ',' '};
  147.         key=step_choose( );//读选择状态
  148.         if(key==A)//是选择输入密码吗?
  149.         {
  150.         Read_Flash(temp1_password,0x00,6);//是的从24c02中读取密码送入第一组密码变量中
  151.                 WR_CMD(0x01);//清屏
  152.                 WR_CMD(0x06);//AC递增,画面不动
  153.                 GotoXY(0,0);//设置显示“input password”的首地址
  154.                 Show_Char("Input Password");//显示“输入密码”
  155.                 if(input_password(temp2_password))//完成输入密码了吗?
  156.                 {
  157.                         if(compare_string(temp1_password,temp2_password))//完成,比较密码正确吗
  158.                         {        num=0;
  159.                                 WR_CMD(0x01);//清屏
  160.                         WR_CMD(0x06);//AC递增,画面不动
  161.                                 GotoXY(0,0);//正确,设置显示“password correct”的首地址
  162.                                 Show_Char("Password Correct");//显示"密码正确"
  163.                                 GotoXY(0,1);//正确,设置显示“password correct”的首地址
  164.                                 Show_Char("Open Lock");//显示"密码正确"        Lock_BIT=0;//密码正确,开锁
  165.                            Lock_BIT=0;//关开锁信号
  166.                            while(1)
  167.                            {
  168.                              kscount++;
  169.                                  if(kscount==1000)
  170.                                   break;
  171.                                 SPK=0;
  172.                                 SPKdelay(10);//发开锁提示声
  173.                                 SPK=1;
  174.                            SPKdelay(40);
  175.                                 }        

  176.                     while(1)
  177.                         {  key2=key1();
  178.                             if(key2==0x0e)
  179.                           {
  180.                                 Lock_BIT=1;//关开锁信号
  181.                                 break;
  182.                                 }
  183.                           }
  184.                                 SPK=0;
  185.                                 //关开锁提示音
  186.                                 TR0=0;//关定时器0
  187.                                 return;//返回
  188.                         }
  189.                         else
  190.                                 {
  191.                                 WR_CMD(0x01);//清屏
  192.                         WR_CMD(0x06);//AC递增,画面不动
  193.                                 GotoXY(0,0);//错误,设置显示“wrong password”的首地址
  194.                                 Show_Char("Wrong Password");//显示“密码错误”
  195.                                   Longdelay(25);
  196.                                 num++;
  197.                                   if(num==3)
  198.                                   {
  199.                                     WR_CMD(0x01);//清屏
  200.                         WR_CMD(0x06);//AC递增,画面不动
  201.                                 GotoXY(0,0);
  202.                                            Show_Char("Please Wait For");
  203.                                            GotoXY(0,1);
  204.                                         Show_Char(" 3 Minute");
  205.                                         while(1)
  206.                                         {
  207.                                            SPK=0;
  208.                                            SPKdelay(100);
  209.                                            SPK=1;
  210.                                            SPKdelay(100);
  211.                                            M1++;
  212.                                            if(M1==24000)
  213.                                             {
  214.                                                  break;
  215.                                                 }
  216.                                         }
  217.                                         Longdelay(1400);
  218.                                      }
  219.                                 Longdelay(10);//延时
  220.                                 return;//返回
  221.                                 }
  222.                 }
  223.                 else
  224.                         {
  225.                                 GotoXY(0,1);//没有完成密码输入,设置显示“error!”的首地址
  226.                                 Show_Char("Error!");//显示“出错”
  227.                                 Longdelay(15);//延时
  228.                         }                                                                                 
  229.         }
  230.         else//是,修改密码
  231.          {
  232.                  Read_Flash(temp1_password,0x00,6);//从24c02中读取密码送入第一组密码变量中
  233.                 WR_CMD(0x01);//清屏
  234.                 WR_CMD(0x06);//AC递增,画面不动
  235.                 GotoXY(0,0);//设置显示“input old password”的首地址
  236.                 Show_Char("Input Old Password");//显示输入旧密码
  237.                 if(input_password(temp2_password))//完成输入密码了吗(输入的旧密码放在数组2中)
  238.                  {
  239.                          if(compare_string(temp1_password,temp2_password))//完成,比较密码正确吗?
  240.                          {
  241.                                  GotoXY(0,1);//正确,设置显示“password correct!”的首地址
  242.                                 Show_Char("Password Correct!");//显示“密码正确”
  243.                                 Longdelay(6);//延时
  244.                                 WR_CMD(0x01);
  245.                                 WR_CMD(0x06);
  246.                                 GotoXY(0,0);
  247.                                 Show_Char("Input New Password!");
  248.                                 if(input_password(temp3_password))//完成第一次新密码输入吗?(输入密码放在数组三中)
  249.                                 {
  250.                                         WR_CMD(0x01);
  251.                                         WR_CMD(0x06);
  252.                                         GotoXY(0,0);
  253.                                         Show_Char("Input Again");//显示再次输入密码
  254.                                         if(input_password(temp4_password))//完成第二次新密码输入吗?(输入的密码放在密码组4中)
  255.                                         {
  256.                                                 if(compare_string(temp3_password,temp4_password))//比较两次输入密码属否相同
  257.                                                 {
  258.                                                         Write_Flash(temp3_password,0x00,6);//相同,将新密码存入24c02中
  259.                                                         WR_CMD(0x01);//清屏
  260.                                                         WR_CMD(0x06);//AC递增,画面不动
  261.                                                         GotoXY(0,0);
  262.                                                         Show_Char("Password has");
  263.                                                         GotoXY(0,1);
  264.                                                         Show_Char("been changed");
  265.                                                         Longdelay(10);
  266.                                                         return;
  267.                                                 }
  268.                                                 else
  269.                                                 {
  270.                                                         WR_CMD(0x01);//两次输入不同清屏
  271.                                                         WR_CMD(0x06);//AC递增,画面不动
  272.                                                         GotoXY(0,0);
  273.                                                         Show_Char("Twice input");  //显示”两次输入“
  274.                                                         GotoXY(0,1);
  275.                                                         Show_Char("is different");        //显示是“不同的”
  276.                                                         Longdelay(10);
  277.                                                         return;        
  278.                                                 }
  279.                                         }
  280.                                         else
  281.                                         {
  282.                                                 GotoXY(0,1);//没有正确完成第二次新密码的输入,设置显示“error”的首地址
  283.                                                 Show_Char("Error!");//显示错误
  284.                                                 Longdelay(15);
  285.                                                 return;
  286.                                         }
  287.                                 }
  288.                                 else
  289.                                 {
  290.                                         GotoXY(0,1);//没有正确完成第一次新密码输入,设置显示“error”的首地址
  291.                                         Show_Char("Error!");
  292.                                         Longdelay(15);
  293.                                         return;
  294.                                 }
  295.                          }
  296.                          else
  297.                             {
  298.                                     WR_CMD(0x01);//两次输入不同清屏
  299.                                         WR_CMD(0x06);//AC递增,画面不动
  300.                                      GotoXY(3,0);//旧密码输入错误,设置显示“wrong password”的首地址
  301.                                     Show_Char("Sorry");
  302.                                     GotoXY(0,1);        
  303.                                     Show_Char("Wrong password");

  304.                                   num++;
  305.                                   if(num==3)
  306.                                   {
  307.                                     WR_CMD(0x01);//清屏
  308.                             WR_CMD(0x06);//AC递增,画面不动
  309.                                      GotoXY(0,0);
  310.                                            Show_Char("Please Wait For");
  311.                                            GotoXY(0,1);
  312.                                         Show_Char(" 3 Minute");
  313.                                         while(1)
  314.                                         {
  315.                                            SPK=0;
  316.                                            SPKdelay(100);
  317.                                            SPK=1;
  318.                                            SPKdelay(100);
  319.                                            M1++;
  320.                                            if(M1==24000)
  321.                                             {
  322.                                                  break;
  323.                                                 }
  324.                                         }
  325.                                          Longdelay(1400);
  326.                                         }
  327.                                         Longdelay(25);
  328.                                         return;
  329.                             }
  330.                  }
  331.                     else
  332.                         {
  333.                                     GotoXY(0,1);//没有正确完成旧密码的输入,设置显示“error!”的首地址
  334.                                         Show_Char("Error!");
  335.                                         Longdelay(15);
  336.                                         return;
  337.                         }
  338.          }
  339. }
  340. //============================================================================================================
  341. void int_service(void) interrupt 0 //外部中断0处理函数
  342. {
  343.         EA=1;//关CPU中断
  344.         EX0=1;//关外部中断0
  345.         for(int_count_1=4;int_count_1>0;int_count_1--)//设置延时时间,10秒
  346.          {
  347.                  for(int_count_2=0xffff;int_count_2>0;int_count_2--)
  348.                 {
  349.                         if(SET==1)//恢复出厂密码设置键松开否?
  350.                          {
  351.                         return;
  352.                          }
  353.                 }
  354.          }                  
  355.          WR_CMD(0x01);
  356.          WR_CMD(0x06);
  357.          Show_Char("Reset Cuccess!");//显示“恢复出厂密码”
  358.          Longdelay(50);
  359.          Write_Flash(temp5_password,0x00,6); //初始密码0000000密码送入24c02中保存

  360. /*          EA=1;//关CPU中断
  361.             EX0=1;         */
  362. }
  363. //==========================================================================================

  364. void t0(void) interrupt 1 using 0//定时、计数器0中断处理函数
  365. {
  366.         TH0=(65536-1000)/256;//重新将定时1000微秒初值的高八位送入TH0
  367.         TL0=(65536-1000)%256;//         重新将定时1000微秒初值的低八位送入TL0
  368.         SPK=~SPK;//信号输出位取反,即1000微秒反转一次,产生周期为2ms的方波

  369. }
  370. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  371. main()
  372.   {        unchar key;
  373.     Initialize(); //1602初始化
  374.         IT0=1;//设INT0为跳变沿沿触发方式
  375.         EX0=1;//开外部中断0
  376.         TMOD=0x01;
  377.         TH0=(65536-1000)/256;//重新将定时1000微秒初值的高八位送入TH0
  378.         TL0=(65536-1000)%256;//         重新将定时1000微秒初值的低八位送入TL0
  379.         TR0=0;
  380.         ET0=1;
  381.         EA=1;
  382.          while(1)
  383.         {         
  384.                    password();//运行密码处理函数
  385.     }
  386. }
  387. //=================================终于完成了==================================================

复制代码



电子密码锁原理图.doc

107.5 KB, 下载次数: 9, 下载积分: 黑币 -5

评分

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

查看全部评分

回复

使用道具 举报

ID:497494 发表于 2019-11-25 13:25 | 显示全部楼层
请问楼主可以分享一下hex文件吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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