第 10 篇:矩阵键盘——16 个按键只占 8 个 IO 口

你有 16 个按键需要接。如果用独立按键方式,需要 16 个 IO 口——STC89C52 总共才 32 个 IO。
这就不得不提到IO的多路复用方式中的经典案例——矩阵按键!
矩阵键盘 4×4 = 16 个按键,只占 8 个 IO。


1. 矩阵键盘接线

     P2.0  P2.1  P2.2  P2.3  (行线,输出)
P2.4  [1]   [2]   [3]   [A]
P2.5  [4]   [5]   [6]   [B]
P2.6  [7]   [8]   [9]   [C]
P2.7  [*]   [0]   [#]   [D]
(列线,输入)

2. 行扫描法

unsigned char key_scan(void)
{
    unsigned char row, col;
    unsigned char key_map[4][4] = {
        {''1'', ''2'', ''3'', ''A''},
        {''4'', ''5'', ''6'', ''B''},
        {''7'', ''8'', ''9'', ''C''},
        {''*'', ''0'', ''#'', ''D''},
    };

    for (row = 0; row < 4; row++) {
        P2 = ~(0x10 << row);  // 逐行输出低电平
        // row=0: P2 = 0xEF (1110 1111)
        // row=1: P2 = 0xDF (1101 1111)
        // row=2: P2 = 0xBF (1011 1111)
        // row=3: P2 = 0x7F (0111 1111)

        if ((P2 & 0x0F) != 0x0F) {  // 有列线被拉低
            delay(10);               // 消抖
            if ((P2 & 0x0F) != 0x0F) {
                col = P2 & 0x0F;     // 读列值

                // 找到是第几列
                if (col == 0x0E) return key_map[row][0];
                if (col == 0x0D) return key_map[row][1];
                if (col == 0x0B) return key_map[row][2];
                if (col == 0x07) return key_map[row][3];
            }
        }
    }
    return 0;  // 没按键
}

3. 实战:矩阵键盘输入 → LCD 显示

void main() {
    unsigned char key;
    char buf[17];  // LCD 一行 16 字符 + \0
    unsigned char pos = 0;

    lcd_init();
    lcd_print("Input:");

    while (1) {
        key = key_scan();
        if (key) {
            buf[pos++] = key;
            buf[pos] = '\0';

            lcd_set_cursor(1, 0);
            lcd_print(buf);

            if (pos >= 15) pos = 0;  // 满了从头

            while (key_scan());  // 等松开
        }
    }
}

下一篇:DS18B20 温度传感器——学会读传感器数据

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐