51单片机-矩阵按键程序代码

一、先上代码

matrix_keyboard.c

cpp 复制代码
/*******************************************************************************
 * 矩阵键盘驱动程序
 * 
 * 硬件连接说明:
 * ============================================================================
 * 矩阵键盘引脚    单片机引脚      说明
 * ---------------------------------------------------------------------------
 * 行1-行4         P1.0-P1.3      输出,用于扫描
 * 列1-列4         P1.4-P1.7      输入,用于检测按键
 * ============================================================================
 * 
 * 键盘布局:
 * ============================================================================
 * 列1    列2    列3    列4
 * 行1:   1      2      3      上
 * 行2:   4      5      6      下  
 * 行3:   7      8      9      设置
 * 行4:   .      0      OK     清除
 * ============================================================================
 * 
 * 代码使用说明:
 * 1. 在主程序中包含头文件: #include "matrix_keyboard.h"
 * 2. 系统初始化时调用 keyboard_init() 初始化键盘
 * 3. 使用 keyboard_scan() 扫描键盘获取键值
 * 4. 使用 keyboard_get_key() 获取按键(带消抖)
 * 
 * 使用示例代码:
 * ============================================================================
 * #include "matrix_keyboard.h"
 * 
 * void main(void)
 * {
 *     u8 key;
 *     
 *     // 初始化键盘
 *     keyboard_init();
 *     
 *     while(1)
 *     {
 *         // 获取按键
 *         key = keyboard_get_key();
 *         
 *         if(key != KEY_NO_PRESS)
 *         {
 *             // 处理按键
 *             switch(key)
 *             {
 *                 case KEY_1:  // 处理数字1
 *                     break;
 *                 case KEY_UP: // 处理上键
 *                     break;
 *                 // ... 其他按键处理
 *             }
 *         }
 *         
 *         delay_ms(10);  // 适当延时
 *     }
 * }
 * ============================================================================
 * 
 * 注意事项:
 * 1. P1口需要配置为推挽输出模式
 * 2. 扫描频率不宜过高,建议10-20ms扫描一次
 * 3. 键值范围: 0-16 (0表示无按键)
 * 4. 支持按键消抖和按键释放检测
 ******************************************************************************/

#include "matrix_keyboard.h"
/*******************************************************************************
 * 函数名: delay_ms
 * 功能:   毫秒级延时(内部使用)
 * 参数:   ms - 延时的毫秒数
 * 返回值: 无
 * 说明:   该函数为内部函数,用于按键消抖
 ******************************************************************************/
static void delay_ms(int ms)
{
    int i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 110; j++);
}
/*******************************************************************************
 * 函数名: keyboard_init
 * 功能:   初始化矩阵键盘
 * 参数:   无
 * 返回值: 无
 * 说明:   配置键盘端口为初始状态
 *         设置P1口为高电平,准备扫描
 * 使用示例:
 *         keyboard_init();  // 初始化键盘
 ******************************************************************************/
void keyboard_init(void)
{
    KEYBOARD_PORT = 0xFF;  // 设置所有引脚为高电平
}

/*******************************************************************************
 * 函数名: keyboard_scan
 * 功能:   扫描矩阵键盘
 * 参数:   无
 * 返回值: u8 - 键值 (0表示无按键,1-16表示对应按键)
 * 说明:   逐行扫描检测按键,返回检测到的键值
 *         该函数不包含消抖,建议使用 keyboard_get_key()
 * 使用示例:
 *         u8 key = keyboard_scan();  // 扫描键盘
 *         if(key != KEY_NO_PRESS) {
 *             // 有按键按下
 *         }
 ******************************************************************************/
unsigned char keyboard_scan(void)
{
    unsigned char key_value = 0;
    unsigned char row, col;
    
    // 设置行线为输出,列线为输入
    KEYBOARD_PORT = COL_MASK;  // 1111 0000
    
    if((KEYBOARD_PORT & COL_MASK) != COL_MASK) {  // 有按键按下
        // 逐行扫描
        for(row = 0; row < 4; row++) {
            // 将当前行置低,其他行置高
            KEYBOARD_PORT = ~(1 << row) | COL_MASK;
            
            // 检查列
            if((KEYBOARD_PORT & 0x10) == 0) col = 0;  // 第1列
            else if((KEYBOARD_PORT & 0x20) == 0) col = 1;  // 第2列
            else if((KEYBOARD_PORT & 0x40) == 0) col = 2;  // 第3列
            else if((KEYBOARD_PORT & 0x80) == 0) col = 3;  // 第4列
            else continue;
            
            // 计算键值
            key_value = row * 4 + col + 1;  // 键值从1开始
            break;
        }
    }
    
    return key_value;
}

/*******************************************************************************
 * 函数名: keyboard_get_key
 * 功能:   获取按键值(带消抖)
 * 参数:   无
 * 返回值: u8 - 键值 (0表示无按键,1-16表示对应按键)
 * 说明:   包含按键消抖和按键释放检测
 *         只有在按键释放后才返回键值,避免重复触发
 * 使用示例:
 *         u8 key = keyboard_get_key();  // 获取按键
 *         if(key != KEY_NO_PRESS) {
 *             // 处理按键
 *         }
 ******************************************************************************/
unsigned char keyboard_get_key(void)
{
    unsigned char key_value = 0;
    
    // 扫描键盘
    key_value = keyboard_scan();
    
    if(key_value != KEY_NO_PRESS) {  // 有按键按下
        // 消抖延时
        delay_ms(10);
        
        // 再次扫描确认
        if(keyboard_scan() == key_value) {  // 确认按键按下
            // 等待按键释放
            while(keyboard_scan() != KEY_NO_PRESS);
            
            // 再次消抖
            delay_ms(10);
            
            return key_value;
        }
    }
    
    return KEY_NO_PRESS;
}

matrix_keyboard.h

cpp 复制代码
#ifndef __MATRIX_KEYBOARD_H__
#define __MATRIX_KEYBOARD_H__

#include <reg52.h>

//typedef unsigned char u8;
//typedef unsigned int u16;

// 矩阵键盘端口定义
#define KEYBOARD_PORT  P1
#define ROW_MASK       0x0F    // 行掩码 (P1.0-P1.3)
#define COL_MASK       0xF0    // 列掩码 (P1.4-P1.7)

// 键值定义
#define KEY_1          1       // 数字键1
#define KEY_2          2       // 数字键2
#define KEY_3          3       // 数字键3
#define KEY_UP         4       // 上键
#define KEY_4          5       // 数字键4
#define KEY_5          6       // 数字键5
#define KEY_6          7       // 数字键6
#define KEY_DOWN       8       // 下键
#define KEY_7          9       // 数字键7
#define KEY_8          10      // 数字键8
#define KEY_9          11      // 数字键9
#define KEY_SET        12      // 设置键
#define KEY_DOT        13      // 小数点
#define KEY_0          14      // 数字键0
#define KEY_OK         15      // 确认键
#define KEY_CLEAR      16      // 清除键

// 键盘状态
#define KEY_NO_PRESS   0       // 无按键按下

// 函数声明
void keyboard_init(void);
unsigned char keyboard_scan(void);
unsigned char keyboard_get_key(void);

#endif

二、硬件连接说明

模块和硬件的连接方式

Px0-》R1,

PX1->R2

PX2->R3

PX3->R4

PX4->C1

PX5->C2

PX6->C3

PX7->C4

如果自己画电路图

PX0开始接第一行

PX4开始接第一列

三、代码用法

调用函数eyboard_get_key(); 可返回按下的按键数值,16个按键从左上到右下分别为1-16,第一行1-4,按键具体功能据需要自定义了。比如提供的代码中宏定义

#define KEY_UP 4 // 上键

那么就是4号按键代表"上"

相关推荐
智者知已应修善业2 小时前
【51单片机1,左边4个LED灯先闪烁2次后,右边4个LED灯再闪烁2次:2,接着所用灯一起闪烁3次,接着重复步骤1,如此循环。】2023-5-19
c++·经验分享·笔记·算法·51单片机
zd8451015002 小时前
51单片机-串口程序代码
单片机·嵌入式硬件·51单片机
nihao56114 小时前
机器学习:阈值与混淆矩阵
人工智能·机器学习·矩阵
4caf115 小时前
作业2:6位数码管静态显示
嵌入式硬件·51单片机
6Hzlia18 小时前
【Hot 100 刷题计划】 LeetCode 74. 搜索二维矩阵 | C++ 二分查找 (一维展开法)
c++·leetcode·矩阵
跨境麦香鱼18 小时前
2026 Pinterest账号运营攻略:多开养号与矩阵引流实战
大数据·人工智能·矩阵
智者知已应修善业20 小时前
【51单片机利用外部中断编写程序用两个按键控制数码管显示从0到9,S1控制加计数0—9,S2控制减计数9—0。】
c语言·经验分享·笔记·算法·51单片机
智者知已应修善业20 小时前
【51单片机实现0-7和8-1循环显示共阴数码管】2023-5-12
c语言·经验分享·笔记·算法·51单片机
蜕变的小白20 小时前
☆嵌入式硬件的学习 :51单片机 知识总结
单片机·嵌入式硬件·51单片机