单片机矩阵按键设计方法的实现

本篇内容主要讲解“单片机矩阵按键设计方法的实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“单片机矩阵按键设计方法的实现”吧!

一、原理

如果我们每个按键用两个位表示,那么一组端口8只引脚则可以实现C82=16个按键的输入。按键4×4布置,按键的键位表示为行和列的交点,同样可以准确的表示按键输入。

单片机矩阵按键设计方法的实现

二、设计步骤

1. 设计电路。

按键布置为4行×4列。P1.0、P1.1、P1.2、P1.3分别连接第1、2、3、4行按键,P1.4、P1.5、P1.6、P1.7分别连接第4、3、2、1列按键。

当某一按键被按下时,对应的行和列对应的引脚被接通而发生变化。由于每一个按键对应了唯一的行列,因此可以精确确定按键的位置。

单片机矩阵按键设计方法的实现

2. 程序设计的思路。

逐行输出低电平,其它引脚输出高电平。对于输出低电平每一行,如果某一列有按键被按下,则对应的引脚会被下拉为低电平。检测低电平所在的位置,即可得到按键所在列。行和列都确定的情况下,即得到按键的所处位置。

本设计中,程序功能设计为当按下某一按键时,动态数码管上显示按键所在行列。

3. 行和列的按键编码

(1)扫描检测行时P1输出的编码

正在检测的行 P1输出
P1.3 P1.2 P1.1 P1.0 二进制编码 十六进制编码
1 1 1 1 0 11111110 0xFE
2 1 1 0 1 11111101 0xFD
3 1 0 1 1 11111011 0xFB
4 0 1 1 1 11110111 0xF7

(2)检测时编码所对应的列

P1输入 被按下按键对应的列
P1.7 P1.6 P1.5 P1.4 二进制编码 十六进制编码*
1 1 1 0 1110 0xEX 4
1 1 0 1 1101 0xDX 3
1 0 1 1 1011 0xBX 2
0 1 1 1 0111 0x7X 1
*X表示因所在行不同,数值有所变化。





4. 程序设计

(1)列数的检测

/**
 * @brief 获取按键所在列
 * 
 * @return 返回1-4或F。F表示无按键。 
 */
UCHAR getColumn()
{
    UCHAR tmp = P1;
    tmp = tmp >> 4; // 请结合P1输入表思考:这是什么操作?

    switch (tmp)
    {
    case 0xF /* 0b1111 */:
        return 0xf;
    case 0xE /* 0b1110 */:
        return 4;
    case 0xD /* 0b1101 */:
        return 3;
    case 0xB /* 0b1011 */:
        return 2;
    case 0x7 /* 0b0111 */:
        return 1;
    }
}

(2)行数和按键的检测

/**
 * @brief 扫描输入的按键并将序号显示在数码管上。
 * 
 */
void inputKeyScan()
{
    UCHAR row = 0x10, column = 0x10;
    UCHAR i;
    const UCHAR rows[] = {0xFE, 0xFD, 0xFB, 0xF7};

    delayNms (20);  //  消除抖动

    for (i = 0; i < 4; i++)
    {
        P1 = rows[i];

        if (getColumn() != 0xf)
        {
            row = 0x10, column = 0x10;
            row = i + 1;
            column = getColumn();
            display4N(0x10, 0x10, row, column);
        }
    }
    
    display4N(0x10, 0x10, 0x10, 0x10);  // 请思考这是为什么?
}

(3)主函数调用

/**
 * @brief 主函数
 * 
 */
void main()
{
    P1 = 0xFF;
    while (1)
    {
        inputKeyScan();
    }
}
三、用到的其它函数

分别在4个数码管上显示数字的函数

/**
 * @brief 分别在4根数码管上显示数字。每个数字的范围都是0-F。
 * 
 * @param n1 第一个数码管上显示的数字。
 * @param n2 第二个数码管上显示的数字。
 * @param n3 第三个数码管上显示的数字。
 * @param n4 第四个数码管上显示的数字。
 */
void display4N(UCHAR n1, UCHAR n2, UCHAR n3, UCHAR n4)
{
    P2 = 0x01; // 选择第一个数码管
    if (n1 >= 0 && n1 < 0x10)
        P0 = HexBCD[n1]; // 显示n1
    else
        P0 = 0xFF;
    delayNms(5);

    P2 = 0x02; // 选择第二个数码管
    if (n2 >= 0 && n2 < 0x10)
        P0 = HexBCD[n2]; // 显示n2
    else
        P0 = 0xFF;
    delayNms(5);

    P2 = 0x04; // 选择第三个数码管
    if (n3 >= 0 && n3 < 0x10)
        P0 = HexBCD[n3]; // 显示n3
    else
        P0 = 0xFF;
    delayNms(5);

    P2 = 0x08; // 选择第四个数码管

    if (n4 >= 0 && n4 < 0x10)
        P0 = HexBCD[n4]; // 显示n4
    else
        P0 = 0xFF;
    delayNms(5);
}

到此,相信大家对“单片机矩阵按键设计方法的实现”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!