014-STM32单片机实现矩阵薄膜键盘设计

1.功能说明

本设计主要是利用STM32驱动矩阵薄膜键盘,当按下按键后OLED显示屏上会对应显示当前的按键键值,可以将此设计扩展做成电子秤、超市收银机、计算器等需要多个按键操作的单片机应用。

2.硬件接线

|------------------|----------------|
| 模块管脚 | STM32单片机管脚 |
| 矩阵键盘行1 | PA0 |
| 矩阵键盘行2 | PA1 |
| 矩阵键盘行3 | PA2 |
| 矩阵键盘行4 | PA3 |
| 矩阵键盘列1 | PA4 |
| 矩阵键盘列2 | PA5 |
| 矩阵键盘列3 | PA6 |
| 矩阵键盘列4 | PA7 |
| 0.96寸OLED显示屏SCL | PB6 |
| 0.96寸OLED显示屏SSDA | PB7 |

3.软件代码

cpp 复制代码
// 定义字符型的4x4矩阵薄膜键盘映射表
char key_map[4][4] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

// IO端口结构体定义,用于描述GPIO端口和针脚
struct IO_PORT
{                                            
        GPIO_TypeDef *GPIO_x; // GPIO端口地址                 
        unsigned short GPIO_pin; // GPIO端口的针脚
};

// 定义行输出的GPIO端口和针脚数组
static struct IO_PORT KEY_OUT[4] = {
        {BUTTON_ROW1_GPIO_PORT, BUTTON_ROW1_GPIO_PIN},
        {BUTTON_ROW2_GPIO_PORT, BUTTON_ROW2_GPIO_PIN},
        {BUTTON_ROW3_GPIO_PORT, BUTTON_ROW3_GPIO_PIN}, 
        {BUTTON_ROW4_GPIO_PORT, BUTTON_ROW4_GPIO_PIN}
};

// 定义列输入的GPIO端口和针脚数组
static struct IO_PORT KEY_IN[4] = {
        {BUTTON_COL1_GPIO_PORT, BUTTON_COL1_GPIO_PIN}, 
        {BUTTON_COL2_GPIO_PORT, BUTTON_COL2_GPIO_PIN},
        {BUTTON_COL3_GPIO_PORT, BUTTON_COL3_GPIO_PIN}, 
        {BUTTON_COL4_GPIO_PORT, BUTTON_COL4_GPIO_PIN}
};

// 定义键盘扫描状态数组
unsigned char key[4][4];

// 初始化4x4键盘的函数
void Button4_4_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    unsigned char i;
    RCC_APB2PeriphClockCmd(BUTTON_GPIO_CLK, ENABLE); // 使能GPIO时钟

    // 初始化行输出端口
    for(i=0;i<4;i++)
    {
        GPIO_InitStructure.GPIO_Pin = KEY_OUT[i].GPIO_pin;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置为推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        
        GPIO_Init(KEY_OUT[i].GPIO_x, &GPIO_InitStructure);
    }
    
    // 初始化列输入端口
    for(i=0;i<4;i++)
    {
        GPIO_InitStructure.GPIO_Pin = KEY_IN[i].GPIO_pin;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 设置为输入上拉
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        
        GPIO_Init(KEY_IN[i].GPIO_x, &GPIO_InitStructure);
    }
    
    // 设置行输出高电平,准备扫描
    for(i = 0; i < 4; i++)
    {
        GPIO_SetBits(KEY_OUT[i].GPIO_x, KEY_OUT[i].GPIO_pin);
    }
}

// 扫描4x4键盘的函数
char Button4_4_Scan(void)
{
    unsigned char i, j;
    for(i = 0; i < 4; i++)
    {
        delay_ms(5); // 延时以稳定信号
        GPIO_ResetBits(KEY_OUT[i].GPIO_x, KEY_OUT[i].GPIO_pin); // 将当前行置低,检测按键
        for(j = 0; j < 4; j++)
        {
            delay_ms(5); // 再次延时
            if(GPIO_ReadInputDataBit(KEY_IN[j].GPIO_x, KEY_IN[j].GPIO_pin) == 0) // 读取列状态,如果为低,则按键被按下
            {
                key[i][j] = 1; // 记录按键状态
                GPIO_SetBits(KEY_OUT[i].GPIO_x, KEY_OUT[i].GPIO_pin); // 恢复当前行高电平
                return key_map[i][j]; // 返回按键对应的字符
            }
            else
            {
                key[i][j] = 0;
            }
        }
        GPIO_SetBits(KEY_OUT[i].GPIO_x, KEY_OUT[i].GPIO_pin); // 恢复当前行高电平
    }
    return 0; // 如果没有按键被按下,返回0或可以选择返回一个特定的字符表示无输入
}

4.获取源码方式

https://download.csdn.net/download/weixin_41011452/90338338

相关推荐
虎王物联6 小时前
STM32 HAL库串口DMA空闲中断:高效接收不定长Modbus数据帧
stm32·单片机·嵌入式硬件·dma·modbus
是隼人7 小时前
buuctf-pwn xdctf2015_pwn200题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
单片机仿真设计9 小时前
【proteus仿真】基于 STC89C52 单片机家用智能台灯设计(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus·毕设
布莱克60511 小时前
数组详解:定义、作用、应用场景及与链表的区别(C/C++ 代码讲解)
c语言·开发语言·c++·数组
hongmai66688811 小时前
MP2348GTL-Z:这颗24V/4A同步降压芯片,把性能和体积平衡得恰到好处
c语言·开发语言·arm开发·单片机·5g
多弗朗皮卡丘11 小时前
C语言梦开始的地方19:文件操作
c语言·开发语言
笨笨饿11 小时前
#135_代码中的类型重定义艺术:从基础封装到函数类型设计
开发语言·stm32·单片机·嵌入式硬件·mcu·物联网·嵌入式实时数据库
万法若空12 小时前
C/C++ 类型别名定义方式对比
java·c语言·c++
LavaLin0113 小时前
STM32H562RGT6 与 STM32F722RET6 规格对比
stm32
佳児素花痴╮14 小时前
STM32U575RIT6(USART)学习
stm32·嵌入式硬件·学习