基于51单片机的数码管密码锁

news2024/11/16 13:43:56

基于51单片机的数码管密码锁是一种可以设置密码并通过输入密码来解锁的安全装置。该密码锁使用51单片机作为控制主板,配合数码管显示模块、按键模块和电磁锁等元件实现密码锁的功能。

实现步骤如下:

1. 硬件连接:将51单片机与数码管、按键模块和电磁锁等元件进行连接。数码管用于显示密码和解锁状态,按键模块用于输入密码,电磁锁用于控制门锁的开关。

2. 程序设计:使用汇编或C语言编写程序。程序主要包括密码的设置、密码的输入和验证等功能。在密码设置模式下,用户可以通过按键输入密码并保存到EEPROM中。在密码输入模式下,用户可以通过按键输入密码并与EEPROM中保存的密码进行比对,如果密码匹配则解锁电磁锁,否则显示密码错误。

3. 系统测试:将程序烧录到51单片机中,将系统连接好后进行测试。测试过程中,可以尝试设置密码、输入密码并观察系统的响应情况。

需要注意的是,为了增加密码的安全性,可以在程序设计中加入防止密码破解的措施,例如密码错误次数的限制、密码输入超时等。此外,还可以考虑使用其他安全元件,如指纹识别模块或刷卡模块,以提高密码锁的安全性。

  • 数字密码锁的基本原理 

51单片机数码管密码锁的基本原理是将用户输入的密码与初始的密码进行比较,如果两者匹配则开锁,否则关锁,开锁之后可以进行修改密码。选用单片机开发板STC89C52作为本设计的核心元件,利用编程设计、I/O端口及其板上的数码管、按键等各种硬件电路,设计密码锁功能,以自创的代码将功能实现。利用单片机的矩阵键盘用于密码的输入、密码复位和更改密码的控制,不掉电密码的存储以及使用数码管进行实时显示输入的密码。数码管负责实现密码显示,矩阵按键负责密码的输入、更改以及复位。

  • 数字密码锁的硬件设计   

(一)原理图设计

 

图1  数字密码锁原理图

(二)原理图各部分原理

主控制电路是由STC89C52芯片和12M晶振组成的,重要的功能是通过写入代码来控制P1、P2、和P3口输入输出状态,达到控制整个电路的功能。

复位按键电路是由复位按键和电容组成的,当复位按键按下之后RES会被拉高,STC89C52芯片上面的RES接口会被给高电平,达到复位电路的功能。

矩阵按键电路是由十六个按键组成,使用一个4行4列矩阵结构,其中每一行都连接一个可编程I/O口,每一列连接一个按键开关。当按下某个按键时,可编程I/O口的输入由高变低,此时通过扫描这4行4列的矩阵可以得出按键对应的行和列号。

数码管显示电路是由两个四位数共阳极码管组成,是一种常用的显示和控制电路,它可以显示不同格式的数字和字母,以及相应的图形。数码管电路由51单片机主控,数码管位选连接到单片机的输出口P2,数码管段选连接到单片机的输出口P3,信号经过电路驱动,在一定时间内控制一个数码管显示相应的状态,然后通过快速切换使的人眼观测为几个数码管同时点亮。

序号

器件名称

参数

数量

1

USB座

1

2

USB线

1

3

串口下载线

1

4

104电容

0.1uF

7

5

LED灯

1

6

电阻

2K

1

7

蜂鸣器

1

8

STC89C52

1

9

晶振

12MHz

1

10

按键

16

11

复位键

1

12

电阻

10K

1

13

40针座

1

14

三极管9015

9

15

电阻

330

1

16

16针座

1

17

MAX232

1

18

电容

20pF

2

19

4位LED

2

20

电阻

330

8

21

电阻

4.7K

8

表2    元器件清单

  • 数字密码锁的软件设计

程序流程图如下:

 

程序代码如下:

#include <REGX52.H>

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

#define KEY_MATRIX_PORT P3 //使用宏定义矩阵按键控制口

#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口

//共阳极数码管显示0~9 N F 的段码数据

u8 nixie[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x37,0x71};

unsigned int Code = 0;//用于保存密码的变量

unsigned int TempCode = 0;//用于暂时保存密码的变量

unsigned int NewCode = 0;//用于保存新密码的变量

unsigned int LNew=0,New=0;//用于判断是否开始录入新密码

unsigned int Newlate=0;//用于确定是否新密码录入结束

void wei(unsigned char pizz);//用于显示第几个数码管的函数声明

unsigned int key=0;//保存按键按下的位数

unsigned int T=0;//密码输入正确判断

unsigned int TLL=0;//密码输入正确判断

unsigned int F=0;//密码输入错误判断

static unsigned char i = 0;//刷新数码管

void delay_10us(u16 ten_us)//延时函数

{

while(ten_us--);

}

u8 key_matrix_ranks_scan(void)

{

u8 key_value=0;



KEY_MATRIX_PORT=0xf7;//给第一列赋值0,其余全为1

if(KEY_MATRIX_PORT!=0xf7)//判断第一列按键是否按下

{

delay_10us(500);//消抖

switch(KEY_MATRIX_PORT)//保存第一列按键按下后的键值

{

case 0x77: key_value=1;break;

case 0xb7: key_value=5;break;

case 0xd7: key_value=9;break;

case 0xe7: key_value=13;break;

}

}

while(KEY_MATRIX_PORT!=0xf7);//等待按键松开



KEY_MATRIX_PORT=0xfb;//给第二列赋值0,其余全为1

if(KEY_MATRIX_PORT!=0xfb)//判断第二列按键是否按下

{

delay_10us(500);//消抖

switch(KEY_MATRIX_PORT)//保存第二列按键按下后的键值

{

case 0x7b: key_value=2;break;

case 0xbb: key_value=6;break;

case 0xdb: key_value=10;break;

case 0xeb: key_value=14;break;

}

}

while(KEY_MATRIX_PORT!=0xfb);//等待按键松开



KEY_MATRIX_PORT=0xfd;//给第三列赋值0,其余全为1

if(KEY_MATRIX_PORT!=0xfd)//判断第三列按键是否按下

{

delay_10us(500);//消抖

switch(KEY_MATRIX_PORT)//保存第三列按键按下后的键值

{

case 0x7d: key_value=3;break;

case 0xbd: key_value=7;break;

case 0xdd: key_value=11;break;

case 0xed: key_value=15;break;

}

}

while(KEY_MATRIX_PORT!=0xfd);//等待按键松开



KEY_MATRIX_PORT=0xfe;//给第四列赋值0,其余全为1

if(KEY_MATRIX_PORT!=0xfe)//判断第四列按键是否按下

{

delay_10us(500);//消抖

switch(KEY_MATRIX_PORT)//保存第四列按键按下后的键值

{

case 0x7e: key_value=4;break;

case 0xbe: key_value=8;break;

case 0xde: key_value=12;break;

case 0xee: key_value=16;break;

}

}

while(KEY_MATRIX_PORT!=0xfe);//等待按键松开



return key_value;

}

u8 key_matrix_flip_scan(void)

{

static u8 key_value=0;



KEY_MATRIX_PORT=0x0f;//给所有行赋值0,列全为1

if(KEY_MATRIX_PORT!=0x0f)//判断按键是否按下

{

delay_10us(500);//消抖

if(KEY_MATRIX_PORT!=0x0f)

{

KEY_MATRIX_PORT=0x0f;//测试列

switch(KEY_MATRIX_PORT)//保存行为0,按键按下后的列值

{

case 0x07: key_value=1;break;

case 0x0b: key_value=2;break;

case 0x0d: key_value=3;break;

case 0x0e: key_value=4;break;

}

KEY_MATRIX_PORT=0xf0;//测试行

switch(KEY_MATRIX_PORT)//保存列为0,按键按下后的键值

{

case 0x70: key_value=key_value;break;

case 0xb0: key_value=key_value+4;break;

case 0xd0: key_value=key_value+8;break;

case 0xe0: key_value=key_value+12;break;

}

while(KEY_MATRIX_PORT!=0xf0);//等待按键松开

}

}

else

key_value=0;

return key_value;

}

void smg_display(unsigned char pizz)

{

    switch(pizz)//位选

{

case 1: P2=0x7f;break;//第一个灯亮

case 2: P2=0xbf;break;//第二个灯亮

case 3: P2=0xdf;break;//第三个灯亮

case 4: P2=0xef;break;//第四个灯亮

case 5: P2=0xf7;break;//第五个灯亮

case 6: P2=0xfb;break;//第六个灯亮

case 7: P2=0xfd;break;//第七个灯亮

case 8: P2=0xfe;break;//第八个灯亮

}

}

void main()

{

  unsigned char k;//限制按下次数

while(1)

{

  key=key_matrix_ranks_scan();

  if(key!=0)

 {

         if(key<=10)

         {

           if(k<4)

            {

 if(T==0)

 {

               Code*=10;            

               Code+=key%10;

  if(TLL!=1)

{

                    k++;

}

 }

if(TLL==1)

{

    TempCode*=10;            

             TempCode+=key%10;

Code=TempCode;

             k++;

     LNew=1;

T=0;

}

         }    

else

{

 k=0;

  if(Code==8888&&Newlate==0)

  {

T=1;

Code=8888;

TLL=1;

   }

  else if(Code==NewCode&&Newlate==1)

  {

   T=1;

   LNew=0;

   TLL=0;

  }

       else

 {

  F=1;

 }

  }

            }

            else if(key==16)

            {

                k=0;

                Code=0;

T=0;

  F=0;

  LNew=0;

  New=0;

            }

            else if(key==15)

            {

               if(LNew==1)

  {

 NewCode=TempCode;

Newlate=1;

 TLL=0;

 Code=0;

 k=0;

 }

            }

        }



if(F==0&&T==0&&Code!=0)

    {

   for(i=0;i<8;i++)

      {

   switch(i)

        {  

        case 0:smg_display(1);P0=~nixie[Code/1000%10];break;

        case 1:P0=0xff;break;

        case 2:smg_display(3);P0=~nixie[Code/10%10];break;

        case 3:P0=0xff;break;

        case 4:smg_display(2);P0=~nixie[Code/100%10];break;

        case 5:P0=0xff;break;

        case 6:smg_display(4);P0=~nixie[Code%10];break;

        case 7:P0=0xff;break;

        }

delay_10us(50);

   }

}

 if(T==1&&LNew==0)

 {

 for(i=0;i<5;i++)

     {

    switch(i)

        {  

case 0:P0=0xff;break;

        case 1:smg_display(7);P0=~nixie[0];break;

        case 2:P0=0xff;break;

case 3:smg_display(8);P0=~nixie[10];break;

        case 4:P0=0xff;break;

        }

delay_10us(50);

}

}

 if(F==1)

 {

 for(i=0;i<7;i++)

     {

   switch(i)

       {  

case 0:P0=0xff;break;

        case 1:smg_display(6);P0=~nixie[0];break;

        case 2:P0=0xff;break;

case 3:smg_display(7);P0=~nixie[11];break;

        case 4:P0=0xff;break;

case 5:smg_display(8);P0=~nixie[11];break;

        case 6:P0=0xff;break;

       }

delay_10us(50);

 }

 }

 if(Code==0)

{

  P0=0x00;  //未输入密码  数码管全部不亮

}

    

}

}
  • 设计成果

矩阵按键功能图如下:

 

下载好程序之后随便按下四个密码,这里以按下按键key1、key2、key3、key4为例,数码管显示输入的密码1234如图一;密码输入达到四位后,此时再按下任一按键,如果密码不是初始密码8888,数码管则显示OFF如图二。此时按下按键key13进行复位,复位后可以继续输入密码,此时这里输入密码为8888和初始密码一样如图三,再按下任一按键,数码管显示ON如图四;当输入密码正确后,可以选择按下复位按键后继续输入密码,或者选择更换密码,这里由key5、key6、key7、key8组成新密码5678,再按下key14保存新密码,这样密码锁的密码就由初始密码8888变成了5678,可以继续分别输入密码8888和5678进行验证如图五和六。

                         图一                                 图二

 

                                              图三                                            图四

                                    图五                                                                图六

设计总结

首先,我要感谢老师在本门课程中给我们提供的宝贵教学资源和丰富的教学经验。此外,我也要感谢队友在完成课程设计任务时的合作精神和出色表现,使我们最终能够顺利完成课程设计任务。在课程设计的过程中,我们学习了关于单片机的例如数码管、延时设计、按键消抖等知识,并用实际应用来进行综合考核。通过本次课程设计,我深刻地理解到,单片机可以实现各种功能,也因为其小巧、低功耗的特点,在大型项目中也能放大作用。最后,我想强调一下,要善于总结、吸收、思考,努力将所学融会贯通,以更好地实现自身的发展和进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/706135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flutter mac环境配置

在 macOS 上安装和配置 Flutter 开发环境 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter一、配置flutter环境变量在 macOS 上安装和配置 Flutter 开发环境 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 解压文件放在我的文档里面 然后设置环境变量 1. 执…

OR青年导师访谈特辑 | 北京邮电大学助理教授 姜蔚蔚:如果不亲自尝试,就永远不知道自己的边界在哪

OR青年计划 由【运筹OR帷幄】社区主办的【OR青年计划】&#xff0c;旨在帮助对运筹学应用有理想和追求的同学&#xff0c;近距离与学界、业界导师交流课题&#xff0c;深入了解运筹学的细分方向&#xff0c;为后续的深造、就业生涯打下坚实的基础&#xff01;更多内容请查看链…

chatgpt赋能python:免费的Python教程:从入门到精通

免费的Python教程&#xff1a;从入门到精通 Python是如今最热门的编程语言之一&#xff0c;在众多编程语言中占据了重要的地位。Python有着简单易学的语法&#xff0c;充足的库支持&#xff0c;高效的执行速度和海量的社区支持&#xff0c;这些使得Python成为最适合初学者的编…

不知道识别表格的方式有哪些?分享识别表格怎么弄

小明&#xff1a;嘿&#xff0c;小红&#xff01;你知道吗&#xff1f;最近我在整理一堆纸质表格&#xff0c;但是手动输入数据实在太耗时间了&#xff0c;我在想有没有什么方法可以快速识别表格的内容呢&#xff1f; 小红&#xff1a;哦&#xff0c;我听说过有一些方式可以自…

java面试Day13

1. 有哪些注解可以注入 Bean&#xff1f;Autowired 和 Resource 的区别&#xff1f; 在 Spring 框架中&#xff0c;常用的注入 Bean 的注解包括&#xff1a; Autowired&#xff1a;自动注入&#xff0c;按照类型自动装配&#xff0c;如果有多个同类型的 Bean&#xff0c;则需要…

前端开发中的样式

目录 基础知识回顾 样式表⭐⭐ 内联样式表 嵌入样式表 外部样式表 选择器 ID选择器&#xff08;#id&#xff09;、类选择器(.class)、标签选择器⭐⭐ 伪类/伪元素选择器 伪类选择器(a:hover ul li:nth-child(odd))逻辑选择元素 伪元素(div::after)抽象创造元素 特…

C语言实现二叉搜索树BST

文章目录 初始化搜索节点删除节点 二叉搜索树(Binary Search Tree, BST)要求父节点大于等于其左子节点&#xff0c;而小于等于其右子节点&#xff0c;这样递归类推&#xff0c;相当于父节点大于等于其左侧的所有节点而小于等于右侧的所有节点&#xff0c;如下图所示 根据BST的规…

闭包治愈“全局变量恐惧症”,利用闭包实现JavaScript私有变量

文章目录 I. 介绍对闭包的定义和概述为什么理解闭包很重要 II. 函数与作用域函数的作用域和生命周期闭包是如何利用函数的作用域的 III. 闭包的实现闭包的实现方式如何创建闭包闭包的应用场景 IV. 闭包的优缺点闭包的优点数据的封装可以实现高阶函数 闭包的缺点内存占用对程序员…

MedLSAM:定位和分割任何3D医学图像模型

文章目录 MedLSAM: Localize and Segment Anything Model for 3D Medical Images摘要本文方法模型学习过程模型推理过程 实验结果 MedLSAM: Localize and Segment Anything Model for 3D Medical Images 摘要 SAM (Segment Anything Model)是近年来出现的一种具有开创性的图像…

【Linux】gcc/g++ 调试学习记录

这是目录 gcc编译选项二、实战1、编译加上 CFLAGS -ggdb三级目录 gcc编译选项 1、-g 编译debug debugging 选项&#xff1a;-g gcc -g手册: 点击这里 -g一共分为4个等级&#xff1a;-g、-g0、-g1、-g3 其中g和g0是一个性质&#xff0c;不打开调试信息&#xff0c;g3保留所有信…

react-native-camera插件的使用,以及实现人脸识别

一、git地址和环境版本 &#xff08;1&#xff09;Git地址&#xff1a;https://github.com/react-native-camera/react-native-camera/tree/master &#xff08;2&#xff09;node版本&#xff1a;14 &#xff08;3&#xff09;react-native版本&#xff1a;0.72 二、环境配…

Linux操作系统——第五章 进程信号

目录 信号概念 用kill -l命令可以察看系统定义的信号列表 信号处理常见方式概览 产生信号 1. 通过终端按键产生信号 2. 调用系统函数向进程发信号 3. 由软件条件产生信号 4. 硬件异常产生信号 阻塞信号 1. 信号其他相关常见概念 2. 在内核中的表示 3. sigset_t 4.…

spring.aop 随笔4 如何借助jdk代理类实现aop

0. 下了有一个月的雨&#xff0c;这对鼻炎来说来吗&#xff1f;不好 其实这也算6月份的博客&#xff0c;之前一直疏于整理 本文仅关注jdk代理所实现的spring.aop下&#xff0c;两者的关系完整的aop源码走读请移步相关 spring.aop 的其他随笔 1. 反编译追踪源码 1.1 jdk代理类…

BPMN2.0规范简介

1 概述 BPMN(Business Process Model & Notation)&#xff0c;中文名为业务流程模型与符号。BPMN2.0是OMG(Object Management Group&#xff0c;对象管理组织)制定的&#xff0c;其主要目的是既给用户提供一套简单的、容易理解的机制&#xff0c;以便用户创建流程模型&…

项目性能优化-内存泄漏检测与修改

最近终于有空优化一波项目的性能了&#xff0c;第一波借助Android Studio自带的Profiler工具检测内存泄漏。 第一步、创建Profiler的SESSIONS 第二步、进入MEMORY内存监控 右侧带有绿色原点的就是此时运行的Profiler的SESSION,点击右侧MEMORY进入内存监控的详情模块 第三步…

缓存三击-缓存穿透、缓存雪崩、缓存击穿

缓存三击-缓存穿透、缓存雪崩、缓存击穿 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ Spring专栏&#x1f449;https://blog.csdn.net/weixin_53580595/category_12279…

【产品设计】掌握“4+X”模型,从0到1构建B端产品

“4X”模型是什么 4个阶段&#xff1a;规划阶段&#xff0c;设计阶段&#xff0c;实现阶段&#xff0c;迭代阶段 X:项目管理&#xff0c;数据分析&#xff0c;产品运营 1、规划阶段 这是一个产品的开始&#xff0c;它决定了产品的设计方向和基调。主要包括用户分析、市场分…

爬虫入门指南(4): 使用Selenium和API爬取动态网页的最佳方法

文章目录 动态网页爬取静态网页与动态网页的区别使用Selenium实现动态网页爬取Selenium 的语法及介绍Selenium简介安装和配置创建WebDriver对象页面交互操作 元素定位 等待机制页面切换和弹窗处理截图和页面信息获取关闭WebDriver对象 使用API获取动态数据未完待续.... 动态网页…

JVM-垃圾回收-基础知识

基础知识 什么是垃圾 简单说就是没有被任何引用指向的对象就是垃圾。后面会有详细说明。 和C的区别 java&#xff1a;GC处理垃圾&#xff0c;开发效率高&#xff0c;执行效率低 C&#xff1a;手工处理垃圾&#xff0c;如果忘记回收&#xff0c;会导致内存泄漏问题。如果回…

Linux Mint 21.2“Victoria”Beta 发布

导读近日消息&#xff0c;Beta 版 Linux Mint 21.2 “Victoria” 于今天发布&#xff0c;用户可以访问官网下载镜像。 Linux Mint 21.2 代号 “Victoria” &#xff0c;基于 Canonical 长期支持的 Ubuntu 22.04 LTS&#xff08;Jammy Jellyfish&#xff09;操作系统&#xff0…