STM32F429IGT6矩阵键盘密码输入:可回退功能实现
STM32F429IGT6矩阵键盘密码输入:可回退功能实现
本代码示例展示了如何在STM32F429IGT6微控制器上使用矩阵键盘实现一个8位数字密码输入功能,并通过OLED显示屏和蜂鸣器反馈结果。代码还包含一个可回退功能,允许用户在输入密码时撤销最后一位数字。
代码实现
#include "stm32f4xx.h"
// 定义回退按钮的引脚和端口
#define BACK_BUTTON_PIN GPIO_Pin_0
#define BACK_BUTTON_PORT GPIOA
// 定义矩阵键盘的引脚和端口
#define ROW1_PIN GPIO_Pin_1
#define ROW1_PORT GPIOA
#define ROW2_PIN GPIO_Pin_2
#define ROW2_PORT GPIOA
#define ROW3_PIN GPIO_Pin_3
#define ROW3_PORT GPIOA
#define ROW4_PIN GPIO_Pin_4
#define ROW4_PORT GPIOA
#define COL1_PIN GPIO_Pin_5
#define COL1_PORT GPIOA
#define COL2_PIN GPIO_Pin_6
#define COL2_PORT GPIOA
#define COL3_PIN GPIO_Pin_7
#define COL3_PORT GPIOA
#define COL4_PIN GPIO_Pin_8
#define COL4_PORT GPIOA
// 定义OLED显示屏和蜂鸣器的引脚和端口
#define OLED_PIN GPIO_Pin_9
#define OLED_PORT GPIOA
#define BEEP_PIN GPIO_Pin_10
#define BEEP_PORT GPIOA
// 定义密码长度
#define PASSWORD_LENGTH 8
// 储存密码
uint8_t password[PASSWORD_LENGTH] = {1, 2, 3, 4, 5, 6, 7, 8};
// 当前输入的密码
uint8_t currentPassword[PASSWORD_LENGTH] = {0};
// 当前输入的密码的索引
uint8_t passwordIndex = 0;
// 初始化GPIO配置
void GPIO_Config(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// 使能GPIO时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
// 配置回退按钮引脚为输入模式
GPIO_InitStructure.GPIO_Pin = BACK_BUTTON_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(BACK_BUTTON_PORT, &GPIO_InitStructure);
// 配置矩阵键盘引脚为输入模式,上拉输入
GPIO_InitStructure.GPIO_Pin = ROW1_PIN | ROW2_PIN | ROW3_PIN | ROW4_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(ROW1_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = COL1_PIN | COL2_PIN | COL3_PIN | COL4_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(COL1_PORT, &GPIO_InitStructure);
// 配置OLED引脚为输出模式
GPIO_InitStructure.GPIO_Pin = OLED_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(OLED_PORT, &GPIO_InitStructure);
// 配置蜂鸣器引脚为输出模式
GPIO_InitStructure.GPIO_Pin = BEEP_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(BEEP_PORT, &GPIO_InitStructure);
}
// 读取矩阵键盘的按键
uint8_t ReadKeypad(void) {
// 配置为输出模式,行输出低电平
GPIO_ResetBits(COL1_PORT, COL1_PIN);
GPIO_SetBits(COL2_PORT, COL2_PIN);
GPIO_SetBits(COL3_PORT, COL3_PIN);
GPIO_SetBits(COL4_PORT, COL4_PIN);
// 延时一段时间等待引脚电平稳定
delay(10);
// 读取列引脚电平
if (GPIO_ReadInputDataBit(ROW1_PORT, ROW1_PIN) == 0) return 1;
if (GPIO_ReadInputDataBit(ROW2_PORT, ROW2_PIN) == 0) return 4;
if (GPIO_ReadInputDataBit(ROW3_PORT, ROW3_PIN) == 0) return 7;
if (GPIO_ReadInputDataBit(ROW4_PORT, ROW4_PIN) == 0) return 10;
// 配置为输出模式,行输出低电平
GPIO_SetBits(COL1_PORT, COL1_PIN);
GPIO_ResetBits(COL2_PORT, COL2_PIN);
GPIO_SetBits(COL3_PORT, COL3_PIN);
GPIO_SetBits(COL4_PORT, COL4_PIN);
// 延时一段时间等待引脚电平稳定
delay(10);
// 读取列引脚电平
if (GPIO_ReadInputDataBit(ROW1_PORT, ROW1_PIN) == 0) return 2;
if (GPIO_ReadInputDataBit(ROW2_PORT, ROW2_PIN) == 0) return 5;
if (GPIO_ReadInputDataBit(ROW3_PORT, ROW3_PIN) == 0) return 8;
if (GPIO_ReadInputDataBit(ROW4_PORT, ROW4_PIN) == 0) return 0;
// 配置为输出模式,行输出低电平
GPIO_SetBits(COL1_PORT, COL1_PIN);
GPIO_SetBits(COL2_PORT, COL2_PIN);
GPIO_ResetBits(COL3_PORT, COL3_PIN);
GPIO_SetBits(COL4_PORT, COL4_PIN);
// 延时一段时间等待引脚电平稳定
delay(10);
// 读取列引脚电平
if (GPIO_ReadInputDataBit(ROW1_PORT, ROW1_PIN) == 0) return 3;
if (GPIO_ReadInputDataBit(ROW2_PORT, ROW2_PIN) == 0) return 6;
if (GPIO_ReadInputDataBit(ROW3_PORT, ROW3_PIN) == 0) return 9;
if (GPIO_ReadInputDataBit(ROW4_PORT, ROW4_PIN) == 0) return 11;
return 255; // 表示无按键按下
}
// 延时函数
void delay(uint32_t time) {
uint32_t i;
for (i = 0; i < time * 1000; i++);
}
// 检查密码是否正确
uint8_t CheckPassword(void) {
for (int i = 0; i < PASSWORD_LENGTH; i++) {
if (currentPassword[i] != password[i]) {
return 0; // 密码不正确
}
}
return 1; // 密码正确
}
// 显示“Pass!”
void ShowPass(void) {
// 在OLED上显示“Pass!”
OLED_ShowString(0, 0, 'Pass!', 12, 1);
// 发出“嘀嘀”2声
GPIO_SetBits(BEEP_PORT, BEEP_PIN);
delay(1000);
GPIO_ResetBits(BEEP_PORT, BEEP_PIN);
delay(100);
GPIO_SetBits(BEEP_PORT, BEEP_PIN);
delay(1000);
GPIO_ResetBits(BEEP_PORT, BEEP_PIN);
}
// 显示“Warning!”
void ShowWarning(void) {
// 在OLED上显示“Warning!”
OLED_ShowString(0, 0, 'Warning!', 16, 1);
// 发出刺耳的警报声
while (1) {
GPIO_SetBits(BEEP_PORT, BEEP_PIN);
delay(100);
GPIO_ResetBits(BEEP_PORT, BEEP_PIN);
delay(100);
}
}
int main(void) {
// 初始化GPIO配置
GPIO_Config();
// 初始化OLED显示屏
OLED_Init();
OLED_Clear();
while (1) {
// 检查是否按下回退按钮
if (GPIO_ReadInputDataBit(BACK_BUTTON_PORT, BACK_BUTTON_PIN) == 0) {
if (passwordIndex > 0) {
passwordIndex--; // 索引减一,回退到前一位
currentPassword[passwordIndex] = 0; // 将当前位的值设为0
delay(100); // 延时一段时间等待按钮释放
}
}
// 读取矩阵键盘的按键
uint8_t key = ReadKeypad();
// 如果按下的是回退按钮,则不处理
if (key == 11) continue;
// 如果按下的是数字键,则将值存入当前输入的密码中
if (key >= 0 && key <= 9 && passwordIndex < PASSWORD_LENGTH) {
currentPassword[passwordIndex] = key;
passwordIndex++; // 索引加一,进入下一位
delay(100); // 延时一段时间等待按钮释放
}
// 如果输入的密码长度已达到8位,则检查密码是否正确
if (passwordIndex == PASSWORD_LENGTH) {
if (CheckPassword()) {
ShowPass(); // 显示“Pass!”
} else {
ShowWarning(); // 显示“Warning!”
}
// 清空当前输入的密码
for (int i = 0; i < PASSWORD_LENGTH; i++) {
currentPassword[i] = 0;
}
passwordIndex = 0; // 重置索引
}
}
}
代码说明
- GPIO配置: 代码首先配置了GPIO端口,包括回退按钮、矩阵键盘、OLED显示屏和蜂鸣器的引脚。
- 按键读取:
ReadKeypad()函数读取矩阵键盘的按键值,并返回对应的数字。 - 密码输入: 在
main()函数的循环中,代码检查是否按下回退按钮,如果按下,则将passwordIndex减一,并清空当前输入的最后一位数字。同时,代码读取矩阵键盘的按键,如果按下的是数字键,则将值存入currentPassword数组。 - 密码验证: 当输入的密码长度达到8位时,
CheckPassword()函数验证密码是否正确,并根据结果执行相应的操作:- 正确: 显示“Pass!”并发出“嘀嘀”两声。
- 错误: 显示“Warning!”并发出刺耳的警报声。
- 重置: 验证完密码后,代码清空
currentPassword数组,并重置passwordIndex,准备接收新的密码输入。
注意事项
- 该代码示例仅供参考,实际使用时需要根据具体的硬件连接和需求进行相应的修改。
- 代码中的
delay()函数可以根据实际情况进行调整。 - 代码中使用了
OLED_ShowString()函数,该函数需要根据实际使用的OLED显示屏进行修改。 - 代码中使用了
GPIO_SetBits()和GPIO_ResetBits()函数,这些函数需要根据实际使用的GPIO端口进行修改。 - 代码中没有进行异常处理,实际使用时需要添加相应的异常处理机制。
总结
本代码示例展示了如何在STM32F429IGT6微控制器上实现一个带有可回退功能的8位数字密码输入功能。该功能可以应用于多种场景,例如门禁系统、安全设备等。
原文地址: https://www.cveoy.top/t/topic/pl1u 著作权归作者所有。请勿转载和采集!