51单片机1602密码锁C程序、proteus仿真、报告! 支持矩阵键盘设置、LCD1602显示、AT24C02存储 支持密码解锁、密码修改 支持三次输错密码锁定键盘并报警3分钟

最近在折腾一个51单片机的密码锁项目,发现把矩阵键盘、LCD显示和EEPROM存储这三兄弟凑一块儿还挺有意思。整个系统用STC89C52当大脑,配了个1602液晶当显示屏,关键数据都存在AT24C02里不怕断电丢失。先给大伙儿看看核心代码里几个有意思的片段:

矩阵键盘扫描这块用了典型的行列反转法,代码写得挺直白:

unsigned char KeyScan() {
    P1 = 0x0f;
    if (P1 != 0x0f) {
        DelayMs(10);
        if (P1 != 0x0f) {
            row = P1 & 0x0f;
            P1 = 0xf0;
            col = P1 & 0xf0;
            return row | col; // 合并行列值
        }
    }
    return 0; // 无按键
}

这玩意儿每次扫描先把P1口低四位拉低,检测到变化后再反转高低四位来定位具体按键。不过要注意消抖处理,实测不加延时的话偶尔会抽风。

密码存储用AT24C02的时候,I2C通信是绕不过的坎。下面这个写字节函数折腾了我俩小时才调通:

void AT24C02_WriteByte(uchar addr, uchar dat) {
    IIC_Start();
    IIC_SendByte(0xA0); // 器件地址
    IIC_WaitAck();
    IIC_SendByte(addr); // 存储地址
    IIC_WaitAck();
    IIC_SendByte(dat);  // 数据
    IIC_WaitAck();
    IIC_Stop();
    DelayMs(10); // 必须延时等待写入完成
}

重点在最后那个10ms延时,手册上说要等5-10ms的写入周期。有次忘了加这个延时,结果读出来的数据总不对,排查了半天才发现是这里掉链子。

输错三次锁定键盘的逻辑实现起来比想象中麻烦:

if(error_count >= 3){
    LCD_ShowString(1,1,"Locked!     ");
    Buzzer = 0; // 开启蜂鸣器
    lock_timer = 180; // 180秒倒计时
    while(lock_timer > 0){
        LCD_ShowNum(2,1,lock_timer/60,2);
        LCD_ShowNum(2,4,lock_timer%60,2);
        DelayMs(1000);
        lock_timer--;
    }
    Buzzer = 1; // 关闭报警
}

这里用了个简单粗暴的倒计时循环,实际跑起来发现DelayMs(1000)并不精确,后来改用了定时器中断来做计时。不过对于演示项目来说,这样凑合也能用。

51单片机1602密码锁C程序、proteus仿真、报告! 支持矩阵键盘设置、LCD1602显示、AT24C02存储 支持密码解锁、密码修改 支持三次输错密码锁定键盘并报警3分钟

Proteus仿真时有个坑要注意:矩阵键盘的列线必须接上拉电阻,不然扫描永远检测不到按键。有次仿真时死活按不出反应,后来才发现原理图里少画了4个10k的上拉电阻,加上去立马就活了。

改密码的流程挺有意思,得先验证旧密码再输两次新密码:

void ChangePassword(){
    uchar new_pass[6], check_pass[6];
    GetInput("Old Password:", old_pass); // 获取旧密码
    if(CheckPassword(old_pass)){
        GetInput("New Password:", new_pass);
        GetInput("Confirm Pass:", check_pass);
        if(memcmp(new_pass, check_pass, 6) == 0){
            WritePassword(new_pass);
            LCD_ShowString(1,1,"Changed!    ");
        }
    }
}

这里用了memcmp来比较两次输入的新密码,比逐个字符对比方便多了。不过要注意数组越界的问题,密码长度固定6位是之前用#define设好的。

整个项目调下来,最费劲的还是状态机切换。从待机界面到输密码、改密码、锁定状态这几个模式切换,稍不留神就出现界面卡死。后来用枚举变量做了个状态标志才理顺流程,看来状态机模式真是嵌入式开发的必备技能。

最后实测发现AT24C02的写入寿命是个隐患,频繁改密码的话估计撑不过半年。不过课程设计嘛,谁还真用这玩意儿当保险柜呢(笑)。倒是报警用的蜂鸣器接了个三极管驱动,仿真时声音模拟不出来,真家伙叫起来能把人吵到耳鸣...

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐