overdoes_218 2024-03-25 21:25 采纳率: 0%
浏览 8

关于#单片机#的问题:在输入键盘数字时,已经输入了4位数字后,本来应该是停下来没有继续显示数字,但是却还是显示最后输入的数字(相关搜索:51单片机)

c51单片机在下面程序里面,在输入键盘数字时,已经输入了4位数字后,本来应该是停下来没有继续显示数字,但是LCD1602却还是显示最后输入的数字。并且一直重复。有没有什么解决的方案。


#include <reg51.h>
#include <string.h>
#define PASSWORD_LENGTH 6
char input_password[PASSWORD_LENGTH];
#define AT24C02_ADDRESS 0xA0
#define LCD_COLS 16
#define PASSWORD_SIZE 4
#define LCD_LINE_LENGTH 16

sbit lcd_RS = P2^0;
sbit lcd_RW = P2^1;
sbit lcd_E = P2^2;
sbit SDA = P3^3;
sbit SCL = P3^2;
sbit jidianqi = P2^7;
char key[] = {0, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30};
char table[] = "password";
char table1[] = "input:";
char table2[] ="newpassword";
int current_input_index = 0;
char passwordInput[5];

char key2[] = "Correct";
char key3[] = "Error";
char newPassword;



void delay(unsigned int x) {
    unsigned int i,j;
    for(i = 0; i < x; i++)
        for(j = 0; j < 12000; j++);
}
void write_com(unsigned char com){
    
    lcd_RS = 0;
    lcd_RW = 0;
    delay(2);
    P0 = com;
    delay(1);
    lcd_E = 1;
    delay(1);
    lcd_E = 0;
}
 
// 写数据到LCD函数
void write_dat(unsigned char dat){
    
    lcd_RS = 1;
    lcd_RW = 0;
    P0 = dat;
    delay(1);
    lcd_E = 1;
    delay(1);
    lcd_E = 0;
}

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;
        case 0xb7:      KeyNumber = 15; break;
    }
    return KeyNumber;
}
void write_password_char() {
    write_dat(42);
}

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<8;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<8;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 storedPassword[PASSWORD_SIZE];
    unsigned char addressToWrite = 0;
    unsigned char addressToRead = 0;

    init();
    i2c_init();

    //LCD上显示"password"和"input:"
    write_com(0x80);
    for(i = 0; i < strlen(table); i++) {
        write_dat(table[i]);
    }
    write_com(0xc0);
    for(i = 0; i < strlen(table1); 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++;               
            }
             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);
                    
                    for(y = 0; y < 5; y++) {
                        write_dat(key3[y]);
                        delay(5);
                    }
               } 
                memset(passwordInput, 0, sizeof(passwordInput));
                passwordLen = 0;
                x = 0;
                position = 0;
                }
                if(KeyNum == 12) { // 清除键
                memset(passwordInput, 0, sizeof(passwordInput));
                passwordLen = 0;
                x = 0;
                position = 0;
                
                
                
               
                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]);
                }
            }
            if (KeyNum == 13) {       //显示'nwepassword'键
            write_com(0x01);
                delay(20);
                write_com(0x80);
                for(i = 0; i < strlen(table2); i++) {
                    write_dat(table2[i]);
                }
            }
            // K14键用于结束输入并写入EEPROM
            if (KeyNum == 14) {
                if (passwordLen > 0 && passwordLen <= PASSWORD_SIZE) {
                    passwordInput[passwordLen] = '\0'; // 添加终止符便于使用strcmp()
                    for(i = 0; i < passwordLen; i++) {
                        AT24C02_WriteByte(addressToWrite++, passwordInput[i]);
                    }
                    x++;
                }          
            }

            // K15键用于验证密码
            if (KeyNum == 15) {
                if (passwordLen > 0 && passwordLen <= PASSWORD_SIZE) {
                    passwordInput[passwordLen] = '\0'; // 添加终止符便于使用strcmp()
                    for(i = 0; i < PASSWORD_SIZE; ++i) {
                        storedPassword[i] = AT24C02_ReadByte(addressToRead++);
                    }
                    storedPassword[PASSWORD_SIZE] = '\0'; // 添加终止符便于使用strcmp()

                    if (strcmp(passwordInput, storedPassword) == 0) {
                        // 密码正确,执行相应操作
                        write_com(0x01);
                        for(y = 0; y < 7; y++) {
                            write_dat(key2[y]);
                            delay(5);
                        }
                    } else {
                        // 密码错误,执行相应操作
                        write_com(0x01);
                        for(y = 0; y < 5; y++) {
                            write_dat(key3[y]);
                            delay(5);
                        }
                    }

                    // 清空输入状态,准备下次输入
                    passwordLen = 0;
                    memset(passwordInput, 0, sizeof(passwordInput));
                    addressToRead = 0;
                }
            }
        }
    }
}


  • 写回答

2条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-03-25 21:43
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    ;#61; 0; } SDA = 1; // 给从机应答}unsigned char i2c_readByte(unsigned char shouldAck) //读取一个字节{ unsigned char i, byte = 0; SDA = 1; for(i = 0; i < 8; i++) { SCL = 1; byte = byte << 1; byte = byte | SDA; SCL = 0; } if (shouldAck) { SDA = 0; SCL = 1; SCL = 0; SDA = 1; } else { SDA = 1; SCL = 1; SCL = 0; } return byte; }void writeTo_AT24C02(unsigned char addr, unsigned char data) { i2c_Start(); i2c_sendByte(AT24C02_ADDRESS + ((addr >> 7) & 0x01)); i2c_sendByte(addr & 0xff); i2c_sendByte(data); i2c_stop();}unsigned char readFrom_AT24C02(unsigned char addr) { unsigned char data; i2c_Start(); i2c_sendByte(AT24C02_ADDRESS + ((addr >> 7) & 0x01)); i2c_sendByte(addr & 0xff); i2c_Start(); i2c_sendByte(AT24C02_ADDRESS + ((addr >> 7) & 0x01)) | 0x01); data = i2c_readByte(0); i2c_stop(); return data;}void display_string(unsigned char line, unsigned char col, char *str) { unsigned char i; if (line == 0) { col |= 0x80; } else { col |= 0xc0; } write_com(col); for (i = 0; str[i] != 0; i++) { write_dat(str[i]); }}void main() { unsigned char i, password_matched, new_password; jidianqi = 1; // 开机先升压 delay(3000); password_matched = 0; // 默认密码未匹配 i2c_init(); init(); while (1) { display_string(0, 0, table); display_string(1, 0, table1); current_input_index = 0; while (1) { do { input_password[current_input_index] = juxingjianpan(); //获取按键值 write_password_char(); // 在LCD上显示星号 current_input_index++; } while (current_input_index < PASSWORD_SIZE); input_password[current_input_index] = 0; //字符串结尾 password_matched = 1; for (i = 0; i < PASSWORD_SIZE; i++) { if (readFrom_AT24C02(i) != input_password[i]) { password_matched = 0; break; } } display_string(0,0,table); if (password_matched) { display_string(1,0,key2); } else { display_string(1,0,key3); } delay(2000); display_string(0,0,table); display_string(1,0,table2); current_input_index = 0; do { newPassword = juxingjianpan(); //获取按键值 write_password_char(); // 在LCD上显示星号 current_input_index++; } while (current_input_index < PASSWORD_SIZE); writeTo_AT24C02(0, newPassword); display_string(0, 0, table); display_string(1, 0, key2); } }} 问题分析: 由于输入密码的部分代码并没有给出,我们暂且无法确定是哪里导致了输入了四位数字后,LCD1602仍然持续显示最后输入的数字。不过,从程序中可以观察到如下几个可能引起问题的地方: 1.程序中有写字符到LCD1602的函数。 void write_dat(unsigned char dat){ lcd_RS = 1; lcd_RW = 0; P0 = dat; delay(1); lcd_E = 1; delay(1); lcd_E = 0; } 如果在输出数字之后,没有清空LCD1602的显示内容,而是直接写新的字符,那么最后一个数字会一直显示在LCD1602屏幕上。解决方案是在每次需要清空屏幕时,写入0x01或者0x02的命令,将屏幕清空。 2. 程序中也没有指定在输入完密码后,将LCD1602上正在显示的内容清空。如果上一次的内容没有被清空,那么新输入的密码将会和上一次的内容重叠,导致LCD1602显示多余的字符。解决方案同上,可以在输入密码之前先清空屏幕。 以上是两种比较常见的问题,如果还存在其他可能引起问题的地方,需要根据实际情况进行排查。
    评论

报告相同问题?

问题事件

  • 创建了问题 3月25日

悬赏问题

  • ¥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#的问题:电脑启动后不显示桌面图标和窗口,除任务栏外无法操作任何东西