简介:51单片机密码锁是电子类毕业设计中的高频选题,面向电子、自动化等专业学生,涵盖指纹识别与键盘密码两种实现方案。压缩包约22.39MB,共包含两套完整资料:电子密码锁套件提供原理图、源程序、仿真工程、开题报告、参考论文及制作详解;指纹密码锁套件增补了元件清单和配套视频,从硬件连线到软件调试均有对应材料。使用者可先按电子密码锁入门,再对照指纹方案深入;两类设计可交叉对照,帮助读者理解键盘输入、液晶显示、数据存储、指纹识别等模块在真实系统下的协同工作,也可直接作为课程设计或毕设的底稿进行改进。压缩包内按套件组织文档,便于按模块查阅。目前已有921人学习/下载,适合正在准备毕设或参加电子竞赛的学生参考。
1. 为什么指纹锁和密码锁总是成对出现在课程设计里
单片机课程设计和毕业设计里,指纹密码锁和电子密码锁是出现频率最高的两个题目,几乎每个实验室的柜子里都能翻出几块洞洞板焊的键盘矩阵和电磁锁。原因很直接:这两个项目恰好覆盖了单片机开发最核心的几个能力点——GPIO 扫描、外部中断、定时器消抖、串口通信、I2C 读写,再加上一块继电器驱动的功率电路。把这两套资料吃透,基本就等于把 51 单片机的主流外设都过了一遍。
两套设计在本质上是同一套骨架:单片机作为控制核心,输入侧是按键或指纹模块,输出侧是电磁锁和报警电路,中间夹着一层密码存储和校验逻辑。区别只在于指纹锁把密码换成了生物特征,多了一条串口数据链路和指纹模块的通信协议。对准备找工作或考研复试的人来说,能在原理图阶段讲清楚指纹模块的 TTL 电平匹配,能在答辩现场写得出密码校验的状态转移图,这比背诵任何开发板上手教程都更有说服力。
这篇文章按一套标准的设计资料组织方式来拆:先讲系统架构和硬件选型,再讲原理图里最容易被问到的几个电路节点,然后进源代码的核心逻辑和状态机,接着是 Proteus 仿真的搭建和排错,最后给出两套资料在学习和答辩中的实际使用建议。全程按“理论能立住、动手能复现”的标准来写。
2. 系统整体架构与硬件选型:指纹锁的串口数据链路和密码锁的矩阵键盘输入
2.1 两套设计的最小系统构成对比
拿到一套设计资料,先不要急着看代码,第一步应该是把硬件框图画出来。指纹密码锁和电子密码锁的最小系统都由四部分组成:主控芯片、输入设备、输出执行器和人机交互界面。
指纹锁的输入设备是指纹模块,通过串口与单片机通信,典型模块是 AS608 或 R305 系列,内部集成了 DSP 处理芯片,负责指纹图像的采集、特征提取和比对,单片机只需要通过串口发送指令包、接收应答包。电子密码锁的输入设备是 4×4 矩阵键盘,直接占用单片机的 GPIO,扫描方式分为行列反转法和逐行逐列扫描法。
输出执行器方面,两套设计一致:电磁锁或继电器控制的电控锁,外加蜂鸣器和 LED 报警指示。人机交互界面几乎都用 LCD1602,两行十六字符,显示菜单、输入状态和剩余尝试次数。
主控芯片在两套资料里最常见的是 STC89C52 或 AT89S52,51 内核,8KB Flash,256B RAM,工作频率 11.0592MHz。选这个频率的原因和串口波特率有关,11.0592MHz 晶振可以精确分频出 9600 波特率,误差为零。指纹模块出厂默认波特率就是 57600 或 9600,两者能直接对上。
2.2 关键选型决策:为什么指纹模块要选串口而非 USB
指纹模块的选型是整套设计里最值得展开讲的一点。市面上的指纹模块按接口分为三类:USB 接口、串口 TTL 接口和 SPI 接口。课程设计资料里几乎全部选用串口 TTL 接口,原因不只是协议简单,更重要的是:
第一,51 单片机没有 USB 控制器,如果选 USB 接口的指纹模块,还得额外接 CH340 或 FT232 做 USB 转串口桥接,电路复杂度直接翻倍。第二,SPI 接口虽然速度快,但 51 单片机需要软件模拟 SPI 时序,而且指纹模块传输的数据包长度通常超过 30 字节,软件模拟 SPI 在 12MHz 主频下的稳定性没有保障。第三,串口是 51 单片机天生支持的接口,直接用定时器 1 做波特率发生器就可以工作。
指纹模块选型时要注意电压匹配。AS608 模块的逻辑电平是 3.3V,而 STC89C52 的 IO 口在 5V 供电下输出高电平是 5V,直接连接可能损坏模块。常见做法是加一个 3.3V 稳压芯片给模块供电,串口 TX 方向串一个 1kΩ 电阻分压。很多资料里省掉了这个电阻,实际做板子时容易烧模块,这一点要在原理图里确认清楚。
| 对比维度 | 指纹密码锁 | 电子密码锁 |
|---|---|---|
| 输入方式 | AS608 指纹模块,串口通信 | 4×4 矩阵键盘,GPIO 扫描 |
| 密码存储 | 指纹模块内部 Flash | AT24C02 EEPROM(I2C 接口) |
| 核心外设 | UART、定时器、GPIO | 定时器、GPIO、I2C |
| 掉电保持 | 指纹特征存储在模块内 | 24C02 存储,单片机掉电不丢失 |
| 设计难点 | 串口协议解析、通信时序 | 按键消抖、密码输入状态机 |
这里插一句,有些资料里指纹锁也加了密码键盘作为后备解锁方式,这种“指纹 + 密码双保险”的设计在答辩时更受欢迎,因为它的逻辑层次更丰富:指纹比对失败后自动切换到密码输入模式,密码输入错误三次触发报警。后面第 4 章的代码实现会把这套双模式逻辑写清楚。
3. 原理图核心电路分析:从最小系统到指纹模块接口的电平匹配
3.1 最小系统三件套:电源、晶振、复位电路
无论指纹锁还是电子密码锁,原理图的开头都是同一个最小系统。电源部分,5V 输入经过一个 10μF 电解电容和 0.1μF 陶瓷电容并联滤波后进单片机 VCC,电容的位置要尽量靠近芯片引脚。如果指纹模块需要 3.3V,用 AMS1117-3.3 降压,输入输出端各加一个 10μF 电容,注意 AMS1117 的压差要求是 1V 以上,5V 输入降到 3.3V 没问题,但电池供电时电压掉到 4V 以下就会出现稳压失效。
晶振电路用 11.0592MHz 石英晶振,两个 30pF 负载电容分别接在晶振两端到地。这里有一个容易被忽略的细节:电容值不是随便选的,它与晶振的负载电容参数有关。11.0592MHz 晶振的负载电容常见为 20pF 到 33pF,取 30pF 是通用做法,如果走线过长可以适当减小到 22pF 以降低振荡幅度衰减。
复位电路采用上电自动复位加手动复位按键的结构。10μF 电容串联 10kΩ 电阻到地构成上电复位,复位按键并联在电容两端。按键按下时 RST 引脚被拉到高电平,单片机复位;松开后电容充电完成,RST 回到低电平正常运行。
3.2 指纹模块接口的三种接法和电平匹配方案
指纹模块与单片机的接口是原理图里最值得对照实物核对的部分。AS608 模块的排针定义一般是 VCC、GND、TX、RX、TOUCH 五个引脚,其中 TOUCH 是感应触摸信号输出,可选接。模块的 TX 接单片机的 RXD,模块的 RX 接单片机的 TXD,交叉连接。
电平匹配的三个方案:
方案一(最简):直接连接。前提是主控芯片供电 3.3V 或者模块能容忍 5V 电平。STC89C52 是 5V 器件,AS608 是 3.3V 器件,不建议这么做。
方案二(分压电阻):单片机 TXD 输出 5V 经过 1kΩ 和 2kΩ 电阻分压到约 3.3V 进指纹模块 RX。指纹模块 TX 输出 3.3V 直接进单片机 RXD,51 单片机的高电平检测阈值是 0.7×VCC,即 3.5V 以下理论上识别不了 3.3V 的高电平信号,但实际因为 51 单片机 IO 口的施密特特性,3.3V 通常能触发,不过长时间运行可能偶发乱码。
方案三(推荐):用 MAX232 或纯逻辑电平转换芯片。如果资料里用的是 MAX232,需要额外提供 ±12V 的电荷泵电容。更干净的做法是加一片 74LVC245 或者直接用一个 NPN 三极管反相电路做电平转换。
// 伪代码:三极管电平转换电路状态说明 // 单片机 TXD(P3.1) ---- 1kΩ ---- 三极管基极 // 三极管发射极接地,集电极接 3.3V 上拉电阻到指纹模块 RX // 单片机 TXD 输出高电平时三极管导通,集电极拉低,模块 RX 收到低电平 // 单片机 TXD 输出低电平时三极管截止,集电极被上拉到 3.3V,模块 RX 收到高电平 // 逻辑反相,所以需要在单片机串口发送前对数据位取反这个电路的协议层面问题在于逻辑反相,实际工程中多数人直接用两个电阻分压,不用三极管。我一般建议照方案二,省事且足够稳定,只要确认模块的 RX 能忍受 3.3V 上拉。
3.3 电磁锁驱动:继电器和达林顿管的取舍
电磁锁的工作电流通常在 300mA 到 800mA 之间,51 单片机的 IO 口最大灌电流约 20mA,不可能直接驱动,中间必须加功率放大器件。两套资料里最常见的是两种电路:ULN2003 达林顿管阵列和 5V 继电器加续流二极管。
用 ULN2003 时,单片机 IO 口直接输入,输出端接继电器线圈或电磁锁一端,另一端接 VCC。ULN2003 内部已经集成了续流二极管,不需要额外接二极管,但要注意负载的供电是 5V 还是 12V。12V 电磁锁需要用 12V 电源单独供电,ULN2003 的 COM 引脚接 12V,用于给内部续流二极管提供反向电压回路。
用继电器方案时,继电器线圈两端必须并联一个 1N4007 二极管,阴极接电源正极,阳极接单片机控制端对应的晶体管集电极。这个二极管非常关键,电感线圈在断电瞬间会产生反向电动势,电压值可能达到几十伏到上百伏,如果没有二极管续流,轻则单片机复位,重则击穿驱动三极管。
驱动电路的三极管选型,常用 S8050(NPN),基极串 1kΩ 电阻限流,集电极接继电器线圈,发射极接地。基极电阻的计算逻辑是:IO 口输出高电平约 5V,三极管基极-发射极压降约 0.7V,基极电流 = (5-0.7)/1000 ≈ 4.3mA,S8050 的放大倍数在 100 倍以上,集电极电流可以驱动 400mA 的负载,余量合理。
4. 源程序核心逻辑:密码校验状态机与指纹模块串口指令帧解析
4.1 矩阵键盘扫描与消除抖动的一次完整实现
电子密码锁的源代码里,最基础也是答辩必问的是矩阵键盘扫描。下面给出一个标准的行列反转法实现,这个写法比逐行逐列扫描代码更短,且不占用定时器资源。
// 矩阵键盘扫描函数,返回按下的键值,无按键返回 0xFF // 硬件连接:P1.0-P1.3 行线,P1.4-P1.7 列线 unsigned char KeyScan(void) { unsigned char row, col; unsigned char temp; P1 = 0x0F; // 行线输出低电平,列线置高并开内部上拉 temp = P1 & 0x0F; // 读取列线状态 if (temp == 0x0F) // 列线全为高,说明没有按键按下 return 0xFF; Delay20ms(); // 软件延时消抖,跳过按键机械抖动区 P1 = 0xF0; // 反转引脚方向:列线输出低,行线输入 temp = P1 & 0xF0; if (temp == 0xF0) return 0xFF; // 反转后无按键,判定为抖动干扰 switch (temp) // 根据列线低电平位置确定列号 { case 0x70: col = 0; break; case 0xB0: col = 1; break; case 0xD0: col = 2; break; case 0xE0: col = 3; break; default: return 0xFF; } P1 = 0x0F; // 再反转回来读行线 temp = P1 & 0x0F; switch (temp) { case 0x0E: row = 0; break; case 0x0D: row = 1; break; case 0x0B: row = 2; break; case 0x07: row = 3; break; default: return 0xFF; } return row * 4 + col; // 返回键值编码 }这段代码的逻辑是两次反转判断:先让行线输出低电平、读列线,确认哪一列被拉低,再反转方向让列线输出低电平、读行线,确认哪一行被拉低。行号和列号相交的位置就是按键。中间加了一次 20ms 延时消抖,原因是按键机械触点在按下瞬间会产生 5ms 到 15ms 的高低电平抖动,20ms 是经验值。
按键扫描的返回时序需要注意,主循环里调用这个函数时,如果按下不松开,函数会反复返回同一个键值,导致密码输入重复。处理办法是在检测到有效按键后加等待释放的循环,或者用标志位记录上次按键值,检测到相同键值且未释放时不再写入密码缓冲区。
4.2 密码输入状态机:从空闲到验证成功的三态迁移
密码校验逻辑不能写成简单的 if-else 嵌套,状态机才是正规做法。密码锁的状态分三个:空闲态、输入态、验证态,外加一个锁定态用于连续输错后的惩罚。
// 密码校验状态机核心结构 typedef enum { STATE_IDLE, // 空闲态,等待键盘输入 STATE_INPUT, // 输入态,正在接收密码位 STATE_VERIFY, // 验证态,执行密码对比 STATE_LOCKED // 锁定态,连续错误后锁定 30 秒 } PwdState; PwdState currentState = STATE_IDLE; unsigned char pwdBuffer[6]; // 密码缓存,最多 6 位 unsigned char pwdCorrect[6] = {1,2,3,4,5,6}; // 正确密码 unsigned char inputIndex = 0; unsigned char errorCount = 0; // 主循环部分代码 void PwdProcess(unsigned char keyValue) { switch (currentState) { case STATE_IDLE: if (keyValue == '#') // 按 # 开始输入密码 { inputIndex = 0; currentState = STATE_INPUT; LcdShowStr("INPUT PWD:"); } break; case STATE_INPUT: if (keyValue >= 0 && keyValue <= 9) // 数字键 { pwdBuffer[inputIndex++] = keyValue; LcdShowChar('*'); // 显示星号防止偷窥 if (inputIndex >= 6) // 输入满 6 位自动验证 currentState = STATE_VERIFY; } else if (keyValue == '*') // 退格键 { if (inputIndex > 0) inputIndex--; LcdShowStr("\b \b"); } else if (keyValue == '#') // 确认键 { currentState = STATE_VERIFY; } break; case STATE_VERIFY: if (memcmp(pwdBuffer, pwdCorrect, 6) == 0) { OpenLock(); // 密码正确,开锁 errorCount = 0; currentState = STATE_IDLE; } else { errorCount++; if (errorCount >= 3) currentState = STATE_LOCKED; // 三次错误进锁定态 else currentState = STATE_IDLE; } break; case STATE_LOCKED: Delay30s(); errorCount = 0; currentState = STATE_IDLE; break; } }这段状态机的关键在于输入态的边界处理:输入不足 6 位时按确认键,需要提示用户密码未输满,而不是直接进验证态;输入超过 6 位时,多余的按键要么丢弃要么提前触发验证,两套资料里常见的做法是第 6 位输入后自动触发验证,不需要按确认键。这里还有一个安全细节:密码显示为星号而不是明文,答辩时提这一点能加分。
锁定态的实现要谨慎。上面代码用的是阻塞式 Delay30s,这在仿真里没问题,但在真实产品里会很糟糕,因为 BLOCK 期间系统无法响应任何事件。更合理的做法是用定时器计时,锁定期间仍然扫描键盘,只是不处理数字键输入。
4.3 指纹模块 AS608 的串口指令帧格式与校验码计算
指纹锁的代码核心是串口指令的组装和应答解析。AS608 的指令帧格式固定为:包头 0xEF01(两个字节),芯片地址(四个字节,默认全 0xFF),包标识(一个字节,命令包为 0x01,应答包为 0x07),数据包长度(两个字节,高字节在前),指令码(一个字节),参数字节,校验和(两个字节)。
校验和的计算范围是从包标识到参数最后一个字节,累加后取低 16 位。下面这段代码实现指纹录入(登记指纹)的命令发送和应答判断:
// 发送指纹录入命令:生成图像并生成特征存入模块的 CharBuffer1 // 参数说明:bufferID 为 1 或 2,对应模块内部的 CharBuffer 编号 unsigned char PS_GetImage(void) { unsigned char cmdPacket[13]; unsigned int sum = 0; unsigned char i; cmdPacket[0] = 0xEF; // 包头高字节 cmdPacket[1] = 0x01; // 包头低字节 cmdPacket[2] = 0xFF; // 芯片地址高字节 cmdPacket[3] = 0xFF; cmdPacket[4] = 0xFF; cmdPacket[5] = 0xFF; cmdPacket[6] = 0x01; // 包标识:命令包 cmdPacket[7] = 0x00; // 数据长度高字节 cmdPacket[8] = 0x03; // 数据长度低字节(指令码+参数共 3 字节) cmdPacket[9] = 0x01; // 指令码:GenImg 采集指纹图像 cmdPacket[10] = 0x00; // 参数:无 // 计算校验和:从包标识 0x01 开始,到参数最后一个字节结束 sum = 0x01; for (i = 7; i <= 10; i++) sum += cmdPacket[i]; cmdPacket[11] = (sum >> 8) & 0xFF; // 校验和高字节 cmdPacket[12] = sum & 0xFF; // 校验和低字节 UART_SendBytes(cmdPacket, 13); // 发送 13 字节完整命令帧 return PS_WaitAck(0x01); // 等待应答帧并检查指令码回显 }注意参数长度字段,GenImg 指令没有额外参数,但数据长度写的是 0x0003,这是把指令码(1 字节)加上 2 个字节的空的参数区都算进去了。实际上 AS608 的指令格式中,每个命令包的数据长度 = 指令码 1 字节 + 参数 n 字节,GenImg 的参数是 0 字节,但很多例程仍然把长度写成 3,这是与模块固件约定俗成的写法。
指纹模块的应答帧需要检查两个关键点:应答包里的确认码(Confirm Code)是否为 0x00,以及应答指令码是否和发送的指令码一致。确认码 0x00 表示成功,0x02 表示采集图像失败,0x0B 表示指纹特征不匹配。调试时把确认码对照表写在注释里,能少走很多弯路。
5. Proteus 仿真搭建与调试:无实物条件下跑通两套资料的验证路径
5.1 仿真工程的元件清单和连线要点
Proteus 仿真指纹锁和密码锁,第一个坑是元件库的差异。单片机用 AT89C52 替代 STC89C52,在 Proteus 里搜索 AT89C52 直接放置。LCD1602 在元件列表里叫 LM016L,注意引脚定义和实物模块不完全一致,资料里的仿真图如果是老版本,可能需要根据仿真模型调整对比度引脚。
指纹模块在 Proteus 里没有直接对应的仿真模型。两套资料通常用两种方式处理:一种是用一个 COMPIM 串口组件虚拟出 COM 口,配合 PC 端的虚拟指纹模块上位机软件来模拟指纹比对;另一种更简单,直接用按键和 LED 模拟指纹采集成功和失败的状态。仿真的目的是验证单片机逻辑,不是验证指纹传感器本身,所以第二种方式对于课程设计已经完全够用。
电磁锁在仿真里用一个 LED 加继电器线圈指示开锁状态。继电器用 Proteus 自带的 RELAY 元件,线圈电压设为 5V,触点接入一个指示灯电路。注意 Proteus 里继电器型号不同,线圈内阻参数也不同,如果仿真时继电器不动作,先检查线圈电压和工作电流是否超过仿真模型的额定值。
打开两套资料里的仿真工程文件后,第一件要做的事不是按运行,而是检查电源网络。Proteus 默认 VCC 和 GND 是隐藏的电源引脚,很多新手发现芯片不工作,原因是没给芯片电源网络接入电源符号。确认方法:放置一个 POWER 端子设为 +5V 接到 VCC 网络,再放置一个 GROUND 端子。
5.2 仿真运行常见故障与排除顺序
仿真不跑或跑出错误结果时,按照下面的顺序排查,基本能解决 90% 的问题。
先看晶振频率设置。双击单片机元件,检查 Clock Frequency 是否设置为 11.0592MHz。Proteus 默认值可能是 1MHz,导致串口波特率完全乱套,指纹模块通信数据全乱,LCD 显示的字符花屏错位。
再看程序加载路径。选择单片机元件后点击编辑属性,Program File 一栏要正确指向 Keil 生成的 hex 文件路径。Proteus 不认 Keil 的工程文件,只认编译后的 hex 或者 cof。每次修改源代码重新编译后,仿真工程不会自动重新加载 hex,需要手动重新选择文件,或者用系统变量让 Proteus 监视文件变化。
最后看时序问题。仿真环境里没有了元器件电气特性的干扰,按键抖动是不存在的,所以仿真里键盘响应比实际硬件灵敏得多。源码里的 20ms 消抖延时在仿真里可以缩短甚至去掉,但这样做会导致程序移植到真实硬件时无法正常使用。正确做法是保留消抖代码,在仿真里接受按键需要按一下的反应时间。
5.3 虚拟串口方案:让 Proteus 与 PC 上位机联调指纹模块通信
如果资料提供了指纹模块的上位机调试助手,可以利用虚拟串口软件把 Proteus 的 COMPIM 组件与 PC 的物理串口对接起来。
具体做法是安装一个虚拟串口工具,创建一对互联的虚拟串口,比如 COM3 和 COM4。Proteus 的 COMPIM 组件设置为 COM3,上位机调试助手打开 COM4,两者波特率都设为 57600。这样单片机通过串口发送的指纹指令帧,经过 Proteus 的 COMPIM 虚拟串口进入上位机,上位机软件模拟出指纹模块的应答帧返回给单片机。
这个联调方案的优势在于,它能真实验证单片机串口发送的指令帧是否正确。如果 AS608 的帧格式有错,上位机软件收到的数据会显示乱码,通过数据对比工具能按字节定位错误位置。实际硬件调试时,串口通信错误最难排查的就是指令帧长度和校验和,虚拟串口联调把这个问题提前暴露在仿真阶段。
仿真调试时建议在源码里加一个串口打印函数,把发送的每个字节的十六进制值输出到虚拟串口监视器。比如发送指纹搜图指令后,在串口终端看到的是EF 01 FF FF FF FF 01 00 03 01 00 00 05,其中最后两个字节00 05是校验和。如果发出去的帧不对,直接对着协议手册逐字节比对。
6. 两套资料的高效使用策略:从复现到答辩的进阶路径
6.1 先跑通密码锁再升级到指纹锁
两套资料的正确学习顺序是先电子密码锁、后指纹密码锁。电子密码锁只涉及 GPIO 扫描、定时器、I2C 和状态机,不牵扯串口协议解析,代码量小,出问题的面少。先把密码锁的程序烧进板子或跑通仿真,确认键盘扫描和 LCD 显示都正常后,再打开指纹锁的工程。
原因在于指纹锁的调试目标不只有逻辑正确性,还有时序正确性。串口是一个对时序敏感的接口,波特率的微小误差在短帧传输时可能不暴露,但在连续传输多帧指令时,误差累积到一定量级就会产生字节错位。如果在密码锁阶段就掌握了 Keil 编译器里针对 11.0592MHz 晶振的定时器初值计算,到指纹锁阶段只需要把注意力集中在协议帧的拼装和解析上。
6.2 答辩前必查的三个功能点
两套资料的源程序在拿来用之前,必须做三项功能验证,这三项也通常是答辩评委追问的重点。
第一项是密码错误锁定后能否自动恢复。有些程序的锁定状态是靠 while 死循环加延时实现的,延时结束后能回到主循环,但如果延时期间矩阵键盘有按键输入,扫描函数读到的是一个已经被按下的键,导致恢复后立刻进入密码输入状态。修复方法是在延时结束后加一次按键释放检测。
第二项是断电后密码是否保持。电子密码锁的密码存储在 AT24C02 里,断电不丢失。如果修改密码后直接切断电源再上电,新密码应该仍然有效。答辩现场可能出现的情况是:评委要求现场修改密码然后断电重启,如果密码用的是单片机内部 Flash 或者常量数组,这一步就会露馅。
第三项是指纹锁的指纹删除功能。指纹模块支持删除单个指纹和清空全部指纹两种指令。资料里的程序如果只实现了录入和比对,没有删除功能,答辩时评委可能会问“已经注册的指纹如何移除”。补充实现 PS_Delete 指令(指令码 0x06)的开销很小,但功能完整性上是一个明显加分点。
| 功能检查点 | 测试方法 | 预期结果 |
|---|---|---|
| 密码错误锁定 | 连续输入 3 次错误密码 | 键盘被锁定,30 秒后恢复 |
| 断电密码保持 | 修改密码后断电重启 | 新密码生效,旧密码无效 |
| 指纹删除 | 注册 2 枚指纹后删除 1 枚 | 被删指纹无法开锁 |
| 退格键功能 | 输入 5 位后按退格再输入 | 光标回退,密码缓冲区正确覆盖 |
| 掉电前开锁状态 | 开锁后立即断电,再上电 | 锁自动回到关闭状态,不允许保持打开 |
6.3 把两套资料整合成一个双保险门禁系统的改造思路
两套资料最大的隐藏价值在于可以合并。指纹密码锁的资料里有指纹模块的串口驱动代码,电子密码锁的资料里有键盘状态机和 EEPROM 掉电存储代码,把两者整合成一个系统,指纹开锁失败后自动降级为密码开锁,密码开锁失败锁定 30 秒。这个功能在答辩时被问到的概率极高,因为评委看到“指纹锁”题目后默认它有密码后备。
整合的核心是串口接收的中断处理和主循环的调度配合。指纹模块的应答帧长度通常为 12 到 16 字节,串口接收中断把数据逐字节存进环形缓冲队列,主循环在空闲时检查队列是否有完整的一帧数据,解析出确认码后再执行后续动作。这样做的原因是串口接收是异步事件,而指纹比对指令的执行时间是几十毫秒,如果在主循环里使用阻塞式接收,键盘扫描会卡住,密码后备功能就形同虚设。
实际的移植顺序是:先保留电子密码锁的主循环框架(键盘扫描 + 状态机 + LCD 刷新),把指纹锁的串口初始化代码放到系统启动时,再用一个全局标志位记录指纹验证状态,主循环的状态机在空闲态先检查这个标志位,如果指纹比对已经成功就直接开锁,否则进入密码输入流程。旧的状态机需要多分出一个分支,而不是重写整个框架。
本文还有配套的精品资源,点击获取