搜索
bottom↓
回复: 4

矩阵键盘扫描偶尔经常死机,重启电源就好了

[复制链接]

出0入0汤圆

发表于 2015-5-21 11:21:40 | 显示全部楼层 |阅读模式
最近做个矩阵键盘扫描的程序,但偶尔会死机(按键无反应),重新关+开电源又可以按了,按键扫描取消松手检测,是用标志位(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;
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2015-5-21 11:22:30 | 显示全部楼层
自己先检查一下,谢谢大家

出0入0汤圆

发表于 2015-5-21 11:45:19 | 显示全部楼层
本帖最后由 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[scankey*3+temp]++;                                //假设按键按下
                if( (tempport & (1<<temp)) == 0 )                //没有按键按下
                keynum[scankey*3+temp]=0;       
        }
        for(temp=0;temp<9;temp++)
        {
                if(keynum[temp]>MAXKEY)                                        //按键计数到
                {
                        keynum[temp]=0;       
                        keybuf=temp;                                                //得到键值                                       
                         break;
                }
        }

        scankey=(scankey+1)%3;
        temp=Keyscan[scankey];
        LPC_GPIO0->FIOPIN2 = (LPC_GPIO0->FIOPIN2 & 0x8f) | temp;                        //扫描输出

编辑原因,贴的程序注释乱了

出0入0汤圆

发表于 2015-5-21 13:14:45 | 显示全部楼层
矩阵扫描,输出品一般要选OPEN-DRAIN模式,
若没有OPEN-DRAIN模式,那么逐行扫描时,只有一个输出口,其它输出口的改为输入模式.

你想,若PUSH-PULL输出,一个口输出高,一个口输出低,按它们短路,单片机会怎么样?

出0入0汤圆

 楼主| 发表于 2015-5-21 20:49:23 | 显示全部楼层
继续学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-4 00:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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