笔记仅供学习参考
学习视频链接
<iframe allowfullscreen="true" data-mediaembed="bilibili" frameborder="0" id="hPnGb6p9-1710838376424" src="https://player.bilibili.com/player.html?aid=41275873&page=7"></iframe>【基础技能07】矩阵键盘的扫描原理与基本应用
基本原理
(图片来自欧老师的视频)
讲一下基本原理吧
图片的左半部分是矩阵键盘的布局 R1R2R3R4C1C2C3C4都是IO端口(就是电平高低可以人为控制)
图片右半部分上面是独立按键 下面是矩阵键盘 两者的区别就是
看末端部分
独立按键是要接地的
矩阵键盘接的还是IO口
当按键被按下的时候
独立按键模式的按键位置的电平就会被拉低 原本是1 变成了0
矩阵键盘模式的按键位置会变成IO口的电平
先看看我们的赋值情况吧 这是扫描第一行的
//row 1
r1=0;
r2=r3=r4=1;
c1=c2=c3=c4=1;
在赋值的过程中 我的理解是 老师把C1C2C3C4当作了上图右半部分的矩阵键盘模式的VCC
即全部都赋值为1
然后r1为0 就是图片中的IO口
当有按键被按下的时候 该按键的值会等于IO口的值 在这个情况下 就是0
所以我们在判断的时候写的是 c1==0 就是判断是否是0
然后再接着写相同的三个这样的结构判断C2C3C4就可以完成R1这一行的按键扫描
然后再整体的结构写3遍就完成了R2R3R4的行扫描
代码
代码如下(我的延时程序和老师的不一样 简单讲就是用老师的,我的板子就无法运行)
#include "reg52.h"
sfr P4=0xc0;
sbit r1=P3^0;
sbit r2=P3^1;
sbit r3=P3^2;
sbit r4=P3^3;
sbit c4=P3^4;
sbit c3=P3^5;
sbit c2=P4^2;
sbit c1=P4^4;
unsigned char code smg_duanma[18]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
void selecthc573(unsigned char channel){
switch(channel){
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 displaykeynum(unsigned char value){
selecthc573(6);
P0=0x01;
selecthc573(7);
P0=value;
}
unsigned char key_num;
void delay()
{
unsigned char data i, j;
i = 216;
j = 37;
do
{
while (--j);
} while (--i);
}
void scankeymulti(){
//row 1
r1=0;
r2=r3=r4=1;
c1=c2=c3=c4=1;
if(c1==0){
delay();
if(c1==0){
while(c1==0);
key_num=0;
displaykeynum(smg_duanma[key_num]);
}
}
if(c2==0){
delay();
if(c2==0){
while(c2==0);
key_num=1;
displaykeynum(smg_duanma[key_num]);
}
}
if(c3==0){
delay();
if(c3==0){
while(c3==0);
key_num=2;
displaykeynum(smg_duanma[key_num]);
}
}
if(c4==0){
delay();
if(c4==0){
while(c4==0);
key_num=3;
displaykeynum(smg_duanma[key_num]);
}
}
//row 2
r2=0;
r1=r3=r4=1;
c1=c2=c3=c4=1;
if(c1==0){
delay();
if(c1==0){
while(c1==0);
key_num=4;
displaykeynum(smg_duanma[key_num]);
}
}
if(c2==0){
delay();
if(c2==0){
while(c2==0);
key_num=5;
displaykeynum(smg_duanma[key_num]);
}
}
if(c3==0){
delay();
if(c3==0){
while(c3==0);
key_num=6;
displaykeynum(smg_duanma[key_num]);
}
}
if(c4==0){
delay();
if(c4==0){
while(c4==0);
key_num=7;
displaykeynum(smg_duanma[key_num]);
}
}
//row 3
r3=0;
r2=r1=r4=1;
c1=c2=c3=c4=1;
if(c1==0){
delay();
if(c1==0){
while(c1==0);
key_num=8;
displaykeynum(smg_duanma[key_num]);
}
}
if(c2==0){
delay();
if(c2==0){
while(c2==0);
key_num=9;
displaykeynum(smg_duanma[key_num]);
}
}
if(c3==0){
delay();
if(c3==0){
while(c3==0);
key_num=10;
displaykeynum(smg_duanma[key_num]);
}
}
if(c4==0){
delay();
if(c4==0){
while(c4==0);
key_num=11;
displaykeynum(smg_duanma[key_num]);
}
}
//row 4
r4=0;
r2=r1=r3=1;
c1=c2=c3=c4=1;
if(c1==0){
delay();
if(c1==0){
while(c1==0);
key_num=12;
displaykeynum(smg_duanma[key_num]);
}
}
if(c2==0){
delay();
if(c2==0){
while(c2==0);
key_num=13;
displaykeynum(smg_duanma[key_num]);
}
}
if(c3==0){
delay();
if(c3==0){
while(c3==0);
key_num=14;
displaykeynum(smg_duanma[key_num]);
}
}
if(c4==0){
delay();
if(c4==0){
while(c4==0);
key_num=15;
displaykeynum(smg_duanma[key_num]);
}
}
}
void main(){
while(1){
scankeymulti();
}
}
结果展示
结果也是正确显示了
代码编写要注意那个数码管的段码 可能比赛的时候官方不给的 要自己背下来
还有就是写一段编译一段 好排查问题
注意全局变量的设置 不要设置成局部变量了
等我之后再写一篇中断和定时器hhhhhhh
直接冲!
标签:while,蓝桥,单片机,小蜜蜂,num,key,c3,c2,c1 From: https://blog.csdn.net/weixin_44554793/article/details/136847943