资讯详情

51单片机简易密码锁:矩阵键盘、LCD1602与AT24C02实现

📅 2026/11/6 2:36:31 | 华诺云谱 👁 阅读
51单片机简易密码锁:矩阵键盘、LCD1602与AT24C02实现
简介《51单片机简易密码锁》是一份面向单片机课程设计、电子密码锁入门实践与选题参考的中文文档围绕AT89C52最小系统、矩阵键盘、1602LCD显示、电源与报警电路展开给出密码设置、修改、显示和错误报警的整体设计思路。压缩包仅含1个doc文件大小约1.72MB内容以课程设计说明书形式组织便于读者了解硬件模块划分、C语言软件流程及系统可靠性、安全性等分析要点。已有445人学习适合需要快速搭建简易密码锁方案、梳理报告结构与功能模块的读者参考也可用于对照理解矩阵输入、LCD显示和单片机控制之间的配合关系。1. 一个两块钱的单片机和一把锁51单片机简易密码锁到底在做什么一件很具体的小事桌面上摆着一个铁皮柜钥匙老丢有人想让它认密码不认钥匙。做法是拿一颗经典 8051 内核的单片机AT89C52 这类引脚兼容型号配 4×4 矩阵键盘、LCD1602 字符屏、一片 AT24C02 掉电存储器和一路继电器把「按键输入 → 密码比对 → 驱动电磁锁」这条链路跑通整套物料成本三十块上下。51单片机简易密码锁解决的问题就这么朴素。适合两类人刚学完 C 语言和数字电路、第一次想把代码烧进真实电路的新手要带课程设计又不想陷进 RTOS 和一堆库函数的指导者。难点从来不在写代码而在电平、时序和干扰——这三样东西仿真软件永远不会教你也正是一块能开锁的板子最难做出来的原因。2. 硬件怎么搭矩阵键盘、LCD1602 和电磁锁的引脚分配动手之前先把一件事说清楚这个项目能不能一次成功八成取决于硬件这一层有没有埋雷。软件写错了改一行重烧硬件接错了轻则查一整晚重则烧片子。我一般会先画一张引脚分配表贴在桌上再拿万用表量一遍确认 5V 和地没有短才开始插线。2.1 元器件清单与一张必须先画出来的引脚表先说选型理由。51 内核单片机虽然老但它的 IO 电平是 5V能直接带动 LCD1602 和继电器模块不用电平转换引脚功能直观P0 是开漏P1/P2/P3 内部有弱上拉片内没有硬件 I2C但用两个 IO 口软件模拟完全够用开发环境简单一个串口就能下载。缺点也明显RAM 只有 128 到 256 字节存不下复杂逻辑没有真正的加密引擎密码存储只能做混淆不能做保护IO 驱动能力弱任何功率负载都得加三极管。清单如下数量按一台整机算类别器件数量说明主控AT89C52 及同引脚兼容型号111.0592MHz 或 12MHz 晶振均可时钟复位11.0592MHz 晶振、22pF 瓷片电容、10μF 电解、10kΩ 电阻各 2/2/1/1晶振靠近芯片复位电容正极接 VCC输入4×4 薄膜矩阵键盘116 键行 4 线列 4 线显示LCD1602 字符屏1带背光5V 供电显示配件10kΩ 电位器、10kΩ 排阻1/1电位器调对比度排阻给 P0 上拉存储AT24C0212Kbit可存 256 字节够存密码和设置存储配件4.7kΩ 电阻2I2C 的 SCL/SDA 上拉不可省驱动5V 继电器模块或 S80501N40071kΩ1 套光耦模块更省事分立方案更看得懂原理电源5V/2A 适配器、12V/1A 适配器各 1锁用 12V主控用 5V必须分开引脚分配建议这样定定了就别中途改改了代码和接线会一起乱功能单片机引脚方向备注键盘行线 ROW1~ROW4P1.4~P1.7输出低电平有效逐行拉低键盘列线 COL1~COL4P1.0~P1.3输入读回低电平说明该键按下LCD1602 数据 D0~D7P0.0~P0.7输出P0 开漏必须外接 10k 排阻上拉LCD1602 RS/RW/EP2.5 / P2.6 / P2.7输出RW 不用检测忙就直接接地AT24C02 SCL/SDAP2.0 / P2.1双向各接 4.7k 上拉到 5V继电器控制P2.2输出高电平吸合具体看模块触发极性门磁或防拆开关P3.2输入可选做防撬检测时用提示P0 口当普通输出用时一定要加排阻否则 LCD1602 收到的电平是虚的会出现「能显示但字符发虚、偶尔乱码」这种特别难查的现象。2.2 最小系统、矩阵键盘与 LCD1602 的接法最小系统三件套晶振、复位、电源。晶振和两颗 22pF 电容尽量贴着芯片的 XTAL1/XTAL2 放走线短。复位电路是 10μF 电容正极接 VCC、负极接 RST同时 RST 经 10kΩ 电阻接地这样上电瞬间 RST 是高电平实现上电复位。如果板子上有手动复位按钮并联在电容两端即可。矩阵键盘的接法是把 4 根行线接到 P1.4~P1.74 根列线接到 P1.0~P1.3。扫描原理是每次只让一根行线输出低电平其余行线输出高电平然后读 4 根列线如果某一列读到低电平就说明「这一行这一列」交叉处的按键被按下。16 个键对应 0~9、确认、删除、修改、上锁等键值在代码里用一张表映射。LCD1602 接 P0 做数据口RS 接 P2.5 控制「写指令还是写数据」RW 接 P2.6 控制读写方向E 接 P2.7 做使能。第三脚 V0 接 10kΩ 电位器的中间抽头电位器两端分别接 5V 和地用来调对比度。背光的 A/K 两端串一个 100Ω 限流电阻接 5V 和地。如果板上空间紧张把 RW 直接接地程序里只写不读用固定延时替代忙标志检测能省一根线和一个判断。上电时序这块一定要按顺序来先给 5V等 40ms 以上让 LCD 内部复位完成再连续发三次 0x388 位数据、两行显示、5×7 点阵然后发 0x0C 开显示关光标、0x06 设置写入后光标右移、0x01 清屏。这个顺序错一步屏幕就可能只亮一排黑方块看着像坏了其实只是没初始化对。2.3 锁的驱动继电器、三极管和那颗不能省的续流二极管单片机的 IO 口拉电流只有几百微安灌电流也就十几毫安直接驱动继电器线圈是绝对带不动的必须加一级三极管或者用现成的光耦继电器模块。分立方案是S8050 的基极串 1kΩ 电阻接 P2.2发射极接地集电极接继电器线圈的一端线圈另一端接 5V。基极电阻不能省省了会从 IO 口抽走大电流。线圈两端必须反并联一颗 1N4007阴极朝 5V阳极朝集电极。原因是继电器线圈是感性负载三极管关断瞬间线圈会产生几十伏的反向电动势不泄放就会击穿三极管甚至顺着电源线把单片机一起带走。这颗二极管是血泪经验不是可选项。电磁锁分两类选错了会出安全问题通电开锁型fail-safe断电时是开着的适合消防通道断电开锁型fail-secure断电时是锁死的适合储物柜。做密码锁用后者更符合直觉但要接受「停电就打不开」这个事实重要的柜子得配机械应急钥匙。电源部分是我见过翻车最多的地方。单片机用 5V/2A 适配器锁用 12V/1A 适配器两路电源的负极必须接到一起共地否则继电器控制信号没有参考电平会出现「继电器偶尔吸合偶尔不吸合」的玄学故障。在 5V 电源入口并一颗 1000μF 电解电容和一颗 0.1μF 瓷片电容前者扛继电器吸合的浪涌后者滤高频噪声。如果继电器模块自带光耦隔离单片机的地和锁的地可以分开抗干扰更好。3. 软件骨架用定时器中断把按键扫描和开锁时序拆开硬件搭好之后软件最容易犯的错是把所有事情塞进一个 while(1) 里用一堆 delay 函数凑时序。这样写出来的程序按键响应迟钝、屏幕刷新闪烁、开锁时间不准改一处崩一片。正确的做法是先用定时器中断建立一个统一时基所有跟时间有关的动作都挂在这个时基上。3.1 用 2ms 定时器中断做时基按键消抖和长按判定的统一入口定时器 0 工作在模式 116 位定时晶振 11.0592MHz 时机器周期是 1.085μs要产生 2ms 中断初值算下来是 65536 - 1843 63693也就是 TH0 0xF8、TL0 0xCD 左右。这个数值不用死记用公式反推一遍就有数了。中断服务函数里只做三件事重装初值、给一个全局的 tick 变量加一、把按键扫描的标志位置一。中断里绝对不能放延时、不能刷屏、不能读写 EEPROM否则主循环会被拖慢串口通信也会丢数据。我见过有人在中断里调 LCD 写函数结果屏幕每隔几秒花一次查了两天才发现是中断超时。有了 2ms 的节拍消抖就好办了每 10 个 tick20ms采样一次键盘连续两次采样值相同才认为是稳定状态从按下到确认大约 40ms手指感觉不到延迟但足以滤掉绝大多数抖动。长按判定也一样同一个键连续保持 100 个 tick2000ms就算长按用来做「长按修改键进入改密模式」这类操作。/* 定时器0初始化11.0592MHz 下产生 2ms 中断 */ void Timer0Init(void) { TMOD 0xF0; /* 清掉定时器0的配置位 */ TMOD | 0x01; /* 定时器0模式116位 */ TH0 0xF8; /* 2ms 初值高字节 */ TL0 0xCD; /* 2ms 初值低字节 */ ET0 1; /* 开定时器0中断 */ EA 1; /* 开总中断 */ TR0 1; /* 启动定时器0 */ } /* 中断服务只做计数和置标志不做耗时操作 */ void Timer0Isr(void) interrupt 1 { TH0 0xF8; TL0 0xCD; g_tick2ms; /* 全局节拍主循环按需取模使用 */ if (g_tick2ms % 10 0) g_keyScanFlag 1; /* 每 20ms 通知主循环扫一次键 */ }逻辑说明中断里只累加计数、置标志把真正的按键处理留给主循环。参数上0xF8CD这个初值是按 11.0592MHz 算的如果你手头是 12MHz 晶振同样 2ms 对应的初值是 0xF8F0 附近两者差一点点长时间跑会累积误差所以晶振频率和初值必须配对。g_tick2ms用unsigned int65536 个 tick 是 131 秒做超时计时够用要更长的计时就再开一个变量在主循环里累加。3.2 矩阵键盘扫描法行扫列读与三种无效键的处理矩阵键盘扫描的核心是「逐行拉低、读列判断」。4 行 4 列共 16 个键扫描一轮需要 4 次端口操作。关键细节有三个每次换行之后要等一小段时间让电平稳定一般几十微秒读列之前要先把列线置高因为 51 的 IO 是准双向口读之前必须先写 1扫描到按键之后要记录键值并等待松手否则一次按下会被识别成很多次。无效键有三种情况要单独处理。第一种是「多键同时按下」两行都有列线被拉低这时候要么取第一个扫到的要么直接丢弃我一般丢弃因为真实使用中不会同时按两个键。第二种是「按键卡住不放」需要松手检测否则程序会一直认为有键输入。第三种是「扫描期间按键刚好松开」这是竞态解决办法是扫描完立刻再读一次确认。/* 扫描一次矩阵键盘返回 0~15 的键号无键按下返回 0xFF */ unsigned char KeyScanOnce(void) { unsigned char row, col, key 0xFF; for (row 0; row 4; row) { P1 ~(0x10 row); /* 只把第 row 行拉低其余高低4位写1 */ DelayUs(50); /* 等电平稳定 */ col P1 0x0F; /* 读低4位列线 */ if (col ! 0x0F) { /* 有列被拉低说明有键 */ if (col 0x0E) key row * 4 0; else if (col 0x0D) key row * 4 1; else if (col 0x0B) key row * 4 2; else if (col 0x07) key row * 4 3; else key 0xFF; /* 多键同时按下丢弃 */ break; } } P1 0xFF; /* 恢复全高避免影响其他电路 */ return key; }逻辑说明~(0x10 row)这个表达式是整段代码的核心。0x10 row在第 row 行为 1取反之后那一行为 0、其余为 1低 4 位全是 1正好满足「输出低电平的那一行 输入列线先写 1」的要求。DelayUs(50)是经验值太短电平没稳太长影响扫描速度。返回 0xFF 表示本轮无有效键主循环拿到 0xFF 就跳过不更新状态。这套扫描配合 20ms 采样周期和连续两次一致的判定能滤掉 99% 的抖动和串键。3.3 密码比对、状态机与开锁时序密码锁的本质是一个有限状态机状态不多但转移条件必须写死。我一般分五个状态上锁态 LOCKED、输入态 INPUT、校验态 CHECK、开锁态 OPEN、报警锁定态 ALARM。上电默认 LOCKED屏幕显示「INPUT PASSWORD」每按一个数字键进入 INPUT屏幕对应位置显示星号按确认键进入 CHECK比对密码正确进入 OPEN驱动继电器吸合 3 秒后自动回到 LOCKED错误则计数加一累计三次进入 ALARM锁定 60 秒并置蜂鸣器。密码不存明文是个好习惯哪怕只是做简易项目。最省事的做法是把 4 位密码逐字节异或一个固定值再写进 AT24C02读出来再异或回来。这挡不住真正想破解的人但能挡住「拿编程器读出 EEPROM 直接看到 1234」这种最低级的窥探。首地址再存一个魔数 0x5A 作为「已初始化」标志读出来不等于这个值就写默认密码避免新片子全是 0xFF 导致永远对不上。开锁时序有两个细节。第一继电器吸合之后要立刻把屏幕更新为「OPEN」别等延时时再刷否则用户会觉得卡。第二开锁 3 秒后自动上锁这个 3 秒由 tick 计数实现不能用 delay不然期间按什么键都没反应。开锁期间如果检测到门磁仍然闭合门没开可以提前结束开锁省电也省线圈寿命。4. 代码落地四个模块的可编译 C 代码与参数说明到这一步硬件和思路都有了缺的是能烧进去跑起来的代码。我习惯把工程拆成四个文件按键与显示、存储与校验、主逻辑、公共延时。这里按调用顺序给三段关键代码每一段都能单独编译验证。4.1 键盘扫描与 LCD1602 驱动先让屏幕亮起来调试顺序一定是先显示后按键。屏幕不亮你连按键值对不对都看不见。LCD1602 的驱动就四个函数写指令、写数据、初始化、指定位置显示字符。#include reg52.h sbit LCD_RS P2^5; sbit LCD_RW P2^6; sbit LCD_EN P2^7; #define LCD_DATA P0 /* 写指令RS0RW0数据送到 P0E 打一个高脉冲 */ void LcdWriteCmd(unsigned char cmd) { LCD_RS 0; LCD_RW 0; LCD_DATA cmd; DelayMs(1); LCD_EN 1; DelayMs(1); LCD_EN 0; DelayMs(2); /* 普通指令执行约 40us留足余量 */ } /* 写数据RS1其余同上 */ void LcdWriteData(unsigned char dat) { LCD_RS 1; LCD_RW 0; LCD_DATA dat; DelayMs(1); LCD_EN 1; DelayMs(1); LCD_EN 0; DelayMs(2); } /* 初始化上电延时 三次 0x38 开显示 清屏 */ void LcdInit(void) { DelayMs(50); /* 上电必须等 40ms 以上 */ LcdWriteCmd(0x38); LcdWriteCmd(0x38); LcdWriteCmd(0x38); /* 连发三次确保进入 8 位模式 */ LcdWriteCmd(0x0C); /* 开显示关光标不闪烁 */ LcdWriteCmd(0x06); /* 写入后光标右移 */ LcdWriteCmd(0x01); /* 清屏 */ DelayMs(5); }逻辑说明LCD_EN的高脉冲宽度要大于 450nsDelayMs(1)是保守写法实际几十微秒就够。三次 0x38 是 LCD1602 上电复位的固定流程少一次都可能停在 4 位模式表现是字符显示成乱码。0x0C里的低两位分别控制光标和闪烁密码输入时不希望光标闪所以是 0。清屏指令 0x01 执行时间较长约 1.64ms后面必须跟延时否则紧接着写数据会丢。按键部分把 3.2 节的KeyScanOnce再包一层消抖主循环每 20ms 调用一次连续两次返回同一个非 0xFF 键值才算有效然后等松手。这套逻辑写出来不到 40 行但决定了整个交互手感。4.2 AT24C02 读写与密码校验掉电不丢密码的最小实现AT24C02 走 I2C51 没有硬件 I2C得用两个 IO 口模拟起始、停止、应答和字节收发。时序的关键是延时标准模式 100kHz 下每半个时钟周期约 5μs用DelayUs(5)就能满足慢一点没关系快了反而容易失败。sbit I2C_SCL P2^0; sbit I2C_SDA P2^1; /* 起始信号SCL 高时 SDA 由高变低 */ void I2cStart(void) { I2C_SDA 1; I2C_SCL 1; DelayUs(5); I2C_SDA 0; DelayUs(5); I2C_SCL 0; } /* 停止信号SCL 高时 SDA 由低变高 */ void I2cStop(void) { I2C_SDA 0; I2C_SCL 1; DelayUs(5); I2C_SDA 1; DelayUs(5); } /* 写一个字节返回 0 表示从机应答1 表示无应答 */ unsigned char I2cWriteByte(unsigned char dat) { unsigned char i, ack; for (i 0; i 8; i) { I2C_SDA (dat 0x80) ? 1 : 0; dat 1; DelayUs(5); I2C_SCL 1; DelayUs(5); I2C_SCL 0; } I2C_SDA 1; /* 释放 SDA准备读应答 */ DelayUs(5); I2C_SCL 1; DelayUs(5); ack I2C_SDA; /* 0 为应答 */ I2C_SCL 0; return ack; }逻辑说明I2C 的每个字节都是高位先发第 9 个时钟周期从机把 SDA 拉低表示应答。I2C_SDA 1在读应答之前必须先释放总线否则主机会一直把 SDA 按在地上从机应答读不到。写完一个字节之后AT24C02 需要 5ms 内部写周期这期间它不应答任何指令所以每次写操作之后必须DelayMs(6)这是新手最容易漏的一步漏了就会出「第一次写成功、第二次写丢」的怪事。存密码的布局我一般这样定地址 0x00 存魔数 0x5A地址 0x01 存密码长度地址 0x02 到 0x05 存四位密码的异或值。上电读出来先看魔数不等于 0x5A 就写默认密码「1234」并置魔数。4.3 主循环与开锁动作把状态机串起来主循环里不写任何长延时所有等待都靠 tick 计数。结构是扫键、按状态分发、到时间做状态转移、刷新显示。#define ST_LOCKED 0 #define ST_INPUT 1 #define ST_OPEN 2 #define ST_ALARM 3 unsigned char g_state ST_LOCKED; unsigned char g_input[6], g_len 0; unsigned char g_errCnt 0; unsigned int g_openTick 0, g_alarmTick 0; void main(void) { unsigned char key; Timer0Init(); LcdInit(); PwdLoad(); /* 从 AT24C02 读密码无魔数则写默认 */ LcdShowStr(0, 0, INPUT PASSWORD); while (1) { if (g_keyScanFlag) { g_keyScanFlag 0; key KeyGet(); /* 内部完成 20ms 消抖和松手检测 */ if (key ! 0xFF) KeyHandle(key); /* 按当前状态分发处理 */ } StateMachine(); /* 处理超时、自动上锁、报警解除 */ if (g_dispDirty) { /* 只在内容变化时刷屏避免闪烁 */ g_dispDirty 0; DispRefresh(); } } }逻辑说明KeyGet()内部维护「上次键值」和「稳定计数」两次采样一致才返回返回一次之后要等松手才允许下一次这样按住不放不会连发。StateMachine()里判断g_state ST_OPEN时比较当前 tick 和g_openTick差值超过 3 秒对应的 tick 数1500 个 2ms就回到 LOCKED 并拉低继电器。g_dispDirty是个小技巧密码锁的显示内容变化很少只在按键、状态切换时置位能显著减少 LCD 写操作屏幕不闪寿命也长。开锁动作本身只有三行拉高继电器引脚、记录开锁时刻、把状态改成 OPEN。真正的功夫在异常分支开锁期间再按确认键要不要立即上锁错误三次之后锁定期间按键是不是完全无响应这些边界必须在写代码之前想清楚不然现场演示时按两下就死机。5. 排查与避坑密码锁不工作时先看这 5 条硬件和代码都齐了板子还是不听话这时候别急着改程序先把下面几条按顺序过一遍。这些都是我实际踩过的坑每一条都值得单独记在本子上。5.1 显示与按键类屏幕黑块、按键串键现象一上电后 LCD1602 只显示一排黑方块写什么字符都没反应。原因有三种初始化延时不够少于 40ms、对比度电位器没调到合适位置、RW 引脚悬空导致 LCD 一直处于忙状态。解决在LcdInit第一行加DelayMs(50)0x38 连发三次拿螺丝刀慢慢调电位器调到字符清晰、背景不黑为止RW 不用就老老实实接地别让它悬着。现象二按一个键屏幕出来两三个数字或者手靠近键盘就乱跳。原因是没做消抖或者扫描速度太快或者列线上拉电阻缺失。51 的 P1 口内部上拉很弱线长一点就容易被干扰。解决把扫描周期固定到 20ms、连续两次一致才确认、确认后等松手列线各并一颗 10kΩ 上拉到 5V键盘排线尽量短远离继电器和电源线。现象三某个键永远按不出来其他键正常。多半是那一行或那一列的焊点虚了或者排线里断了一根。解决用万用表蜂鸣档量键盘排线两端通断再量单片机引脚到排线座的通断逐个排除。这种问题代码改一万遍也没用。5.2 电源与驱动类一开锁就复位、锁关不断现象四继电器一吸合屏幕立刻花掉程序从头开始跑。这是电源被拉垮了。原因锁和单片机共用一路 5V继电器吸合瞬间浪涌把电压拉到 4V 以下单片机欠压复位或者续流二极管漏装反电动势顺着电源线打回来。解决主控和锁分开供电、单点共地线圈两端加 1N40075V 入口并 1000μF 电解继电器模块的控制线远离晶振和复位线。现象五断电之后锁还吸着继电器摸上去发烫。原因可能是用了通电开锁型的锁却按断电开锁的逻辑写程序也可能是三极管关断不彻底。解决先确认锁的类型通电开锁的锁断电才弹开程序逻辑要反过来三极管基极加一颗 10kΩ 下拉电阻到地确保 IO 高阻时可靠关断继电器模块如果是低电平触发程序里的电平要取反。5.3 存储与逻辑类密码莫名变成 255现象六断电重上电密码恢复成默认值或者怎么输都不对。原因AT24C02 写完没等 5ms 写周期数据没真正落盘或者首地址没写魔数程序把全 0xFF 的空片子当成了有效密码。解决每次写操作后DelayMs(6)地址 0x00 固定写 0x5A读出不等就重写默认密码密码按字节异或后再存读出来先异或还原。现象七改完密码当时能用重启就失效。多半是只改了 RAM 里的变量没写 EEPROM或者写的时候地址算错了。解决改密流程固定成「校验旧密码 → 写新密码到 EEPROM → 回读比对 → 更新 RAM」回读比对这一步不能省它是唯一能确认写成功的手段。注意调试期可以把当前状态、按键值、错误次数实时显示在 LCD 第二行比接串口打印快得多拔掉电源就看不见也不会留痕迹。6. 从能用到敢用虚位密码、防拆检测和掉电保护一套能开锁的装置和一套敢装在门上的装置差的是几个不起眼的设计。虚位密码是最容易加、效果最直观的一个用户可以在真实密码前后随便加数字只要末尾 4 位对就开锁旁边有人看着也猜不出哪几位是真的。/* 虚位密码输入串长度不短于 6且末尾 4 位等于真实密码即通过 */ unsigned char CheckVirtual(const unsigned char *buf, unsigned char len) { if (len 6 || len 16) return 0; /* 太短没意义太长缓冲区放不下 */ return (buf[len-4] g_pwd[0] buf[len-3] g_pwd[1] buf[len-2] g_pwd[2] buf[len-1] g_pwd[3]); }这段代码把输入缓冲区开到 16 字节按确认键时只比对末尾四位其余位置随便填。缓冲区长度这个参数要跟着 RAM 走51 的 RAM 只有一百多字节开太大别的地方就不够用了。防拆检测用 P3.2 接一个常闭的微动开关装在锁体内部。正常关门时开关闭合P3.2 读到低电平外壳被撬开开关断开P3.2 变高程序立刻进入 ALARM 状态并锁定键盘。这个功能的价值不在于报警声有多大而在于让「拆开面板直接短接继电器」这条路走不通。掉电保护是个容易被忽略的细节。密码本身存在 AT24C02 里不怕断电怕的是开锁过程中断电导致继电器状态不确定。做法是在主循环里检测一个「开锁中」标志上电初始化时先无条件把继电器拉到关闭状态再读 EEPROM 判断是否处于异常断电如果是就要求在 30 秒内重新输入密码才能再次开锁。多这几行代码能避免「停电再来电门自己开了一整晚」这种事故。最后说个我自己的习惯每次改完硬件先不接锁用万用表量三样东西——5V 对地有没有短路、单片机 RST 脚上电瞬间是不是高电平然后变低、继电器控制脚在待机时是不是确定的低电平。这三样都对了再插锁、再烧程序。这个顺序帮我省下的芯片比省下的时间多得多。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑