设为首页收藏本站淘宝杂货铺

从F到0 - From F to 0

 找回密码
 注册已关闭
搜索
查看: 3499|回复: 2
收起左侧

DIY 单管密码锁 - 只需1个数码管和两个按键和STC单片机制作的8位16进制密码锁

[复制链接]
发表于 2017-7-1 08:17:35 | 显示全部楼层 |阅读模式

  1. /*
  2. DIY 单管密码锁 - 只需1个数码管和两个按键和STC单片机制作的8位16进制密码锁
  3. 程序上电后,首先只有1个小数点亮,此为省电模式。
  4. 按下任意按键后点亮数码管,按下(增加键) 增加当前位的密码,按下(保存)键,输入下一位密码。
  5. 10秒钟无按键按下后,自动进入省电模式,同时清除客户输入的所有密码。
  6. 连接1个74HC138译码器外接8个LED,让客户知道是在输入第几位密码。
  7. 验证密码时,译码器上8个的LED会熄灭,密码错误时显示r 字样,正确时显示o字样。
  8. 密码正确后需要持续按下(保存)键,继电器才会吸合,放开后继电器也会释放。
  9. 按下增加按键1秒后,当前输入的密码位会以0.2秒的速度持续增加。
  10. 共阳数码管A~DP连接P1.0~P1.7口,增加按键、保存按键分别连接P3.0、P3.1和GND。
  11. 继电器控制口连接P3.2(低电平吸合),74HC138高电平使能有效端连接P3.6,其余两端连接GND,译码输入线连接P3.3~P3.5即可。
  12. 74HC138输出8端连接8个共阳LED,用于提示客户在第几位输入密码,74HC138以及8个LED可有可无,最好加上。
  13. LED以及数码管、可能需要串联限流电阻,按照实际额定电压电流进行串联,译码口接反按照源程序将a2和a0的定义颠倒即可。
  14. 程序延时时间不同型号的可能会有不同,按照型号以及晶振频率进行修改成准确的即可。
  15. 晶振频率:12Mhz 型号:STC89C****
  16. By:LscmunaixMG 2017-07-01
  17. */

  18. #include "reg51.h"
  19. #include "intrins.h"
  20. unsigned char code nbr[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //数码管段码数据
  21. unsigned char c[8]={0,0,0,0,0,0,0,0}; //客户输入的密码
  22. unsigned char code d[8]={1,2,3,4,10,11,12,13}; //正确的密码 1234ABCD,不能超过15(0xF)否则无法解锁。
  23. unsigned char a=0; //当前输入的密码 取值0~15
  24. unsigned char b=0; //在第几位输入密码 取值0~7
  25. unsigned char e=0; //段码缓存
  26. unsigned int f=0; //无按键时间计数
  27. unsigned char at=0; //增加按键按下时间计数
  28. sbit key=P3^0; //增加按键
  29. sbit key2=P3^1; //保存按键
  30. sbit relay=P3^2; //继电器 低电平吸合
  31. unsigned char delay=0; //延迟计数
  32. //74hc138 译码器与使能
  33. sbit a2=P3^3;
  34. sbit a1=P3^4;
  35. sbit a0=P3^5;
  36. sbit en=P3^6; //高电平译码有效

  37. void Delay10ms()                //@12MHz
  38. {
  39.         unsigned char i, j;

  40.         i = 20;
  41.         j = 113;
  42.         do
  43.         {
  44.                 while (--j);
  45.         } while (--i);
  46. }





  47. bit ifpass(){
  48. unsigned char i=0;
  49.         for(i=0;i<8;i++){ //密码匹配
  50.                 if(d[i] != c[i]) { //有1个不匹配
  51.                 return 0;
  52.                 }
  53.                 c[i]=0; //清除
  54.                         }

  55.                 return 1; //全匹配

  56. }
  57. void outb(){
  58.         en=1;
  59.         switch(b){
  60.         case 0:a0=0;a1=0;a2=0;break;
  61.         case 1:a0=0;a1=0;a2=1;break;
  62.         case 2:a0=0;a1=1;a2=0;break;
  63.         case 3:a0=0;a1=1;a2=1;break;
  64.         case 4:a0=1;a1=0;a2=0;break;
  65.         case 5:a0=1;a1=0;a2=1;break;
  66.         case 6:a0=1;a1=1;a2=0;break;
  67.         case 7:a0=1;a1=1;a2=1;break;
  68.         default:break;
  69.         }

  70. }
  71. void main(){

  72. f=1000; //初始省电
  73. outb();
  74. while(1){

  75.                         if(f >= 1000){ //10秒无按键
  76.                                 //清除所有按键数据
  77.                                 b=0;
  78.                                 outb();
  79.                                 en=0;
  80.                                 a=0;

  81.                                
  82.                                 while(f >= 1000){ //进入省电模式
  83.                                 P1 = 0x7F;
  84.                                         if(key == 0 || key2 == 0){ //省电模式有按键按下
  85.                                         Delay10ms();
  86.                                                 while(key == 0 || key2 == 0){
  87.                                                 P1=nbr[0]&0x7F;
  88.                                                 }
  89.                                                 f=0; //退出省电模式
  90.                                         }
  91.                                 }
  92.                                 en=1;
  93.                         }




  94.                 if(key == 0){ //按键按下
  95.                                 Delay10ms(); //等待10毫秒
  96.                                         if(key == 0){ //按键在按下
  97.                                         f=0; //无按键时间清零
  98.                                         a++; //计数加1
  99.                                         a&=0xF;
  100.                                         while(key == 0){ //等待按键放开
  101.                                                 P1=nbr[a];
  102.                                                 Delay10ms();
  103.                                                 at++; //按下时间计数
  104.                                                 while(key == 0 && at >= 100){ //按下时间到1秒
  105.                                                         P1=nbr[a];
  106.                                                         a++; //计数加1
  107.                                                         a&=0xF;
  108.                                                         for(delay=0;delay<20;delay++){
  109.                                                         Delay10ms();
  110.                                                                 if(key == 1){ //按键放开
  111.                                                                 at=0; //清除持续时间
  112.                                                                 a--;
  113.                                                                 a&=0xF;
  114.                                                                 break;//跳出循环
  115.                                                                 }
  116.                                                         }
  117.                                                        
  118.                                                 }

  119.                                         }

  120.                                         at=0;
  121.                                        
  122.                                 }

  123.         }


  124.                 if(key2 == 0){ //保存按键按下
  125.                         Delay10ms(); //等待10毫秒
  126.                         if(key2 ==0){
  127.                                 f=0;
  128.                                 c[b]=a; //保存密码
  129.                                 b++; //计数加1
  130.                                 outb();
  131.                                 a=0;
  132.                                         if(b>7){ //输入到8位
  133.                                         en=0;
  134.                                         if(ifpass() == 1){ //正确
  135.                                                 e=0xA3;
  136.                                                 relay=0;
  137.                                                 } else { //错误
  138.                                                 e=0xAF;
  139.                                         }
  140.                                         a=0;


  141.                                         } else {
  142.                                         e=nbr[0]&0x7F;

  143.                                 }


  144.                                 while(key2 == 0){
  145.                                 P1 = e;
  146.                                 Delay10ms();

  147.                                 }
  148.                         if(b>7){
  149.                                 en=1;
  150.                                 b=0;
  151.                                 outb();
  152.                         }
  153.                         relay=1;
  154.                         }
  155.                 }

  156.                
  157.                 P1=nbr[a];
  158.                 Delay10ms();
  159.                 f++;

  160.                
  161. }
  162. }


复制代码

相关帖子

发表于 2017-7-3 18:22:12 | 显示全部楼层
现在还没接触单片机,只能单纯的四处暖(水)贴。消灭零回复。
发表于 2017-9-20 12:07:45 来自手机 | 显示全部楼层
demon 发表于 2017-7-3 18:22
现在还没接触单片机,只能单纯的四处暖(水)贴。消灭零回复。

其实我也没接触过。
您需要登录后才可以回帖 登录 | 注册已关闭

本版积分规则

QQ|手机版|Archiver|从F到0 ( 蒙ICP备17002595号-1 )
蒙公网安备15010402000325号

腾讯云安全认证

GMT+8, 2024-4-20 10:40 , Processed in 0.467026 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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