YangHY 发表于 2026-1-20 09:47:55

按6也是正常的

YangHY 发表于 2026-1-20 09:49:10

课后小练:

这个难度有点大大大.........

第十课到此结束

YangHY 发表于 2026-1-21 09:26:21

今天我们继续学习第十一集 矩阵按键

先回忆最简单的独立按键:




YangHY 发表于 2026-1-21 09:29:24

矩阵按键接法不同,IO口少

8个按键,只需要6个I/O口

YangHY 发表于 2026-1-21 09:32:20

如果是16个按键,只需要4列4行

4+4=8个按键!

当然,软件就复杂点,要2个方向扫描

YangHY 发表于 2026-1-21 09:49:05

矩阵按键的一个原理就是用按键2中状态高低电平的一个基础知识

P06P07是不是先给他输出高电平,P00P01P02P03是不是先给他输出低电平

假设K01按下,P06j就变成低电平 ,1端点就变成低电平,确定是P06这行有按键按下

然后4列输出高电平,2行输出低电平

由于 是K1按下,自然是P01对应的1端点是低电平,这样我们就知道是第一行,第二列被按下



按键识别原理:端口默认为高电平,实时读取到引脚为低电平是表示按下。
①第一步:现将PO.0-PO.3输出低电平,PO.6-P0.7输出高电平,如果有按键按下,按下的那一行的10就会变成低电平,就可以判断出哪一行按下了。
②第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一列的10就会变成低电平,就可以判断出哪一列按下了。
③第三步:行列组合一下就可以判断出是哪个按键按下了。

YangHY 发表于 2026-1-21 10:18:32

任务1:数码管显示当前的按键号

u8 key_num = 0xff;

//任务1:数码管显示当前的按键号
void Task_1(void)
{
        //①第一步:现将P0.0-P0.3输出低电平,P0.6-P0.7输出高电平,如果有按键按下,按下的那一行的IO就会变成低电平,就可以判断出哪一行按下了。
        COL1 = 0;
        COL2 = 0;
        COL3 = 0;
        COL4 = 0;
        ROW1 = 1;
        ROW2 = 1;
       
        if(( ROW1 == 0 ) || ( ROW2 == 0 ))                //如果行按键有按下
        {
                if(( ROW1 ==0 ) && ( ROW2 ==0 ))        //如果两行都有按键按下,不处理
                {
                       
                }
                else if((( ROW1 ==1 )&&( ROW2 ==0 )) || (( ROW1 ==0 )&&( ROW2 ==1 )))        //如果有按键按下,而且只有一颗
                {
                        if( ROW1 ==0 )                                //判断哪一行,输出行开始的序号
                                key_num = 0;
                        else if( ROW2 ==0 )
                                key_num = 4;
                               
                        //②第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。
                        COL1 = 1;
                        COL2 = 1;
                        COL3 = 1;
                        COL4 = 1;
                        ROW1 = 0;
                        ROW2 = 0;
                       
                        if( COL1 ==0 )                                //判断哪一列,叠加按键的序号
                        {
//                                key_num = key_num ;
                        }
                        else if( COL2 ==0 )
                        {
                                key_num = key_num + 1;
                        }
                        else if( COL3 ==0 )
                        {
                                key_num = key_num + 2;
                        }
                        else if( COL4 ==0 )
                        {
                                key_num = key_num + 3;
                        }
                }
                COL1 = 0;
                COL2 = 0;
                COL3 = 0;
                COL4 = 0;
                ROW1 = 1;
                ROW2 = 1;               
        }
        else
        {
                key_num = 0xff;
        }
       
        //③第三步:行列组合一下就可以判断出是哪个按键按下了。

}

YangHY 发表于 2026-1-21 10:20:35

为甚可以这样写?

COL1 = 0;
        COL2 = 0;
        COL3 = 0;
        COL4 = 0;
        ROW1 = 1;
        ROW2 = 1;

是因为在io.h里宏定义了:

#ifndef __IO_H
#define __IO_H

#include "config.h"                        //调用头文件

#define ROW1        P06                        //端口定义
#define ROW2        P07
#define COL1        P00
#define COL2        P01
#define COL3        P02
#define COL4        P03

#define HC595_SER         P34
#define HC595_RCK         P35
#define HC595_SCK         P32

extern u8 key_num ;

void LED0_Blink(void);
void LED1_Blink(void);
void LED2_Blink(void);

void KEY_Task(void);
void Task_1(void);
void SEG_Task(void);
void Init_595(void);
//void PW_write_Task(void);

#endif

YangHY 发表于 2026-1-21 10:30:22

这里明显是2行4列

这样写就清晰明了

先在程序里这样:

/*
        #define ROW1        P06                        //端口定义
        #define ROW2        P07
        #define COL1        P00
        #define COL2        P01
        #define COL3        P02
        #define COL4        P03
*/

因为画PCB板的人会自己方便,IO口顺序是很混乱的

我们这样宏定义(建议直接把注释copy到程序中,对着写)

就不会出错,也不用反复打开io.h来看

YangHY 发表于 2026-1-21 10:35:49

if(( ROW1 == 0 ) || ( ROW2 == 0 ))                //如果行按键有按下

C语音中“或”分为两种:逻辑或(||)和按位或(|):

逻辑或(||):用于条件判断,当两个操作数中至少有一个为真时,结果为真。常用于if等条件语句中。例如:if (a > 0 || b < 10)

按位或(|):用于二进制位操作,对两个数的每一位进行或运算。例如:int c = a | b;

就是说这2个条件有1个条件成立,这个条件语句就开始执行


说人话就是2行中有任意一行按钮按下就执行

页: 66 67 68 69 70 71 72 73 74 75 [76] 77 78 79 80 81 82 83 84 85
查看完整版本: 第一课 序言《AI8051U的特点》