TY33333333 2024-06-08 15:50 采纳率: 28.6%
浏览 5

基于STC89C52RC单片机的密码锁的设计

基于STC89C52RC单片机的密码锁的设计
用STC89C52RC单片机作为核心控制元件,用4x4按键中的数字键作为密码输入按键,蜂鸣器用来发出按键声音,所设计密码锁应具有如下功能:(1)总共可以设置8位密码,每位密码值范围为1~8。(2)用户可以自行设定和修改密码。
(3) 按每个密码键时都由声音提示。
(4) 若输入的密码不正确,则报警5s,蜂鸣器响。
(5)开锁密码连续三次输错要报警1分钟,报警期间输入密码无效。
(6) 输入密码完全正确才能开锁,以LED小灯闪烁1s为开锁成果信号

以下是代码,代码运行没有问题,但是下载到板子上没有反应,按键按下蜂鸣器也不会叫,功能实现不了,请问是什么原因。

#include <stdio.h>
#include <string.h>
#include <reg52.h>
#include <intrins.h>

#define PASSWORD_LENGTH 8

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit AD7 = P0^7;
sbit ENLED = P1^4;
sbit BUZZ = P1^6;

unsigned char password[8] = {1, 2, 3, 4, 5, 6, 7, 8};
unsigned char inputPassword[8];
unsigned char inputCount = 0;
unsigned char errorCount = 0;
bit alarmOn = 0;
unsigned int alarmDelay = 0;
bit buSta = 0;

void delay(unsigned int ms) {
    unsigned int i, j;
    for (i = ms; i > 0; i--)
        for (j = 110; j > 0; j--);
}

bit checkPassword() {
    unsigned char i;
    for (i = 0; i < 8; i++) {
        if (inputPassword[i] != password[i]) {
            return 0;
        }
    }
    return 1;
}

void unlock() {
    AD7 = 1;
    delay(1000);
    AD7 = 0;
}

void alarm() {
    BUZZ = 1;
    delay(5000);
    BUZZ = 0;
}

void continuousErrorAlarm() {
    alarmOn = 1;
    alarmDelay = 60000;
    while (alarmDelay > 0) {
        alarm();
        delay(1000);
        alarmDelay--;
    }
    alarmOn = 0;
}

void setPassword(unsigned char inputPassword[8]) {
    memcpy(password, inputPassword, 8);
    unlock();
}

unsigned char inputI = 0;

void InputSetNumber(unsigned char ccode) {
    if (inputI < 16) {
        if ((ccode >= '0') && (ccode <= '9')) {
            inputPassword[inputI] = ccode;
            inputI++;
        }
    }
}

sbit KEY_IN_1 = P2^4;
sbit KEY_IN_2 = P2^5;
sbit KEY_IN_3 = P2^6;
sbit KEY_IN_4 = P2^7;
sbit KEY_OUT_1 = P2^3;
sbit KEY_OUT_2 = P2^2;
sbit KEY_OUT_3 = P2^1;
sbit KEY_OUT_4 = P2^0;

unsigned char KeyCodeMap[4][4] = {
    {'1', '2', '3', 0x26},
    {'4', '5', '6', 0x25},
    {'7', '8', '9', 0x28},
    {'0', 0x1B, 0x0D, 0x27}
};

unsigned char KeySta[4][4] = {
    {1, 1, 1, 1},
    {1, 1, 1, 1},
    {1, 1, 1, 1},
    {1, 1, 1, 1}
};


void KeyAction(unsigned char keycode) {
    if ((keycode >= '0') && (keycode <= '9')) {
        InputSetNumber(keycode);
    } else if (keycode == 0x1B) {
        setPassword(inputPassword);
    } else if (keycode == 0x26) { 
        buSta = ~buSta; 
        }
}
void KeyDriver() {
    unsigned char i, j;
    static unsigned char backup[4][4] = {
        {1, 1, 1, 1},
        {1, 1, 1, 1},
        {1, 1, 1, 1},
        {1, 1, 1, 1}
    };

    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            if (backup[i][j] != KeySta[i][j]) {
                if (backup[i][j] != 0) {
                    KeyAction(KeyCodeMap[i][j]);
                }
                backup[i][j] = KeySta[i][j];
            }
        }
    }
}

unsigned char KeyScan() {
    unsigned char i;
    static unsigned char keyout = 0;
    static unsigned char keybuf[4][4] = {
        {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF}
    };

    keybuf[keyout][0] = (keybuf[keyout][0] << 1) | (KEY_IN_1 == 0 ? 1 : 0);
    keybuf[keyout][1] = (keybuf[keyout][1] << 1) | (KEY_IN_2 == 0 ? 1 : 0);
    keybuf[keyout][2] = (keybuf[keyout][2] << 1) | (KEY_IN_3 == 0 ? 1 : 0);
    keybuf[keyout][3] = (keybuf[keyout][3] << 1) | (KEY_IN_4 == 0 ? 1 : 0);

    for (i = 0; i < 4; i++) {
        if ((keybuf[keyout][i] & 0x0F) == 0x00) {
            KeySta[keyout][i] = 0;
        } else if ((keybuf[keyout][i] & 0x0F) == 0x0F) {
            KeySta[keyout][i] = 1;
        }
    }

    keyout++;
    keyout &= 0x03;

    switch (keyout) {
        case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
        case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
        case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
        case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
        default: break;
    }
    keyDriver();
    
    
    return KeyCodeMap[keyout][i];
}



void main() {
    unsigned char key;
    unsigned char i;

    EA = 1;
    TMOD = 0x11;
    TH0 = 0xFC;
    TL0 = 0x66;
    ET0 = 1;
    TR0 = 1;

    P2 = 0xFF;

    for (i = 0; i < 8; i++) {
        inputPassword[i] = 0;
    }

    while (1) {
        key = KeyScan();
        if (key != 0xFF) {
            // 处理按键事件
            if (key >= '1' && key <= '8') {
                inputPassword[inputCount] = key;
                inputCount++;

                if (inputCount == 8) {
                    if (checkPassword()) {
                        unlock();
                    } else {
                        errorCount++;
                        if (errorCount >= 3) {
                            continuousErrorAlarm();
                            errorCount = 0;
                        } else {
                            delay(5000);
                        }
                    }
                    inputCount = 0;
                }
            }
        }
    }
}
void InterruptTimer0() interrupt 0 {
    TH0 = 0xFC;
    TL0 = 0x66;
}

void InterruptTimer2() interrupt 2 {
    TF2 = 0;
    if (buSta == 1)
        BUZZ = ~BUZZ;
    else
        BUZZ = 1;
}

  • 写回答

1条回答 默认 最新

  • 阿里嘎多学长 2024-06-08 15:50
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    根据您提供的代码和描述,这里有几个可能的原因和解决方案,帮助您排查问题:

    1. 硬件连接问题:首先确保您的硬件连接正确,包括按键、蜂鸣器、LED等。检查是否有断线或接触不良的情况。

    2. 电源问题:确保单片机和所有外围设备都得到了稳定的电源供应。

    3. 晶振配置:检查您的单片机是否配置了正确的晶振,因为定时器依赖于晶振来工作。

    4. 中断配置:您的代码中使用了定时器中断,需要确保中断使能位和定时器控制寄存器配置正确。

    5. 按键扫描逻辑:您的按键扫描逻辑可能存在问题。在KeyScan函数中,KeyCodeMap[keyout][i]这一行代码中i没有在函数内部定义,这将导致未定义行为。您可能需要修改按键扫描逻辑,确保能够正确地读取按键值。

    6. 蜂鸣器控制:在KeyAction函数中,您使用了BUZZ = ~BUZZ;来控制蜂鸣器,但这个操作是在一个非定时器中断的函数中进行的,可能不会按预期工作。您应该在定时器中断服务程序中切换蜂鸣器状态。

    7. 密码输入逻辑:在main函数中,您检查按键是否在'1'到'8'的范围内,但您的KeyCodeMap数组包含了非数字键,这可能导致密码输入逻辑出现问题。

    8. 编译器问题:确保您的代码是使用正确的编译器和配置编译的,不同的编译器可能对寄存器的定义有所不同。

    9. 烧录问题:如果代码没有问题,检查烧录过程是否成功,有时烧录失败也会导致单片机没有反应。

    10. 调试:如果可能的话,使用仿真器或逻辑分析仪来调试您的硬件和软件。

    对于代码实现,您可能需要对上述几点进行修改和调试。由于我无法直接修改您的代码,建议您根据上述建议逐一排查。

    至于参考资料,您可以查看STC89C52RC单片机的官方数据手册和开发指南,这些通常会提供硬件连接、中断配置和定时器使用的详细信息。另外,您也可以参考一些在线论坛和社区,如CSDN、电子发烧友等,那里有许多嵌入式开发者分享的经验和解决方案。

    如果您需要更详细的帮助,建议您将问题发布到专业的嵌入式开发论坛,那里有许多经验丰富的开发者可以提供帮助。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月8日

悬赏问题

  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 易优eyoucms关于二级栏目调用的问题
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题