overdoes_218 2024-03-21 20:55 采纳率: 0%
浏览 12
已结题

关于#单片机#的问题:c51单片机想要做一个密码重置键,按下k13的时候获取输入数字,输入完4位数字之后,发送存储到24c02里面去,读出24c02里面的数据,lcd显示成功

c51单片机想要做一个密码重置键,按下k13的时候获取输入数字,输入完4位数字之后,发送存储到24c02里面去,按下k14的时候,读出24c02里面的数据,进行比较,如果比较正确的话,lcd显示成功,否则失败。求解答,最好是按照我代码的思路来。如果解决问题直接采纳。

#include<reg51.h>
#include<string.h>
#define AT24C02_ADDRESS 0xA0 
#define PASSWORD_SIZE 4
#define LCD_LINE_LENGTH 16
 
// 定义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; // 根据实际硬件连接配置SDA引脚
sbit SCL = P3^2; // 根据实际硬件连接配置SCL引脚
 
 
// 定义键值数组
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 table2[] ="newpassword";
char passwordInput[5];
char newpassword;
 
 
 
// 延时函数
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,debounce_count;
   for (debounce_count = 0; debounce_count < 5; debounce_count++) { // 假设循环5次作为消抖延时
        P1 = 0x0f;
        x = P1;
        P1 = 0xf0;
        y = P1;
 
        // 检查按键是否稳定(连续读取几次都相同)
        if ((x + y) == (P1 & 0x0f) + ((P1 & 0xf0) >> 4)) {
            break;
        }
        delay(10); // 添加一个简短的延时,例如20ms
    }
    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 = 13; break;
        case 0xd7:      KeyNumber = 14; break;
    }
    return KeyNumber;
}
void i2c_init() {
    SDA = 1;
    SCL = 1;
}
 
void i2c_Start(void) {
    SDA = 1;    
    SCL = 1;
    SDA = 0; 
      SCL = 0;
}
void i2c_Stop(void) {
    SDA = 0;
    SCL = 1;    
    SDA = 1;     
}
void i2c_sendByte(unsigned char Byte)       //发送一个字节
{       unsigned char i;
      for(i=0;i<4;i++)
    { SDA = Byte&(0X80>>i);
      SCL = 1;
      SCL = 0;
    }   
}
unsigned char i2c_ReceiverByte(void)     //接收一个字节
{        unsigned char i,Byte=0x00;
       SDA = 1;
      for(i=0;i<4;i++)
     { SCL = 1;
       if(SDA){Byte|=(0x80>>i);}
       SCL = 0;
     }
       return Byte;
}
 
void i2c_sendAck(unsigned char AckBit)
{       SDA =AckBit;
        SCL = 1;
       SCL = 0;
}
unsigned char i2c_ReceiveAck(void)
{   unsigned char  AckBit=0;
    SDA =1;
    SCL =1;
    AckBit=SDA;
    SCL =0;
    return AckBit;
}
void AT24C02_WriteByte( unsigned char wordAddress,Data)     //写字节
{
      i2c_Start();
      i2c_sendByte(AT24C02_ADDRESS);
      i2c_ReceiveAck();
      i2c_sendByte(wordAddress);
      i2c_ReceiveAck();
      i2c_sendByte(Data);
      i2c_ReceiveAck();
      i2c_Stop();
}
 
unsigned char AT24C02_ReadByte(unsigned char wordAddress)
{      unsigned char Data;
      i2c_Start();
      i2c_sendByte(AT24C02_ADDRESS);
      i2c_ReceiveAck();
      i2c_sendByte(wordAddress);
      i2c_ReceiveAck();
      i2c_Start();
      i2c_sendByte(AT24C02_ADDRESS|0x01);
      i2c_ReceiveAck();
      Data=i2c_ReceiverByte();
      i2c_sendAck(1);
      i2c_Stop();
      return Data;
}
 
void main() {
    static unsigned char position = 0, x = 0, y;
    unsigned int i, KeyNum, passwordLen = 0;
    unsigned char j,isMatch;
    unsigned char storedPassword[PASSWORD_SIZE];
    
    // 初始化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_dat(key[KeyNum]);
                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]);
                }
            }else if(KeyNum == 13) { // K13重置密码键位
            write_com(0x01);
            delay(20);
            write_com(0x80);
            for(i = 0; i < strlen(table2); i++) {
                write_dat(table2[i]);
                }            
            i2c_init();
            for(i=0;i<passwordLen;i++)
            { 
             AT24C02_WriteByte(i,passwordInput[i]);
            }
 
            }
           }
 
 
    }
 
}
 
    
            
 
        
 
 
   
 
 


  • 写回答

13条回答 默认 最新

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

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

    针对你的问题,你已经提供了一个C51单片机项目的框架代码,用于实现通过矩阵键盘输入四位密码,并将其存储到24C02 EEPROM中,以及读取EEPROM中的数据进行比较显示的功能。以下是对你的代码进行补充和修正的建议:

    首先,你需要在K14按下时执行读取EEPROM并比较密码的功能,这部分代码应添加在else if(KeyNum == 13)之后:

    else if(KeyNum == 14) { // K14读取并验证密码键位
        memset(newpassword, 0, PASSWORD_SIZE + 1); // 初始化新密码缓冲区
        for(i = 0; i < PASSWORD_SIZE; i++) {
            newpassword[i] = AT24C02_ReadByte(i);
        }
    
        isMatch = strcmp(passwordInput, newpassword) == 0; // 比较输入的新密码与从EEPROM读取的密码
    
        if(isMatch) {
            write_com(0x01);
            delay(20);
            write_com(0x86);
            for(y = 0; y < strlen(key2); y++) {
                write_dat(key2[y]);
                delay(5);
            }
        } else {
            write_com(0x01);
            delay(20);
            write_com(0x86);
            for(y = 0; y < strlen(key3); y++) {
                write_dat(key3[y]);
                delay(5);
            }
        }
    
        // 清除输入状态
        memset(passwordInput, 0, sizeof(passwordInput));
        passwordLen = 0;
        x = 0;
        position = 0;
    }
    

    此外,请注意在项目中使用strcmp()函数之前需要包含 <string.h> 头文件(已包含),并且确保newpassword是一个足够大的数组来存放从EEPROM读取的密码。

    最后,关于EEPROM操作,当写入四位密码时,应当确保地址正确递增,修改AT24C02_WriteByte调用为:

    for(i=0;i<passwordLen && i<PASSWORD_SIZE;i++) {
        AT24C02_WriteByte(i,passwordInput[i]);
    }
    

    这样,当你按下K13后,四位密码将被依次写入EEPROM;而按下K14后,会从EEPROM中读取这四位密码并与当前输入的密码进行比较,然后在LCD上显示“Correct”或“Error”。

    评论 编辑记录

报告相同问题?

问题事件

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

悬赏问题

  • ¥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#的问题:电脑启动后不显示桌面图标和窗口,除任务栏外无法操作任何东西
  • ¥15 如何输入百度,显示本地下载的html文件页面,地址栏还显示百度的地址
  • ¥15 通过kinect制作换装程序但是服装不贴合(标签-ar)