overdoes_218 2024-03-13 22:50 采纳率: 0%
浏览 25
已结题

关于#c语言#的问题,请各位专家解答!

c51单片机想要做一个重置密码的按键,想通过AT24C02来存储重置开锁的密码应该要怎么控制?

img


#include<reg51.h>
#include<string.h>


// 定义LCD和按键相关SFR
sbit lcd_RS = P2^0;
sbit lcd_RW = P2^1;
sbit lcd_E = P2^2;
sbit jidianqi = P2^7;
sbit buzzer = P3^0;
sbit SDA = P3^3; 
sbit SCL = P3^2; 

// 定义键值数组
char key[] = {0, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30};

// 定义字符串常量
char key2[] = "Correct";
char key3[] = "Error";
char table[] = "password";
char table1[] = "input:";
char passwordInput[5];



// 延时函数
void delay(unsigned int x) {
    unsigned int i;
    for(x = 0; x < 100; x++)
        for(i = 0; i < x; i++);
}

// 五元音报警函数
void wuyuan() {
    int k;
    for(k = 0; k < 20; k++) {
        buzzer = 1;
        delay(39999);
        buzzer = 0;
        delay(39999);
    }
}

// 写命令到LCD函数
void write_com(unsigned char com) {
    while(lcd_busy());
    lcd_RS = 0;
    lcd_RW = 0;
    delay(200);
    P0 = com;
    delay(200);
    lcd_E = 1;
    delay(200);
    lcd_E = 0;
}

// 写数据到LCD函数
void write_dat(unsigned char dat) {
    while(lcd_busy());
    lcd_RS = 1;
    lcd_RW = 0;
    P0 = dat;
    delay(200);
    lcd_E = 1;
    delay(200);
    lcd_E = 0;
}

// 写密码字符到LCD函数
void write_password_char() {
    write_dat(42);
}

// 判断LCD是否忙函数
lcd_busy() {
    unsigned char temp;
    lcd_RS = 0;
    lcd_RW = 1;
    delay(20);
    P0 = 0xff;
    delay(20);
    lcd_E = 1;
    delay(20);
    temp = P0;
    delay(20);
    lcd_E = 0;
    return(temp & 0x80);
}

// LCD初始化函数
void init() {
    write_com(0x01);
    write_com(0x38);
    write_com(0x0c);
    write_com(0x06);
}

// 检测矩阵键盘函数
unsigned char juxingjianpan() {
    unsigned char KeyNumber, x, y;
    P1 = 0x0f;
    x = P1;
    P1 = 0xf0;
    y = P1;
    switch(x + y) {
        case 0xee:      KeyNumber = 1; break;
        case 0xde:      KeyNumber = 2; break;
        case 0xbe:      KeyNumber = 3; break;
        case 0x7e:      KeyNumber = 4; break;
        case 0xed:      KeyNumber = 5; break;
        case 0xdd:      KeyNumber = 6; break;
        case 0xbd:      KeyNumber = 7; break;
        case 0x7d:      KeyNumber = 8; break;
        case 0xeb:      KeyNumber = 9; break;
        case 0xdb:      KeyNumber = 10; break;
        case 0xbb:      KeyNumber = 11; break;
        case 0x7b:      KeyNumber = 12; break;
        case 0xe7:      KeyNumber = 12; break;
    }
    return KeyNumber;
}

void main() {
    static unsigned char position = 0, x = 0, y;
    unsigned int i, KeyNum, passwordLen = 0;

    // 初始化LCD
    init();

    // 在LCD上显示"password"和"input:"
    write_com(0x80);
    for(i = 0; i < 8; i++) {
        write_dat(table[i]);
    }
    write_com(0xc0);
    for(i = 0; i < 6; i++) {
        write_dat(table1[i]);
    }

    while(1) {
        write_com(0xc6 + position);

        // 获取当前按键值
        KeyNum = juxingjianpan();
        if(KeyNum) {
            if(KeyNum <= 10 && x <= 3) {
                write_password_char();
                delay(5);
                passwordInput[passwordLen++] = key[KeyNum];
                position++;
                x++;
            } else if(KeyNum == 11) { // 确认键
                if(strcmp(passwordInput, "1234") == 0) {
                    write_com(0x01);
                    delay(20);
                    write_com(0x86);
                    jidianqi = 0;
                    for(y = 0; y < 7; y++) {
                        write_dat(key2[y]);
                        delay(5);
                    }
                } else {
                    write_com(0x01);
                    delay(20);
                    write_com(0x86);
                    wuyuan();
                    for(y = 0; y < 5; y++) {
                        write_dat(key3[y]);
                        delay(5);
                    }
                }
                memset(passwordInput, 0, sizeof(passwordInput));
                passwordLen = 0;
                x = 0;
                position = 0;
            } else if(KeyNum == 12) { // 清除键
                memset(passwordInput, 0, sizeof(passwordInput));
                passwordLen = 0;
                x = 0;
                position = 0;
                buzzer = 1;
                delay(20);
                buzzer = 0;
                delay(20);
                jidianqi = 1;
                write_com(0x01);
                write_com(0x80);
                for(i = 0; i < 8; i++) {
                    write_dat(table[i]);
                }
                write_com(0xc0);
                for(i = 0; i < 6; i++) {
                    write_dat(table1[i]);
                }
            }
        }
    }
}
  • 写回答

17条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-13 22:53
    关注

    引自免费微信小程序:皆我百晓生

    在您的C语言代码中,已经实现了通过矩阵键盘输入密码、LCD显示以及简单密码验证的功能。但是您提到想要通过AT24C02(EEPROM)来存储重置开锁的密码,目前代码中尚未包含这部分内容。

    为了实现使用AT24C02存储和读取密码,首先需要初始化I2C通信,并编写相应的读写函数以操作EEPROM。以下是一个简化的示例,展示了如何将密码写入到AT24C02:

    #include<reg51.h>
    #include<intrins.h>
    
    #define I2C_SDA P3_3
    #define I2C_SCL P3_2
    
    // 初始化I2C接口
    void init_I2C(void) {
        SDA = 1;
        SCL = 1;
        // 设置为开漏输出模式
        P3_DIR |= (1 << 2) | (1 << 3);
    }
    
    // 向EEPROM发送一个字节
    void send_byte_to_eeprom(unsigned char byte, unsigned int addr) {
        unsigned char i;
        for(i = 0; i < 8; i++) {
            if(byte & 0x80)
                SDA = 1;
            else
                SDA = 0;
            byte <<= 1;
            
            SCL = 1;
            _nop_();
            SCL = 0;
        }
        
        // 发送EEPROM地址
        for(i = 0; i < 8; i++) {
            SDA = addr >> (7 - i);
            SCL = 1;
            _nop_();
            SCL = 0;
        }
    
        // 发送写命令(0x00)
        SDA = 0;
        SCL = 1;
        _nop_();
        SCL = 0;
    
        // 发送停止信号
        SDA = 1;
        SCL = 1;
        _nop_();
        SCL = 0;
        SDA = 1;
    }
    
    // 将密码写入EEPROM指定地址
    void write_password_to_eeprom(char *password, unsigned int eeprom_addr) {
        int i;
        for(i = 0; i < 5; i++) { // 假设密码长度为5个字节
            send_byte_to_eeprom(password[i], eeprom_addr + i);
        }
    }
    
    // 从EEPROM读取一个字节
    unsigned char read_byte_from_eeprom(unsigned int addr) {
        // 实现读取功能...
    }
    
    // 从EEPROM读取密码到缓冲区
    void read_password_from_eeprom(char *buffer, unsigned int eeprom_addr) {
        int i;
        for(i = 0; i < 5; i++) { // 假设密码长度为5个字节
            buffer[i] = read_byte_from_eeprom(eeprom_addr + i);
        }
    }
    
    // 在main函数中添加密码存取逻辑
    void main() {
        // ...已有代码...
    
        // 写密码到EEPROM
        char password[] = "1234";
        write_password_to_eeprom(password, 0); // 假设从EEPROM地址0开始存储
    
        // 读取并验证密码
        char stored_password[6];
        read_password_from_eeprom(stored_password, 0);
    
        if(strcmp(stored_password, "1234") == 0) {
            // 密码正确处理
        } else {
            // 密码错误处理
        }
    
        // ...其余代码...
    }
    

    请根据实际硬件连接和EEPROM型号调整I2C时序和地址。以上代码仅作为参考,您可能需要根据实际情况进一步完善read_byte_from_eeprom函数的实现,以便从EEPROM正确读取数据。

    注意:对于EEPROM操作,通常还需要在写入前进行设备寻址和状态检查,此处为了简化示例未包括这些步骤,实际应用中应当考虑这些细节。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月19日
  • 创建了问题 3月13日

悬赏问题

  • ¥25 oracle中的正则匹配
  • ¥15 关于#vscode#的问题:把软件卸载不会再出现蓝屏
  • ¥15 vimplus出现的错误
  • ¥15 usb无线网卡转typec口
  • ¥30 怎么使用AVL fire ESE软件自带的优化模式来优化设计Soot和NOx?
  • ¥30 解决github RealtimeTTS项目的打包,别用ai回答,没用
  • ¥15 Ubuntu20.04.4.LTS系统如何下载安装VirtualBox虚拟机?
  • ¥15 如何用QDomDocument读取内容为空格的xml数据
  • ¥15 请阅读下面代码,帮我修改下代码
  • ¥15 关于#microsoft#的问题:电脑启动后不显示桌面图标和窗口,除任务栏外无法操作任何东西