普中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);
        }
    }
}

完结,撒花~

相关推荐
盐焗西兰花14 小时前
鸿蒙学习实战之路 - 图片预览功能实现
学习·华为·harmonyos
Xudde.14 小时前
friendly2靶机渗透
笔记·学习·安全·web安全·php
知识分享小能手14 小时前
CentOS Stream 9入门学习教程,从入门到精通, CentOS Stream 9 命令行基础 —语法知识点与实战详解(4)
linux·学习·centos
码界奇点14 小时前
Java Web学习 第15篇jQuery从入门到精通的万字深度解析
java·前端·学习·jquery
摇滚侠15 小时前
零基础小白自学 Git_Github 教程,GitHub Action 基础概念,笔记22
笔记·git·github
车载测试工程师15 小时前
CAPL学习-ETH功能函数-通用函数
网络·学习·tcp/ip·capl·canoe
OAoffice15 小时前
智能学习培训考试平台如何驱动未来组织:重塑人才发展格局
人工智能·学习·企业智能学习考试平台·学练考一体化平台
linly121916 小时前
ERP学习笔记-频域分析之小波变换fieldtrip
笔记·学习
QiZhang | UESTC16 小时前
学习日记day40
学习
大江东去浪淘尽千古风流人物17 小时前
【MSCKF】UpdaterHelper 学习备注
学习