找回密码
 立即注册
楼主: jiuyue77

ai8051U--学习记录

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:19
  • 最近打卡:2025-09-03 11:07:14
已绑定手机

1

主题

10

回帖

99

积分

注册会员

积分
99
发表于 2025-8-23 21:48:06 | 显示全部楼层

ai8051U--虚拟键盘LED和数码管--打卡8

灵活调用各各接口进行使用。

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:19
  • 最近打卡:2025-09-03 11:07:14
已绑定手机

1

主题

10

回帖

99

积分

注册会员

积分
99
发表于 前天 08:49 | 显示全部楼层

ai8051U矩阵按键--打卡9

矩阵按键原理

行端口列端口。当行端口为高电平时,列端口为低电平,按键按下会将按下行的高电平改为低电平,确认按键所在行;当行端口为低电平时,列端口为高电平,按键会将按下的列的高电平改为低电平,确认按键所在列。行号和列号确认即可找到对应的按键。
缺点只能有一个按键按下,检测一个按钮被按下。不支持多按键按下。

图片.png

图片.png

按键内容

第一种写法:顺序操作判断每个端口

// 键号
unsigned char keyNum = 0xFF;
// 行号
#define ROW1 端口号(例如P00)
#define ROW2
// 列号
#define COLUMN1 端口号(例如P05)
#define COLUMN2
#define COLUMN3
#define COLUMN4
void matrixButtons(){
// 1.先确认行号,行端口:高电平,列端口:低电平,行端口判断低电平
COLUMN1 = 0;
COLUMN2 = 0;
COLUMN3 = 0;
COLUMN4 = 0;
ROW1= 1;
ROW2= 1;

if((ROW1 == 0) || (ROW2 == 0)){
    if(ROW1 == 0) && (ROW2 ==0)){
      ROW1 = 1;
      ROW2 = 1;
      keyNum = 0;
      printf_usb(" 非法操作,有多个按键被按下 \r\n");
    }else if((ROW1 == 0) &&(ROW2 == 1)) || ((ROW1 == 1) &&(ROW2 == 0)){
        // 2.确认列号,行端口:低电平,列端口:高电平,列端口判断低电平
        COLUMN1 = 1;
        COLUMN2 = 1;
        COLUMN3 = 1;
        COLUMN4 = 1;
        ROW1= 0;
        ROW2= 0;
        if(ROW1 == 0){
            // 行按键起始号
            keyNum = 1;
            if((COLUMN1 == 0) && (COLUMN2 == 1) && (COLUMN3 == 1) && (COLUMN4 == 1){
               keyNum = keyNum + 1;
              printf_usb(" 按键位置:第1行第1列 \r\n");
            }else if(COLUMN1 == 1) && (COLUMN2 == 0) && (COLUMN3 == 1) && (COLUMN4 == 1){
               keyNum = keyNum + 2;
               printf_usb(" 按键位置:第1行第2列 \r\n");
            }else if(COLUMN1 == 1) && (COLUMN2 == 1) && (COLUMN3 == 0) && (COLUMN4 == 1){
               keyNum = keyNum + 3;
              printf_usb(" 按键位置:第1行第3列 \r\n");
            }else if(COLUMN1 == 1) && (COLUMN2 == 1) && (COLUMN3 == 1) && (COLUMN4 == 0){
               keyNum = keyNum + 4;
              printf_usb(" 按键位置:第1行第4列 \r\n");
            }
        }else if(ROW2 == 0){
            // 行按键起始号
            keyNum = 4;
            if((COLUMN1 == 0) && (COLUMN2 == 1) && (COLUMN3 == 1) && (COLUMN4 == 1){
               keyNum = keyNum + 1;
              printf_usb(" 按键位置:第2行第1列 \r\n");
            }else if(COLUMN1 == 1) && (COLUMN2 == 0) && (COLUMN3 == 1) && (COLUMN4 == 1){
               keyNum = keyNum + 2;
               printf_usb(" 按键位置:第2行第2列 \r\n");
            }else if(COLUMN1 == 1) && (COLUMN2 == 1) && (COLUMN3 == 0) && (COLUMN4 == 1){
               keyNum = keyNum + 3;
              printf_usb(" 按键位置:第2行第3列 \r\n");
            }else if(COLUMN1 == 1) && (COLUMN2 == 1) && (COLUMN3 == 1) && (COLUMN4 == 0){
               keyNum = keyNum + 4;
              printf_usb(" 按键位置:第2行第4列 \r\n");
            }
        }

        // 3.恢复初始值,过滤闪烁问题,行端口:高电平,列端口:低电平
        COLUMN1 = 0;
        COLUMN2 = 0;
        COLUMN3 = 0;
        COLUMN4 = 0;
        ROW1= 1;
        ROW2= 1;
  
    }else if((ROW1 == 1) && (ROW2 == 1)){
         // 清空键值
        keyNum = 0xFF;
    }

}



}

第二种写法:使用十六进制数表示端口,端口组合模式判断匹配
低位:行,高位:列

例如第一行第一列
0x0F = 0000 1111
ROW = P1 & 0x0F = 0000 1110 & 0000 1111 = 0000 1110
0xF0 = 1111 0000
COLUMN = P1 & 0xF0 = 1110 0000 & 1111 0000 = 1110 0000
ROW + COLUMN = 0000 1110 + 1110 0000 = 1110 1110 = 0xEE
所以第一行第一列的按键可以用0xEE来指向。

按位与(&):只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)
按位或(|):参加运算的两个数只要两个数中的一个为1,结果就为1。
按位异或(^):参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
即 0 ^ 0=0 , 0 ^ 1= 1 , 1 ^ 0= 1 , 1 ^ 1= 0 。

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:19
  • 最近打卡:2025-09-03 11:07:14
已绑定手机

1

主题

10

回帖

99

积分

注册会员

积分
99
发表于 昨天 17:57 | 显示全部楼层

ai8051U复位系统--打卡10

回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-9-4 04:34 , Processed in 0.124967 second(s), 61 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表