普中51单片机学习笔记-矩阵按键

目录

写在前面

矩阵键盘扫描方法对比

按键消抖处理

硬件电路

示例代码


写在前面

矩阵键盘采用行列交叉的结构。按键位于行线和列线的交叉点上:

  • 4×4矩阵键盘:由4根行线和4根列线交叉构成,形成16个按键。

  • 减少I/O占用:16个按键仅需8个I/O口,远少于独立按键。

矩阵键盘扫描方法对比

方法 原理 优点 缺点 适用场景
逐行扫描法 每次将一行拉低,读取列线状态 逻辑直观,易于理解 代码较长,CPU利用率低 初学者学习,实时性要求不高的系统
行列扫描法 先所有列输出低电平读行线,再所有行输出低电平读列线 代码简洁,执行效率高 逻辑相对复杂 实际项目,需要高效扫描的场合

按键消抖处理

按键在按下和释放时会产生机械抖动,导致电平不稳定。处理方法:

  • 软件消抖:检测到按键按下后延时10-20ms,再次检测确认。

  • 硬件消抖(可选):在按键两端并联0.1μF电容。

硬件电路

示例代码

复制代码
#include <reg51.h>

// ================================
// 硬件端口宏定义
// ================================

// 数码管显示端口定义
#define SMG_PORT P0  // 数码管数据线连接的端口

// 矩阵键盘端口定义  
#define KEY_PORT P1  // 矩阵键盘连接的端口

// ================================
// 数码管显示编码(共阴)
// ================================
unsigned char code seg_table[16] = {
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,  // 0-7
    0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71   // 8-15 (A-F)
};

// ================================
// 延时函数
// ================================
void delay_ms(unsigned int ms)
{
    unsigned int i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 123; j++);
}

// ================================
// 键盘扫描函数
// ================================
unsigned char key_scan()
{
    unsigned char x, y, key_value = 0;
    
    // 第一步:所有列输出低电平,行作为输入
    KEY_PORT = 0xF0;  // 列输出0,行输入1
    if(KEY_PORT != 0xF0)
    {  
        delay_ms(10);  // 延时消抖
        
        if(KEY_PORT != 0xF0)
        {
            x = KEY_PORT & 0xF0;  // 保存行状态
            
            // 第二步:所有行输出低电平,列作为输入
            KEY_PORT = 0x0F;  // 行输出0,列输入1
            y = KEY_PORT & 0x0F;  // 保存列状态
            
            // 组合行和列状态确定键值
            switch(x | y)
            {
                case 0xEE: key_value = 1; break;   // 第0行第0列
                case 0xDE: key_value = 2; break;   // 第0行第1列
                case 0xBE: key_value = 3; break;   // 第0行第2列
                case 0x7E: key_value = 4; break;   // 第0行第3列
                
                case 0xED: key_value = 5; break;   // 第1行第0列
                case 0xDD: key_value = 6; break;   // 第1行第1列
                case 0xBD: key_value = 7; break;   // 第1行第2列
                case 0x7D: key_value = 8; break;   // 第1行第3列
                
                case 0xEB: key_value = 9; break;   // 第2行第0列
                case 0xDB: key_value = 10; break;  // 第2行第1列
                case 0xBB: key_value = 11; break;  // 第2行第2列
                case 0x7B: key_value = 12; break;  // 第2行第3列
                
                case 0xE7: key_value = 13; break;  // 第3行第0列
                case 0xD7: key_value = 14; break;  // 第3行第1列
                case 0xB7: key_value = 15; break;  // 第3行第2列
                case 0x77: key_value = 16; break;  // 第3行第3列
                
                default: 
                    key_value = 0;  // 无效按键
                    break;
            }
            
            if(key_value != 0) {
                // 等待按键释放,增加消抖
                delay_ms(10);
                while((KEY_PORT & 0x0F) != 0x0F) {
                    delay_ms(1);  // 短延时避免忙等待
                }
                delay_ms(10);  // 释放消抖
            }
        }
    }
    return key_value;
}

// ================================
// 主函数
// ================================
void main()
{
    unsigned char key_val;
    
    // 系统初始化
    SMG_PORT = 0x00;   // 数码管初始不显示
    KEY_PORT = 0xFF;   // 键盘端口初始化为高电平
    
    while(1)
    {
        key_val = key_scan();
        
        if(key_val != 0)
        {
            // 在数码管上显示按键编号(1-16对应0-F)
            SMG_PORT = seg_table[key_val - 1];
            
            // 添加响应延时,避免重复检测
            delay_ms(200);
        }
    }
}

完结,撒花~

相关推荐
一只小菜鸡..几秒前
南京大学 操作系统 (JYY) 学习笔记:从 UNIX 到 Linux 与庞大的应用生态
笔记·学习·unix
MartinYeung51 小时前
[论文学习]迈向自主医疗人工智能智能体:MIRA系统深度分析
人工智能·学习
熊猫钓鱼>_>3 小时前
ArkTS 装饰器总览:V1 / V2 / 通用装饰器完整学习笔记
笔记·学习·华为·交互·harmonyos·arkts·arkweb
GLDbalala3 小时前
GPU PRO 5 - 5.2 glTF: Designing an Open-Standard Runtime Asset Format笔记
笔记
春生野草3 小时前
个人笔记——栈
笔记
chnyi6_ya3 小时前
论文阅读笔记 | One Sentence, One Drama: 基于多智能体系统的个性化短剧生成
论文阅读·笔记
ysa0510304 小时前
【板子】短序列dp(换成维护更小常数维度的dp)
c++·笔记·算法·板子
Dory_Youth5 小时前
联想笔记本电脑失灵
运维·笔记·电脑
2501_926978335 小时前
认知边缘的双向耦合:从核技术类比到智力货币时代
人工智能·经验分享·笔记·ai写作
hanlin035 小时前
刷题笔记:力扣第242、349题(哈希表)
笔记·算法·leetcode