27,508
社区成员




今下午我自己尝试写了一个矩阵键盘的代码(扫描列再匹配模式),预想成果是这样的:第一列的第1~4行按键控制LED1~4,第二列的第1~4行按键控制LED5~6。第三第四列逻辑重复第一第二列。(下面按键我以行列排序,例如第一列第二个按键序号就是12)
然后当我写好后发现第三第四列正常运行,但是第一第二列就有问题了,当连续按下第一第二列的的按键时会有两个灯间接亮起,也就是说当我连续按下11的时候(无论按下的间隔大还是小)LED1和LED5会间接亮起,而且两个灯的转换间隔也不一样(相对稳定的按下速度时),后面也类似12是LED2和LED6,13是LED3和LED7,14是LED4和LED8,第二列也是同样结果21=11,22=12,23=13,24=13。
我尝试过修改消抖延迟,但不管是改大还是改小最后都是一样。
然后我尝试分别注释掉第一列和第二列的代码,发现可能是其中有错:注释掉第一列代码后,确实第一列按键不工作了,但是第二行依旧是相同问题。反过来只注释第二行也一样.
我用的单片机芯片型号是IAP15F2K61S2(就是学校给的板子),
在对P3赋值时已经写过用P44 P42代替P37 P36口。有消抖处理和松手检测。第三第四列对比第一第二列除了一开始的P3赋值和switch匹配的数值不同(以及没有P44 P42)之外,代码完全一样。
对这个问题我已经找过几个ai,看了好几个原理视频,翻了十几个网页,还试过硬件仿真(但是按下按键的时候不知道为什么会报错然后弹出去),弄了快四个小时还是找不出问题,所以就来请问一下
#include <STC15F2K60S2.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED1=P0^0;
sbit LED2=P0^1;
sbit LED3=P0^2;
sbit LED4=P0^3;
void Delay5ms(); //@11.0592MHz
void key2();
void main()
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
while(1)
{
key2();
}
}
void key2()
{
uchar temp;
P3=0X7F;P44=0;//扫描第一列
temp=P3;temp&=0x0f;
if(temp!=0x0f)
{
Delay5ms();//消抖处理
temp=P3;temp&=0x0f;
if(temp!=0x0f)//确认按下
{
temp=P3;//重新赋值
switch(temp)
{
case 0x7E: P0=0XFE;break;//LED1
case 0x7D: P0=0XFD;break;//LED2
case 0x7B: P0=0XFB;break;//LED3
case 0x77: P0=0XF7;break;//LED4
}
while(temp!=0x0f)
{
temp=P3;
temp&=0x0f;
}
}
}
P3=0XBF;P42=0;//扫描第二列
temp=P3;temp&=0x0f;
if(temp!=0x0f)
{
Delay5ms();
temp=P3;temp&=0x0f;
if(temp!=0x0f)
{
temp=P3;
switch(temp)
{
case 0xbE: P0=0XEF;break;//LED5
case 0xbD: P0=0XDF;break;//LED6
case 0xbB: P0=0XBF;break;//LED7
case 0xb7: P0=0X7F;break;//LED8
}
while(temp!=0x0f)
{
temp=P3;
temp&=0x0f;
}
}
}
P3=0XDF;//扫描第三列
temp=P3;temp&=0x0f;
if(temp!=0x0f)
{
Delay5ms();
temp=P3;temp&=0x0f;
if(temp!=0x0f)
{
temp=P3;
switch(temp)
{
case 0xDE: P0=0XFE;break;//LED1
case 0xDD: P0=0XFD;break;//LED2
case 0xDB: P0=0XFB;break;//LED3
case 0xD7: P0=0XF7;break;//LED4
}
while(temp!=0x0f)
{
temp=P3;
temp&=0x0f;
}
}
}
P3=0XEF;//扫描第四列
temp=P3;temp&=0x0f;
if(temp!=0x0f)
{
Delay5ms();
temp=P3;temp&=0x0f;
if(temp!=0x0f)
{
temp=P3;
switch(temp)
{
case 0xEE: P0=0XEF;break;//LED5
case 0xED: P0=0XDF;break;//LED6
case 0xEB: P0=0XBF;break;//LED7
case 0xE7: P0=0X7F;break;//LED8
}
while(temp!=0x0f)
{
temp=P3;
temp&=0x0f;
}
}
}
}
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}