前言
这个项目是 Raspberry Pi Pico 的密码锁系统,使用 I2C LCD 1602 显示屏作为显示, 4×4 矩阵键盘作为密码输入装置,继电器模拟门锁开关。
功能特性
- 密码验证:输入密码后按
*确认,正确则继电器吸合(模拟开锁) - 密码修改:按
#进入修改流程,需先验证旧密码再设置新密码 - 密码隐藏:输入时 LCD 第二行以
*代替实际字符 - 明文修改:修改密码时新密码以明文显示,便于核对
- 扩展字符:支持
0-9及A-D作为密码字符(最多 16 位) - 默认密码:
735560
硬件需求
| 元件 | 规格 | 数量 |
|---|---|---|
| Raspberry Pi Pico | RP2040 | 1 |
| I2C LCD 1602 | 16×2 字符,PCF8574 转接板 | 1 |
| 4×4 矩阵键盘 | 16 键薄膜/机械键盘 | 1 |
| 继电器模块 | 5V/3.3V 继电器 | 1 |
| 杜邦线 | 公母/母母 | 若干 |
引脚接线
| 外设 | 信号 | Pico GPIO | 物理引脚 |
|---|---|---|---|
| LCD 1602 | SDA | GP4 | Pin 6 |
| LCD 1602 | SCL | GP5 | Pin 7 |
| LCD 1602 | VCC | 3.3V | Pin 36 |
| LCD 1602 | GND | GND | Pin 38 |
| 键盘列 C1 | — | GP18 | Pin 24 |
| 键盘列 C2 | — | GP19 | Pin 25 |
| 键盘列 C3 | — | GP20 | Pin 26 |
| 键盘列 C4 | — | GP21 | Pin 27 |
| 键盘行 R1 | — | GP10 | Pin 14 |
| 键盘行 R2 | — | GP11 | Pin 15 |
| 键盘行 R3 | — | GP12 | Pin 16 |
| 键盘行 R4 | — | GP13 | Pin 17 |
| 继电器 | 控制信号 | GP14 | Pin 19 |

键盘布局
┌───┬───┬───┬───┐
│ 1 │ 2 │ 3 │ A │
├───┼───┼───┼───┤
│ 4 │ 5 │ 6 │ B │
├───┼───┼───┼───┤
│ 7 │ 8 │ 9 │ C │
├───┼───┼───┼───┤
│ * │ 0 │ # │ D │
└───┴───┴───┴───┘
按键功能
| 按键 | 功能 |
|---|---|
0-9, A-D | 密码字符输入 |
* | 确认/提交密码 |
# | 进入密码修改模式 / 取消返回 |
使用说明
开机
上电后 LCD 显示:
Enter Password:
█
光标在第二行首位闪烁,等待输入。
输入密码
逐位输入密码字符,LCD 以 * 显示:
Enter Password:
****█
验证密码
输入完毕后按 * 键:
- 密码正确 → 显示
Successful,继电器吸合 300ms,1.5 秒后返回初始页面 - 密码错误 → 显示
Wrong Password,1.5 秒后返回初始页面
修改密码
- 在初始页面按
#键,进入旧密码验证:Old Password █ - 输入当前密码,按
*确认:- 正确 → 进入新密码设置
- 错误 → 显示
Wrong Password,返回旧密码页面重试
- 新密码设置页面:
输入新密码(明文显示,便于核对),按Change Password █*确认 - 显示
Password Changed,2 秒后自动返回初始页面
在修改流程中随时按
#可取消并返回初始页面。
程序结构
oled.c
├── LCD 1602 I2C 驱动 (PCF8574)
│ ├── lcd_init() LCD 初始化 (4-bit 模式)
│ ├── lcd_send_byte() 发送字节 (命令/数据)
│ ├── lcd_clear() 清屏
│ ├── lcd_set_cursor() 设置光标位置
│ ├── lcd_char() 输出单个字符
│ └── lcd_string() 输出字符串
│
├── 4×4 矩阵键盘驱动
│ ├── keypad_init() 初始化键盘 GPIO
│ └── keypad_get_key() 扫描并返回按键字符
│
├── 密码系统
│ ├── show_enter_password_page() 初始输入页面
│ ├── show_old_password_page() 旧密码验证页面
│ ├── show_new_password_page() 新密码设置页面
│ ├── show_result() 结果提示页面
│ ├── display_asterisks() 以 * 显示输入
│ ├── display_plaintext() 明文显示输入
│ ├── append_input() 追加输入字符
│ ├── clear_input() 清空输入缓冲
│ └── relay_success() 继电器触发
│
└── main() 主循环,状态机调度
状态机流程
┌──────────────────────────┐
│ STATE_ENTER_PASSWORD │
│ "Enter Password:" │
│ 第二行: ****光标 │
└─────┬──────────┬─────────┘
[*]验证 [#]修改
│ │
┌────────┴──┐ ┌────┴────────────────┐
│ Successful │ │ STATE_OLD_PASSWORD │
│ 继电器吸合 │ │ "Old Password" │
└────────────┘ │ 第二行: ****光标 │
└────┬──────┬────────┘
[*]验证 [#]取消
│ │
┌───────┴──┐ ┌───┴───────────┐
│ 验证通过 │ │ 返回初始页面 │
└────┬─────┘ └───────────────┘
│
┌────────┴───────────────┐
│ STATE_NEW_PASSWORD │
│ "Change Password" │
│ 第二行: 明文+光标 │
└────┬────────┬─────────┘
[*]确认 [#]取消
│ │
┌───────┴──┐ ┌───┴───────────┐
│Password │ │ 返回初始页面 │
│Changed │ └───────────────┘
│(2秒后返回) │
└───────────┘
编译和烧录
前提条件
- 安装 Raspberry Pi Pico SDK
- 配置
PICO_SDK_PATH环境变量
编译
mkdir build && cd build
cmake ..
make
烧录
- 按住 Pico 上的 BOOTSEL 按钮
- 通过 USB 连接电脑
- 松开 BOOTSEL,Pico 显示为 USB 大容量存储设备
- 将
build/oled.uf2拖入 Pico 磁盘
常见问题
Q: LCD 无显示?
- 检查 I2C 地址:代码默认
0x27,部分模块为0x3F,修改addr变量 - 确认 SDA/SCL 接线正确(GP4→SDA, GP5→SCL)
Q: 键盘无响应?
- 确认行列引脚接线与代码定义一致
- 行列引脚不能接反(列→GP18-21, 行→GP10-13)
Q: 继电器不动作?
- 默认使用 GP13,与键盘行 R4 共用,确保接线正确
- 如需独立引脚,修改
RELAY_SUCCESS_PIN宏


被折叠的 条评论
为什么被折叠?



