单片机模板四:矩阵按键

一、原理

与独立按键不同的是,按键的两个引脚都分别连接的单片机的I/O端口,一个作为行信号,另外一个作为列信号。矩阵键盘的实现和动态数码管有一定的相似之处,动态数码管是循环通过段选来点亮。而矩阵键盘(4*4)是循环检测键值判断是否按下。

对于矩阵键盘,我们只能逐行扫描,然后读取列的状态信号。如果R3行输出低电平,那么黄色按键如果有按下动作的话,那读取C2列信号也应该为低电平,而该行上其他没有按下动作的按键的列信号则为高电平。因此,我们可以得到矩阵键盘的基本扫描步骤:
    1、 R1输出低电平,R2、R3、R4输出高电平,逐个读取C1、C2、C3、C4判断列信号,如果都为高电平则R1行上没有按键按下。
    2、 R2输出低电平,R1、R3、R4输出高电平,逐个读取C1、C2、C3、C4判断列信号。
    3、 R3输出低电平,R1、R2、R4输出高电平,发现C2列信号为低电平,那么可以判断得R3行的C2列的按键有按下动作。
    4、 R4输出低电平,R1、R3、R4输出高电平,逐个读取C1、C2、C3、C4判断列信号。
    如此循环往复,扫描的按键的状态。

则我们写一个代码,使按下不同的按键,数码管显示不同的数字,如下图(显示红色的数字或字母):

二、代码:

#include "reg52.h"
 
sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;
 
 sfr P4 = 0xc0;//头文件中无P4,定义内存地址
 
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;//行
 
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;//列
 
unsigned char key_num;
unsigned char code SMG_duanma[18] = {
    //  0   1    2    3    4    5    6    7
        0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
    //  8   9    A    B    C    D    E    F
        0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
    //  -   .
        0xbf,0x7f};  //共阳数码管
 
        
void InitHC138(unsigned char n)//译码器电路,选Y
{
    switch (n)
    {
        case 4://LED Y4
            HC138_C = 1;
            HC138_B = 0;
            HC138_A = 0;
        break;
        case 5://蜂鸣器与继电器 Y5
            HC138_C = 1;
            HC138_B = 0;
            HC138_A = 1;
        break;
        case 6://数码管位置 Y6
            HC138_C = 1;
            HC138_B = 1;
            HC138_A = 0;
        break;
        case 7://数码管段码 Y7
            HC138_C = 1;
            HC138_B = 1;
            HC138_A = 1;
        break;
    }
}
 
void SMG_KeyNum(unsigned char value)//数码管位置(只在第一位)、数据
{
    InitHC138(6);
    P0 = 0x01;
    InitHC138(7);
    P0 = value;
}
 
void ScanKeys()
{
//扫描第一行    
    R1 = 0; R2 = R3 = R4 = 1;
    C1 = C2 = C3 = C4 = 1;
    if (C1 == 0)
    {
        while(!C1);//松开后
        key_num = 0;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C2 == 0)
    {
        while(!C2);
        key_num = 1;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C3 == 0)
    {
        while(!C3);
        key_num = 2;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C4 == 0)
    {
        while(!C4);
        key_num = 3;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    
//扫描第二行
    R2 = 0; R1 = R3 = R4 = 1;
    C1 = C2 = C3 = C4 = 1;
    if (C1 == 0)
    {
        while (!C1);
        key_num = 4;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C2 == 0)
    {
        while(!C2);
        key_num = 5;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C3 == 0)
    {
        while(!C3);
        key_num = 6;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C4 == 0)
    {
        while(!C4);
        key_num = 7;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    
//扫描第三行
    R3 = 0; R1 = R2 = R4 = 1;
    C1 = C2 = C3 = C4 = 1;
    if (C1 == 0)
    {
        while(!C1);
        key_num = 8;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C2 == 0)
    {
        while(!C2);
        key_num = 9;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C3 == 0)
    {
        while(!C3);
        key_num = 10;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C4 == 0)
    {
        while(!C4);
        key_num = 11;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    
//扫描第四行
    R4 = 0; R1 = R2 = R3 = 1;
    C1 = C2 = C3 = C4 = 1;
    if (C1 == 0)
    {
        while(!C1);
        key_num = 12;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C2 == 0)
    {
        while(!C2);
        key_num = 13;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C3 == 0)
    {
        while(!C3);
        key_num = 14;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
    else if (C4 == 0)
    {
        while(!C4);
        key_num = 15;
        SMG_KeyNum(SMG_duanma[key_num]);
    }
}
 
void main()
{
    while(1)
    {
        ScanKeys();
    }
}

三、硬件结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值