【蓝桥杯-单片机学习笔记(六)】矩阵键盘控制数码管显示0~F

本文介绍了蓝桥杯单片机训练平台上的矩阵键盘控制数码管显示数字0~F的方法。首先讲解了矩阵键盘的识别原理,然后分析了硬件电路,其中行线连接在P3.0~P3.3,列线连接在P4.4、P4.2、P3.5和P3.4。最后,提到了数码管的使用,并指出程序中需要注意P4口的自定义配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、要求

在CT107D单片机训练平台上,首先将J5处的跳线帽接到1~2引脚,使按键S4~S19组成4*4的矩阵键盘。在扫描按键的过程中,发现有按键触发信号后,待按键松开后,数码管显示相应的数字。按键顺序是:从左至右,从上到下,依次显示0~F。

二、矩阵键盘按键识别方法

矩阵键盘比独立的按键识别要复杂一些。与独立按键不同的是,矩阵键盘的每个按键两个引脚都是连接在单片机的I/O端口,一个作为行信号,另一个作为列信号。

其识别方法是:列线作为输入端,通过电阻接正电源或用程序预设为高电平,并将行线所接的单片机的I/O口作为输出端且预设为低电平。这样,当没有按键按下时,所有列线输入端都是高电平,行线输出是低电平。一旦有按键按下,则列线输入线就会被拉低。这样就可以通过读取输入线的状态就可以得知是否有按键按下并确定是哪个按键按下。

三、硬件电路分析

如图所示是矩阵矩阵键盘与单片机IO口连接硬件电路图。其中矩阵键盘的行线连接在P3.0~P3.3,第一、二列线对应的连接在P4.4和P4.2,第三、四列线对应的连接在P3.5和P3.4。

本次实验中还设计到数码管的使用,数码管硬件电路连接参考:

【蓝桥杯-单片机学习笔记(三)】共阳数码管的静态显示_Backlight__的博客-优快云博客

四、程序

在引脚配置时注意,P4口要自己定义。我使用的头文件reg52.h中没有定义P4,所以在程序中我给P4做了定义,P4口定义后才能使用。

#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char 
    
sfr P4 = 0xc0;  //定义P4口地址

sbit R1 = P3^0; //row-行,定义行
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;

sbit C1 = P4^4; //column-列,定义列
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;



uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                       0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
                       0xbf,0xff};//共阳段码表

void delay_ms(uchar xms)		//@11.0592MHz
{
	uchar i,j;
    while(xms)
    {    
        _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
            while (--j);
        } while (--i);
        xms--;
    }
}

void channel_select(uchar n) //要使用数码管,所以需要对译码器的输出通道进行选择
{
    switch(n)
    {
        case 4 :
            P2 = (P2 & 0x1f) | 0x80;
        break;
        case 5 :
            P2 = (P2 & 0x1f) | 0xa0;
        break;
        case 6 :
            P2 = (P2 & 0x1f) | 0xc0;
        break;
        case 7 :
            P2 = (P2 & 0x1f) | 0xe0;
        break;   
    }
}

void num_display(uchar num) //在数码管上显示字符
{
    channel_select(6);  
    P0 = 0x01;  //打开第一个数码管的位选
    channel_select(7);  //打开数码管的段选
    P0 = num;   //显示字符
}

void key_scanf()
{
    R1 = 0;
    R2 = R3 = R4 = 1;
    C1 = C2 = C3 = C4 = 1;
    if(C1 == 0)
    {
        num_display(table[0]);
        delay_ms(1000);
    }
    else if(C2 == 0)
    {
        num_display(table[1]);
        delay_ms(1000);
    }
    else if(C3 == 0)
    {
        num_display(table[2]);
        delay_ms(1000);
    }
    else if(C4 == 0)
    {
        num_display(table[3]);
        delay_ms(1000);
    }
    
    R2 = 0;
    R1 = R3 = R4 = 1;
    C1 = C2 = C3 = C4 = 1;
    if(C1 == 0)
    {
        num_display(table[4]);
        delay_ms(1000);
    }
    else if(C2 == 0)
    {
        num_display(table[5]);
        delay_ms(1000);
    }
    else if(C3 == 0)
    {
        num_display(table[6]);
        delay_ms(1000);
    }
    else if(C4 == 0)
    {
        num_display(table[7]);
        delay_ms(1000);
    }
    
    R3 = 0;
    R1 = R2 = R4 = 1;
    C1 = C2 = C3 = C4 = 1;
    if(C1 == 0)
    {
        num_display(table[8]);
        delay_ms(1000);
    }
    else if(C2 == 0)
    {
        num_display(table[9]);
        delay_ms(1000);
    }
    else if(C3 == 0)
    {
        num_display(table[10]);
        delay_ms(1000);
    }
    else if(C4 == 0)
    {
        num_display(table[11]);
        delay_ms(1000);
    }
    
    R4 = 0;
    R1 = R3 = R2 = 1;
    C1 = C2 = C3 = C4 = 1;
    if(C1 == 0)
    {
        num_display(table[12]);
        delay_ms(1000);
    }
    else if(C2 == 0)
    {
        num_display(table[13]);
        delay_ms(1000);
    }
    else if(C3 == 0)
    {
        num_display(table[14]);
        delay_ms(1000);
    }
    else if(C4 == 0)
    {
        num_display(table[15]);
        delay_ms(1000);
    }
}


void system_init()
{
    channel_select(4);
    P0 = 0xff;
}

void main()
{
    system_init();
    while(1)
    {
        key_scanf();
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单片机学习之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值