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; // 重置索引
        }
    }
}

代码说明

  1. GPIO配置: 代码首先配置了GPIO端口,包括回退按钮、矩阵键盘、OLED显示屏和蜂鸣器的引脚。
  2. 按键读取: ReadKeypad() 函数读取矩阵键盘的按键值,并返回对应的数字。
  3. 密码输入: 在main() 函数的循环中,代码检查是否按下回退按钮,如果按下,则将 passwordIndex 减一,并清空当前输入的最后一位数字。同时,代码读取矩阵键盘的按键,如果按下的是数字键,则将值存入 currentPassword 数组。
  4. 密码验证: 当输入的密码长度达到8位时,CheckPassword() 函数验证密码是否正确,并根据结果执行相应的操作:
    • 正确: 显示“Pass!”并发出“嘀嘀”两声。
    • 错误: 显示“Warning!”并发出刺耳的警报声。
  5. 重置: 验证完密码后,代码清空 currentPassword 数组,并重置 passwordIndex,准备接收新的密码输入。

注意事项

  • 该代码示例仅供参考,实际使用时需要根据具体的硬件连接和需求进行相应的修改。
  • 代码中的 delay() 函数可以根据实际情况进行调整。
  • 代码中使用了 OLED_ShowString() 函数,该函数需要根据实际使用的OLED显示屏进行修改。
  • 代码中使用了 GPIO_SetBits()GPIO_ResetBits() 函数,这些函数需要根据实际使用的GPIO端口进行修改。
  • 代码中没有进行异常处理,实际使用时需要添加相应的异常处理机制。

总结

本代码示例展示了如何在STM32F429IGT6微控制器上实现一个带有可回退功能的8位数字密码输入功能。该功能可以应用于多种场景,例如门禁系统、安全设备等。


原文地址: https://www.cveoy.top/t/topic/pl1u 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录