Arduino与Proteus仿真实例-密码输入、验证与更新仿真
密码输入、验证与更新仿真
本次实例将通过4X4矩阵键盘、LCD1602、EEPROM实现一个密码输入匹配、储存、更新。
1、仿真电路原理图

在仿真电路原理图中,4X4矩阵键盘通过PCF8574 IO扩展器驱动,请参考前面文章:
LCD1602通过4线连接方式驱动,请参考:
EEPROM数据储存与读取,请参考:
2、驱动代码实现
本次应用实例主要功能分为:
1)导入依赖头文件
1 2 3 4 5 6
| #include <LiquidCrystal.h> #include <Keypad\_I2C.h> #include <Keypad.h> #include <Wire.h> #include <EEPROM.h>
|
2)设备定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| // LCD1602 LiquidCrystal lcd(12, 11,5, 4, 3, 2);// RS、RW,D0~D7
#define KEYPAD\_I2CADDR 0x20 // I2C键盘 const byte ROWS = 4; // 4行 const byte COLS = 4; // 4列 char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'\*','0','#','D'} }; // PCF8574IO映射 byte rowPins[ROWS] = {0, 1, 2, 3}; // 连接键盘行引脚 byte colPins[COLS] = {4, 5, 6, 7}; // 连接键盘列引脚
TwoWire \*jwire = &Wire; // 键盘对象 Keypad_I2C kpd( makeKeymap(keys), rowPins, colPins, ROWS, COLS, KEYPAD_I2CADDR, PCF8574, jwire );
|
3)密码储存及操作定义
1 2 3 4 5 6 7 8 9 10 11 12
| #define PASSWORD\_ADDR 0x10 // 密码储存地址 #define PASSWORD\_INIT\_ADDR 0x01 // 密码状态地址 #define PASSWORD\_LEN 0x06 // 密码长度 #define PASSWORD\_UPDATE "\*#01#\*" // 密码更新 #define PASSWORD\_CMD\_COMPARE 0x01 // 密码验证 #define PASSWORD\_CMD\_UPDATE 0x02 // 密码更新
const char inited_password[PASSWORD_LEN] = {'1','2','3','4','5','6'}; // 默认密码 char saved_password[PASSWORD_LEN] = {0}; // EEPROM储存的密码 char current_password[PASSWORD_LEN] = {0}; // 当前输入密码 char password_cmd = PASSWORD_CMD_COMPARE; // 密码操作命令
|
4)默认密码初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 初始化密码 void init\_password(){ int isInited = 0; isInited = EEPROM.read(PASSWORD_INIT_ADDR); // 读取密码状态 if(isInited != 1){ // 密码未初始化 int addr = PASSWORD_ADDR; for(unsigned char i = 0;i < PASSWORD_LEN;i++){ EEPROM.write(addr,inited_password[i]); // 写入默认密码 addr++; } EEPROM.write(PASSWORD_INIT_ADDR,1); // 更新密码标志 Serial.println("initialized password"); } }
|
init_password函数用于初始化默认密码,在第一次开机启动时通过调用EEPROM.write函数将默认密码数据写入EEPROM。
5)从EEPROM中读取密码
1 2 3 4 5 6 7 8 9
| // 读取密码 void read\_password(){ int addr = PASSWORD_ADDR; for(unsigned char i = 0;i < PASSWORD_LEN;i++){ saved_password[i] = (char)EEPROM.read(addr); addr++; } }
|
read_password函数用于从EEPROM中读取密码。通过调用EEPROM.read函数实现。
6)密码验证
1 2 3 4 5 6 7 8 9 10
| // 比较密码 bool compare\_password(char\* pass){ for(unsigned char i = 0;i < PASSWORD_LEN;i++){ if(pass[i] != saved_password[i]){ return false; } } return true; }
|
compare_password函数用于比较当前输入密码与设定的密码。
7)更新密码
1 2 3 4 5 6 7 8 9 10
| // 更新密码 void update\_password(char\* pass){ int addr = PASSWORD_ADDR; for(unsigned char i = 0;i < PASSWORD_LEN;i++){ EEPROM.write(addr,inited_password[i]); addr++; } Serial.println("password updated"); }
|
update_password函数用于更新密码。将最新设置的密码写入到EEPROM中。
8)更新密码指定检测
1 2 3 4
| bool is\_update\_password(char\* pass){ return(pass[0] == '\*' && pass[1] == '#' && pass[2] == '0' && pass[3] == '1' && pass[4] == '#' && pass[5] == '\*'); }
|
9)系统初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void setup() { Serial.begin(9600); // 初始化串口 init\_password(); // 初始化密码 read\_password(); // 读取密码 Serial.print("inited password:"); for(unsigned char i = 0;i < PASSWORD_LEN;i++){ Serial.print((char)saved_password[i]); } Serial.println(); // 初始化LCD1605 lcd.begin(16, 2); // 设置LCD的行和列 // 键盘初始化 jwire->begin(); kpd.begin(); }
|
10)功能逻辑实现
在loop函数实现密码输入、验证、更新逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| unsigned char index = 0; // 当前密码输入索引 bool is_updating_password = false; // 当前页面是否正在更新密码 void loop() { char key = kpd.getKey(); // 扫描键盘输入 if(key){ if(password_cmd == PASSWORD_CMD_COMPARE){ // 密码验证状态输入 current_password[index] = key; if(index == 0){ lcd.clear(); } lcd.setCursor(index, 0); lcd.print('\*'); }else{ // 密码更新状态输入 if(index == 0){ is_updating_password = true; } saved_password[index] = key; current_password[index] = key; lcd.setCursor(index, 2); lcd.print((char)key); } Serial.print("index:"); Serial.print(index); Serial.print(",key="); Serial.println(key); index++; } if(index == 6){ lcd.clear(); lcd.setCursor(0,0); if(is\_update\_password(current_password)){ // 判断输入密码是否为更新指令 password_cmd = PASSWORD_CMD_UPDATE; } if(password_cmd == PASSWORD_CMD_UPDATE){ // 更新密码 if(!is_updating_password){ lcd.clear(); lcd.setCursor(0,0); lcd.print("Update Password:"); }else{ // 更新密码输入完成 is\_update\_password(current_password); lcd.clear(); lcd.setCursor(0,0); lcd.print("Password Updated"); password_cmd = PASSWORD_CMD_COMPARE; is_updating_password = false; } }else{ // 验证密码 password_cmd = PASSWORD_CMD_COMPARE; if(compare\_password(current_password)){ // 验证成功 lcd.print("Password Passed"); }else{ lcd.print("Password Failed"); } } index = 0; } }
|
3、仿真结果

文章来源: https://iotsmart.blog.csdn.net/article/details/127881315
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!