矩阵键盘扫描偶尔经常死机,重启电源就好了
最近做个矩阵键盘扫描的程序,但偶尔会死机(按键无反应),重新关+开电源又可以按了,按键扫描取消松手检测,是用标志位(flag_hsh)判定的,PA口高4位加了10K上拉电阻,请帮忙分析一下uchar key_press(void)
{
uchar i;
DDRA = 0XFF;
PORTA = 0XF0;
DDRA = 0X0F;
_NOP();
i = PINA;
if(i==0XF0)
{
DDRA=0XFF;
flag_hsh=1; //没有键按下,按键标志位置1
return 0;
}
else
{
DDRA=0XFF;
return 1;
}
}
uchar key_scan(void)
{
uchar keycode=0x12,i=0X7F,j,k1=0x13,k2=0x14,k3=0x15,k4=0x16,k5=0x17,k6=0x18,k7=0x19,k8=0x20,a=0,k=0x21;
delayms(50);
if(key_press()&(flag_hsh==1))
{
flag_hsh=0; //把按键按键标志位置0,防止按键没松开时重复进入扫描程序。
delayms(2);
if(key_press())
{
delayms(4);
if(key_press())
{
delayms(5);
if(key_press())
{
delayms(6);
if(key_press())
{
for(a=0;a<8;a++) //再重复检测8次,看看每次是否每次检测到的值都一样
{
do
{
i=(i<<1|i>>7);
PORTA=i;
DDRA=0X0F;
_NOP();
k=PINA;
j=k&0XF0;
}while(j==0XF0);//此处下面取消松手检测
switch(a)
{
case 0: k1=k;break;
case 1: k2=k;break;
case 2: k3=k;break;
case 3: k4=k;break;
case 4: k5=k;break;
case 5: k6=k;break;
case 6: k7=k;break;
case 7: k8=k;break;
default:break;
}
delayms(2);
}
if((k1==k2)&&(k2==k3)&&(k3==k4)) //检测8次看看每次是否每次检测到的值都一样
{
if((k4==k5)&&(k5==k6)&&(k6==k7)&&(k7==k8))//检测8次看看是否每次检测到的值都一样
{
keycode=k8;
if(open_num==0)//设置标志位,只在第一次按键的时候执行下面的语句,按下结束按键时open_num已清零
{
PORTB=0x00;
PORTD=0x04; //INT0口设置为高电平
led_zong=0;
led_fen=0;
led_dianya=0;
TCCR1B = 0x02;//启动定时器
}
open_num=1;
}
}
}
}
}
}
}
return keycode;
}
自己先检查一下,谢谢大家
我是在在2mS定时器中断中加这个
本帖最后由 xiaodao35 于 2015-5-21 11:48 编辑tempport=LPC_GPIO0->FIOPIN2&0x0e; //读取key0-key2数据(p0.17,18,19)
tempport=tempport>>1;
for(temp=0;temp<3;temp++)
{
keynum++; //假设按键按下
if( (tempport & (1<<temp)) == 0 ) //没有按键按下
keynum=0;
}
for(temp=0;temp<9;temp++)
{
if(keynum>MAXKEY) //按键计数到
{
keynum=0;
keybuf=temp; //得到键值
break;
}
}
scankey=(scankey+1)%3;
temp=Keyscan;
LPC_GPIO0->FIOPIN2 = (LPC_GPIO0->FIOPIN2 & 0x8f) | temp; //扫描输出
编辑原因,贴的程序注释乱了 矩阵扫描,输出品一般要选OPEN-DRAIN模式,
若没有OPEN-DRAIN模式,那么逐行扫描时,只有一个输出口,其它输出口的改为输入模式.
你想,若PUSH-PULL输出,一个口输出高,一个口输出低,按它们短路,单片机会怎么样? 继续学习
页:
[1]