关于PXA270下keyboard驱动的问题

时间:2021-12-22 08:07:26
请教各位大侠,我们使用的是PXA270平台+wince5.0。客户给了一个硬件板子,让我们开发驱动,本来PXa270有一个keyboard接口,但是客户的硬件没有使用,而是使用的IO口连接键盘,电路图如下:
关于PXA270下keyboard驱动的问题
我们不能再更改客户的电路图,因为硬件已经做好,只要重写驱动。
我们的基本步骤如下:中断是GPIO_37,low active。
首先初始化中断:

//Keyboard IRQ
g_pGPIORegs->GAFR1_L&=~(XLLP_GPIO_AF_BIT_FFDSR_MASK);
g_pGPIORegs->GPDR1 &= ~GPIO_37;
g_pGPIORegs->GFER1 |=  GPIO_37;
g_pGPIORegs->GRER1 &= ~GPIO_37

然后在intr.c的enable,disable,done函数中增加中断的设置。
在keypad驱动中,首先为keypad分配地址,如下:

if (g_extKeyPadRegs == NULL)
    {
        PA.QuadPart = MAINSTONEII_BASE_PA_SECONDARY_FLASH;
        g_extKeyPadRegs = (volatile EXT_KEYPAD_REG *) MmMapIoSpace(PA, sizeof(SPDA_KBD_REGS), FALSE);        
    }    
    if (g_pGPIORegs == NULL)
    {
        PA.QuadPart = BULVERDE_BASE_REG_PA_GPIO;
        g_pGPIORegs = (volatile BULVERDE_GPIO_REG *) MmMapIoSpace(PA, sizeof(XLLP_GPIO_T), FALSE);
    }
    if (g_pOSTRegs == NULL)
    {
        PA.QuadPart = BULVERDE_BASE_REG_PA_OST;
        g_pOSTRegs = (volatile BULVERDE_OST_REG *) MmMapIoSpace(PA, sizeof(XLLP_OST_T), FALSE);
    }
    

然后修改KeyPadDataRead函数。

    g_pGPIORegs->GRER1 &= ~ GPIO_37; // Disable interrupt
    g_pGPIORegs->GFER1 &=~ GPIO_37;
    g_pGPIORegs->GEDR1 |=  GPIO_37;
    //Scan keyboard and read scan code
    bRet = (SPDAReadScanCode( (SPDA_KBD_REGS *)g_extKeyPadRegs,pui8Data) == XLLP_TRUE ? TRUE : FALSE);
    g_pGPIORegs->GRER1 &=  ~GPIO_37; //Enable interrupt
    g_pGPIORegs->GFER1 |= GPIO_37;

SPDAReadScanCode是我们自己写的扫描键盘的函数。
现在的问题就是,测试键盘的时候:
1、中断只能发生一次,即我按下一个键一次后,在按其他的键都没有反应了,除非重启动。
2、我按下一个键,在LCD上的显示确是像不停的按,即比方说我按下A键一次,理论上LCD上只显示一个字母a,但是实际上a不停的出现,直到我的wordpad软件崩溃。同时串口信息上显示的是只产生了一次中断,而不是多次。
请大家帮忙分析一下,可能是哪里出现了问题呢?
非常感谢!

27 个解决方案

#1


你的中断线程退出了吗?是否是这个线程一直占用着?

#2


InterruptDone(SYSINTR_KEYPAD);了吗?

#3


对,你的线程退出了吗?

#4


向楼上诸位表示敬意。
OALIntrStaticTranslate(SYSINTR_KEYPAD, IRQ_GPIO0_EXPBD);
这样语句我有。
不过请问中断线程的退出是什么意思?我是个新手,有些东西还不太明白。
在keypad.cpp中,中断的执行过程如下:

BOOL KeyPad::IsrThreadStart()
{
    HANDLE  hthrd;
   hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)KeyPadIsrThread,this,0,NULL);
   CloseHandle(hthrd);
    return TRUE;
}

调用了KeyPadIsrThread函数,如下:

WORD KeyPadIsrThread(KeyPad *v_pKpd)
{
    v_pKpd->IsrThreadProc();
    return 0;
}

调用了IsrThreadProc函数,如下:

BOOL KeyPad::IsrThreadProc()
{    
    m_hevInterrupt = CreateEvent(NULL,FALSE,FALSE,NULL);
    if (m_hevInterrupt == NULL) {
        RETAILMSG(1, (TEXT("IsrThreadProc: InterruptInitialize Failed\r\n")));
    }
    else 
    {
        if (InterruptInitialize(SYSINTR_KEYPAD, m_hevInterrupt, NULL, 0)) 
        {
            KEYBD_IST keyPadIst;
            keyPadIst.hevInterrupt = m_hevInterrupt;            
            keyPadIst.dwSysIntr_Keybd = SYSINTR_KEYPAD;            
            keyPadIst.uiPddId = v_uiPddId;            
            keyPadIst.pfnGetKeybdEvent = KeyPadPdd_GetEventEx2;            
            keyPadIst.pfnKeybdEvent = v_pfnKeyPadEvent;
            // Note: no point in trying to set the thread priority here, because KeybdIstLoop()
            //  forces it after we give up control: 
            KeybdIstLoop(&keyPadIst);
        }
        else
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("KeyPad::IsrThreadProc: InterruptInitialize Failure\r\n")));
        }
    }
    return(0);

请帮忙看看,中断线程的退出是如何做的呢?

#5


"我按下一个键,在LCD上的显示确是像不停的按,即比方说我按下A键一次,理论上LCD上只显示一个字母a,但是实际上a不停的出现,直到我的wordpad软件崩溃。同时串口信息上显示的是只产生了一次中断,而不是多次。"

这是因为你打开的是wordpad, 你的驱动只发送了KeyDown的event, 并没有KeyUp的event, 所以会一直打印键值.
所以, 我觉得你的按键弹起时, 中断没有产生, 会不会是在接下中断发生并处理完后你忘记了清中断? 





#6


楼主,我觉得是你没有退出线程/清中断——这个中断线程等的代码可以参考BSP下的其他例子。
很容易就发现少了什么了。

#7


你把SPDAReadScanCode函数贴出来看看
这里面需要处理防抖动,repeat,长按,短按等多种处理情况
再一个你看你的代码跳出这个SPDAReadScanCode函数了吗?而且跳出来后你的上升沿中断也没有重新Enable

#8


m_hevInterrupt
this 事件在哪挂起的?

#9


关注结果.

#10


谢谢大家的帮忙,我的SPDAReadScanCode函数如下,目前还没有做很多判断键值的动作,只做了扫描键盘的动作。请问应该在哪里增加防抖处理呢?谢谢。

XLLP_BOOL_T SPDAReadScanCode( SPDA_KBD_REGS *v_pKeyPadRegs , XLLP_UINT8_T *pui8Data)
    
{
// total 8*16 key scan_line= bit0-bit3(C) , input_line=bit4-bit7(R)
BYTE   tmp_scanLine=0x01;
int i;
XLLP_BOOL_T retval=XLLP_FALSE;
XLLP_UINT32_T C,R,RthBit,c0,c1,c2,c3,c4,c5,c6,c7;
  int numOfKeysPressed=0;
  XLLP_UINT32_T col[8];
  XLLP_UINT32_T temp_indata; 
 
RETAILMSG(1,(TEXT("ReadScanCodeAutomatically-----SPDA\r\n")));
v_pKeyPadRegs->scan_line = 0xFF;
// Scan keyboard 
for(i=0;i<8;i++)
{
col[i]=0;
v_pKeyPadRegs->scan_line = ~tmp_scanLine; 
       temp_indata = v_pKeyPadRegs->data_in;
temp_indata &= 0x00FFFF;
if(temp_indata != 0xFFFF)
{
 if(temp_indata != 0xFFFF)
 {
    col[i] = temp_indata;
    numOfKeysPressed +=1;     
 }
}
tmp_scanLine<<=1;
 }
if(numOfKeysPressed == 1)
{
for(i=0;i<8;i++)
   {
    if(col[i]!=0)
      {
    C = (XLLP_UINT32_T) i;
    R =  TransVal(&col[i]);  
    R <<=4;     
   }
    }
         *pui8Data = (unsigned char) (C | R);
 }
    else 
           {
    if(numOfKeysPressed > 1)
    {
    c0 = TransVal(&col[0]);
c1 = TransVal(&col[1]);
c2 = TransVal(&col[2]);
    c3 = TransVal(&col[3]);    
c4 = TransVal(&col[4]);
c5 = TransVal(&col[5]);
   c6 = TransVal(&col[6]);
   c7 = TransVal(&col[7]);  
}
else
*pui8Data = NO_KEY;
}
retval = XLLP_TRUE;
   return(retval);
}
int TransVal( XLLP_UINT32_T *val)
{
int i;

for (i=0;i<16;i++)
  {
   if(!(*val & 0x0001)) return i;
   *val >>=1;   
  }
  return i;
}

#11


引用 7 楼 hzdysymbol 的回复:
你把SPDAReadScanCode函数贴出来看看
这里面需要处理防抖动,repeat,长按,短按等多种处理情况
再一个你看你的代码跳出这个SPDAReadScanCode函数了吗?而且跳出来后你的上升沿中断也没有重新Enable

我的代码已经跳出SPDAReadScanCode函数了,跳出后我enable了中断,如下:
 g_pGPIORegs->GRER1 &=  ~GPIO_37; //Enable interrupt
 g_pGPIORegs->GFER1 |= GPIO_37;
请问这两句是否有问题呢?

#12


引用 5 楼 eagle1597 的回复:
"我按下一个键,在LCD上的显示确是像不停的按,即比方说我按下A键一次,理论上LCD上只显示一个字母a,但是实际上a不停的出现,直到我的wordpad软件崩溃。同时串口信息上显示的是只产生了一次中断,而不是多次。"

这是因为你打开的是wordpad, 你的驱动只发送了KeyDown的event, 并没有KeyUp的event, 所以会一直打印键值.
所以, 我觉得你的按键弹起时, 中断没有产生, 会不会是在接下中断发生并处理完后你忘记了清中断?

谢谢,我也再想这个问题,不过我使用的是下降沿产生中断,除非一直按住键,否则波形就是low一下立刻就被拉高了,这样的话,我如何相应按键弹起的中断呢?

#13


如果线程没有退出,你的打印的东西就不停的执行。
结果很像你的现象。

#14


谢谢楼上,我是参考MainstroneII的代码修改的keyboard驱动,除了中断和扫描函数外,线程部分都是使用原始的代码。我查看了一下,没有找到线程应该在哪里退出。

#15


关于只能产生一次中断的问题,在串口上我只能看到一次中断信息,同时我测量中断的pin脚,也量不到下降沿产生,请问硬件上量不到中断是否是软件的问题呢?键盘的中断应该是由硬件发出,而软件响应的吧,如果硬件上量不到中断,是否有可能是硬件有问题,或者是肯定硬件有问题?
谢谢了!

#16


引用 15 楼 jerry79 的回复:
关于只能产生一次中断的问题,在串口上我只能看到一次中断信息,同时我测量中断的pin脚,也量不到下降沿产生,请问硬件上量不到中断是否是软件的问题呢?键盘的中断应该是由硬件发出,而软件响应的吧,如果硬件上量不到中断,是否有可能是硬件有问题,或者是肯定硬件有问题? 
谢谢了!


在中断线程处放置打印信息,如果不停的打印,那么就从线程着手吧。

#17


问题解决了一个,在扫描完键盘后没有将扫描的结果清空,造成中断不能继续相应。增加一行:
g_extKeyPadRegs->scan_line = 0x00;
但是按一个key,出现多个字母的问题还没有解决,请大家帮忙看看。
另外,关于键盘的防抖处理,应该是如何做的呢?
谢谢!

#18


引用 17 楼 jerry79 的回复:
问题解决了一个,在扫描完键盘后没有将扫描的结果清空,造成中断不能继续相应。增加一行: 
g_extKeyPadRegs->scan_line = 0x00; 
但是按一个key,出现多个字母的问题还没有解决,请大家帮忙看看。 
另外,关于键盘的防抖处理,应该是如何做的呢? 
谢谢!


防抖动就是要实现只处理第一次按下的那次,
就是在扑捉到第一次按下的动作之后再次判断是否有按键按下。如果有就让ARM什么都不做,如果没有就说明只按下了一次,可以继续往下运行。

这个原理和单片机的原理是一样的。

#19


引用 18 楼 gooogleman 的回复:
引用 17 楼 jerry79 的回复:
问题解决了一个,在扫描完键盘后没有将扫描的结果清空,造成中断不能继续相应。增加一行:
g_extKeyPadRegs->scan_line = 0x00;
但是按一个key,出现多个字母的问题还没有解决,请大家帮忙看看。
另外,关于键盘的防抖处理,应该是如何做的呢?
谢谢!


防抖动就是要实现只处理第一次按下的那次,
就是在扑捉到第一次按下的动作之后再次判断是否有按键按下。如果有就让ARM什么都不做,如果…

非常感谢,我现在发现在builtinkeypad_0409.cpp文件中的BuiltInKeypad_RemapVKey函数在按键中断完成后仍然一直被调用,请问做过pxa270键盘驱动的高人,BuiltInKeypad_RemapVKey这个函数实在哪里被调用的呢?我一直也没有找到。

#20


键盘驱动向系统报告的是按键的压下和抬起动作,可能是没有报告按键的抬起动作引起的。

#21


现在又前进了一步,单次按键已经没有问题了。我们是通过触发两次中断,第一次中断检测key的值,第一次中断结束后,触发第二次中断,检测到0xFF,即NO_KEY,系统收到NO_KEY则表示按键已经弹起。
但是目前的问题是,如果我长按住按键不放一段时间,在松开,系统就无法检测到按键弹起。请问检测按键长按不放的基本方法是什么呢?
请大家帮帮忙,时间紧迫啊,元旦前必须完成。谢谢

#22


请问按键长击不放的是时候,应该如何处理按键事件呢?现在我们的驱动在按键长击再松开之后,也无法检测中断。

#23


问题解决了,第二次中断的时候,我们原来设置是只检测上升沿,现在设置都检测上升和下降沿,这样长按键的时候,中断也可以持续发出了。谢谢大家的帮忙,帖子过两天再结,看还有没有其他问题。

#24


结贴!

#25


引用 23 楼 jerry79 的回复:
问题解决了,第二次中断的时候,我们原来设置是只检测上升沿,现在设置都检测上升和下降沿,这样长按键的时候,中断也可以持续发出了。谢谢大家的帮忙,帖子过两天再结,看还有没有其他问题。


这个是双边缘触发吧,和SD卡类似。

#26


引用 7 楼 hzdysymbol 的回复:
你把SPDAReadScanCode函数贴出来看看 
这里面需要处理防抖动,repeat,长按,短按等多种处理情况 
再一个你看你的代码跳出这个SPDAReadScanCode函数了吗?而且跳出来后你的上升沿中断也没有重新Enable 

早就告诉你有一个方向的中断在第二次没有重新Enable,而你自己的代码中却注释着Eable interrupt?   
     g_pGPIORegs->GRER1 &=  ~GPIO_37; //Enable interrupt
    g_pGPIORegs->GFER1 |= GPIO_37;

#27


引用 26 楼 hzdysymbol 的回复:
引用 7 楼 hzdysymbol 的回复:
你把SPDAReadScanCode函数贴出来看看
这里面需要处理防抖动,repeat,长按,短按等多种处理情况
再一个你看你的代码跳出这个SPDAReadScanCode函数了吗?而且跳出来后你的上升沿中断也没有重新Enable

早就告诉你有一个方向的中断在第二次没有重新Enable,而你自己的代码中却注释着Eable interrupt?
g_pGPIORegs->GRER1 &=  ~GPIO_37; //Enable interrupt
g_pGPIORegs->GFER1 |= GPIO_37;

唉,看帖子不仔细,花了这么多时间,非常感谢。
结贴。

#1


你的中断线程退出了吗?是否是这个线程一直占用着?

#2


InterruptDone(SYSINTR_KEYPAD);了吗?

#3


对,你的线程退出了吗?

#4


向楼上诸位表示敬意。
OALIntrStaticTranslate(SYSINTR_KEYPAD, IRQ_GPIO0_EXPBD);
这样语句我有。
不过请问中断线程的退出是什么意思?我是个新手,有些东西还不太明白。
在keypad.cpp中,中断的执行过程如下:

BOOL KeyPad::IsrThreadStart()
{
    HANDLE  hthrd;
   hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)KeyPadIsrThread,this,0,NULL);
   CloseHandle(hthrd);
    return TRUE;
}

调用了KeyPadIsrThread函数,如下:

WORD KeyPadIsrThread(KeyPad *v_pKpd)
{
    v_pKpd->IsrThreadProc();
    return 0;
}

调用了IsrThreadProc函数,如下:

BOOL KeyPad::IsrThreadProc()
{    
    m_hevInterrupt = CreateEvent(NULL,FALSE,FALSE,NULL);
    if (m_hevInterrupt == NULL) {
        RETAILMSG(1, (TEXT("IsrThreadProc: InterruptInitialize Failed\r\n")));
    }
    else 
    {
        if (InterruptInitialize(SYSINTR_KEYPAD, m_hevInterrupt, NULL, 0)) 
        {
            KEYBD_IST keyPadIst;
            keyPadIst.hevInterrupt = m_hevInterrupt;            
            keyPadIst.dwSysIntr_Keybd = SYSINTR_KEYPAD;            
            keyPadIst.uiPddId = v_uiPddId;            
            keyPadIst.pfnGetKeybdEvent = KeyPadPdd_GetEventEx2;            
            keyPadIst.pfnKeybdEvent = v_pfnKeyPadEvent;
            // Note: no point in trying to set the thread priority here, because KeybdIstLoop()
            //  forces it after we give up control: 
            KeybdIstLoop(&keyPadIst);
        }
        else
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("KeyPad::IsrThreadProc: InterruptInitialize Failure\r\n")));
        }
    }
    return(0);

请帮忙看看,中断线程的退出是如何做的呢?

#5


"我按下一个键,在LCD上的显示确是像不停的按,即比方说我按下A键一次,理论上LCD上只显示一个字母a,但是实际上a不停的出现,直到我的wordpad软件崩溃。同时串口信息上显示的是只产生了一次中断,而不是多次。"

这是因为你打开的是wordpad, 你的驱动只发送了KeyDown的event, 并没有KeyUp的event, 所以会一直打印键值.
所以, 我觉得你的按键弹起时, 中断没有产生, 会不会是在接下中断发生并处理完后你忘记了清中断? 





#6


楼主,我觉得是你没有退出线程/清中断——这个中断线程等的代码可以参考BSP下的其他例子。
很容易就发现少了什么了。

#7


你把SPDAReadScanCode函数贴出来看看
这里面需要处理防抖动,repeat,长按,短按等多种处理情况
再一个你看你的代码跳出这个SPDAReadScanCode函数了吗?而且跳出来后你的上升沿中断也没有重新Enable

#8


m_hevInterrupt
this 事件在哪挂起的?

#9


关注结果.

#10


谢谢大家的帮忙,我的SPDAReadScanCode函数如下,目前还没有做很多判断键值的动作,只做了扫描键盘的动作。请问应该在哪里增加防抖处理呢?谢谢。

XLLP_BOOL_T SPDAReadScanCode( SPDA_KBD_REGS *v_pKeyPadRegs , XLLP_UINT8_T *pui8Data)
    
{
// total 8*16 key scan_line= bit0-bit3(C) , input_line=bit4-bit7(R)
BYTE   tmp_scanLine=0x01;
int i;
XLLP_BOOL_T retval=XLLP_FALSE;
XLLP_UINT32_T C,R,RthBit,c0,c1,c2,c3,c4,c5,c6,c7;
  int numOfKeysPressed=0;
  XLLP_UINT32_T col[8];
  XLLP_UINT32_T temp_indata; 
 
RETAILMSG(1,(TEXT("ReadScanCodeAutomatically-----SPDA\r\n")));
v_pKeyPadRegs->scan_line = 0xFF;
// Scan keyboard 
for(i=0;i<8;i++)
{
col[i]=0;
v_pKeyPadRegs->scan_line = ~tmp_scanLine; 
       temp_indata = v_pKeyPadRegs->data_in;
temp_indata &= 0x00FFFF;
if(temp_indata != 0xFFFF)
{
 if(temp_indata != 0xFFFF)
 {
    col[i] = temp_indata;
    numOfKeysPressed +=1;     
 }
}
tmp_scanLine<<=1;
 }
if(numOfKeysPressed == 1)
{
for(i=0;i<8;i++)
   {
    if(col[i]!=0)
      {
    C = (XLLP_UINT32_T) i;
    R =  TransVal(&col[i]);  
    R <<=4;     
   }
    }
         *pui8Data = (unsigned char) (C | R);
 }
    else 
           {
    if(numOfKeysPressed > 1)
    {
    c0 = TransVal(&col[0]);
c1 = TransVal(&col[1]);
c2 = TransVal(&col[2]);
    c3 = TransVal(&col[3]);    
c4 = TransVal(&col[4]);
c5 = TransVal(&col[5]);
   c6 = TransVal(&col[6]);
   c7 = TransVal(&col[7]);  
}
else
*pui8Data = NO_KEY;
}
retval = XLLP_TRUE;
   return(retval);
}
int TransVal( XLLP_UINT32_T *val)
{
int i;

for (i=0;i<16;i++)
  {
   if(!(*val & 0x0001)) return i;
   *val >>=1;   
  }
  return i;
}

#11


引用 7 楼 hzdysymbol 的回复:
你把SPDAReadScanCode函数贴出来看看
这里面需要处理防抖动,repeat,长按,短按等多种处理情况
再一个你看你的代码跳出这个SPDAReadScanCode函数了吗?而且跳出来后你的上升沿中断也没有重新Enable

我的代码已经跳出SPDAReadScanCode函数了,跳出后我enable了中断,如下:
 g_pGPIORegs->GRER1 &=  ~GPIO_37; //Enable interrupt
 g_pGPIORegs->GFER1 |= GPIO_37;
请问这两句是否有问题呢?

#12


引用 5 楼 eagle1597 的回复:
"我按下一个键,在LCD上的显示确是像不停的按,即比方说我按下A键一次,理论上LCD上只显示一个字母a,但是实际上a不停的出现,直到我的wordpad软件崩溃。同时串口信息上显示的是只产生了一次中断,而不是多次。"

这是因为你打开的是wordpad, 你的驱动只发送了KeyDown的event, 并没有KeyUp的event, 所以会一直打印键值.
所以, 我觉得你的按键弹起时, 中断没有产生, 会不会是在接下中断发生并处理完后你忘记了清中断?

谢谢,我也再想这个问题,不过我使用的是下降沿产生中断,除非一直按住键,否则波形就是low一下立刻就被拉高了,这样的话,我如何相应按键弹起的中断呢?

#13


如果线程没有退出,你的打印的东西就不停的执行。
结果很像你的现象。

#14


谢谢楼上,我是参考MainstroneII的代码修改的keyboard驱动,除了中断和扫描函数外,线程部分都是使用原始的代码。我查看了一下,没有找到线程应该在哪里退出。

#15


关于只能产生一次中断的问题,在串口上我只能看到一次中断信息,同时我测量中断的pin脚,也量不到下降沿产生,请问硬件上量不到中断是否是软件的问题呢?键盘的中断应该是由硬件发出,而软件响应的吧,如果硬件上量不到中断,是否有可能是硬件有问题,或者是肯定硬件有问题?
谢谢了!

#16


引用 15 楼 jerry79 的回复:
关于只能产生一次中断的问题,在串口上我只能看到一次中断信息,同时我测量中断的pin脚,也量不到下降沿产生,请问硬件上量不到中断是否是软件的问题呢?键盘的中断应该是由硬件发出,而软件响应的吧,如果硬件上量不到中断,是否有可能是硬件有问题,或者是肯定硬件有问题? 
谢谢了!


在中断线程处放置打印信息,如果不停的打印,那么就从线程着手吧。

#17


问题解决了一个,在扫描完键盘后没有将扫描的结果清空,造成中断不能继续相应。增加一行:
g_extKeyPadRegs->scan_line = 0x00;
但是按一个key,出现多个字母的问题还没有解决,请大家帮忙看看。
另外,关于键盘的防抖处理,应该是如何做的呢?
谢谢!

#18


引用 17 楼 jerry79 的回复:
问题解决了一个,在扫描完键盘后没有将扫描的结果清空,造成中断不能继续相应。增加一行: 
g_extKeyPadRegs->scan_line = 0x00; 
但是按一个key,出现多个字母的问题还没有解决,请大家帮忙看看。 
另外,关于键盘的防抖处理,应该是如何做的呢? 
谢谢!


防抖动就是要实现只处理第一次按下的那次,
就是在扑捉到第一次按下的动作之后再次判断是否有按键按下。如果有就让ARM什么都不做,如果没有就说明只按下了一次,可以继续往下运行。

这个原理和单片机的原理是一样的。

#19


引用 18 楼 gooogleman 的回复:
引用 17 楼 jerry79 的回复:
问题解决了一个,在扫描完键盘后没有将扫描的结果清空,造成中断不能继续相应。增加一行:
g_extKeyPadRegs->scan_line = 0x00;
但是按一个key,出现多个字母的问题还没有解决,请大家帮忙看看。
另外,关于键盘的防抖处理,应该是如何做的呢?
谢谢!


防抖动就是要实现只处理第一次按下的那次,
就是在扑捉到第一次按下的动作之后再次判断是否有按键按下。如果有就让ARM什么都不做,如果…

非常感谢,我现在发现在builtinkeypad_0409.cpp文件中的BuiltInKeypad_RemapVKey函数在按键中断完成后仍然一直被调用,请问做过pxa270键盘驱动的高人,BuiltInKeypad_RemapVKey这个函数实在哪里被调用的呢?我一直也没有找到。

#20


键盘驱动向系统报告的是按键的压下和抬起动作,可能是没有报告按键的抬起动作引起的。

#21


现在又前进了一步,单次按键已经没有问题了。我们是通过触发两次中断,第一次中断检测key的值,第一次中断结束后,触发第二次中断,检测到0xFF,即NO_KEY,系统收到NO_KEY则表示按键已经弹起。
但是目前的问题是,如果我长按住按键不放一段时间,在松开,系统就无法检测到按键弹起。请问检测按键长按不放的基本方法是什么呢?
请大家帮帮忙,时间紧迫啊,元旦前必须完成。谢谢

#22


请问按键长击不放的是时候,应该如何处理按键事件呢?现在我们的驱动在按键长击再松开之后,也无法检测中断。

#23


问题解决了,第二次中断的时候,我们原来设置是只检测上升沿,现在设置都检测上升和下降沿,这样长按键的时候,中断也可以持续发出了。谢谢大家的帮忙,帖子过两天再结,看还有没有其他问题。

#24


结贴!

#25


引用 23 楼 jerry79 的回复:
问题解决了,第二次中断的时候,我们原来设置是只检测上升沿,现在设置都检测上升和下降沿,这样长按键的时候,中断也可以持续发出了。谢谢大家的帮忙,帖子过两天再结,看还有没有其他问题。


这个是双边缘触发吧,和SD卡类似。

#26


引用 7 楼 hzdysymbol 的回复:
你把SPDAReadScanCode函数贴出来看看 
这里面需要处理防抖动,repeat,长按,短按等多种处理情况 
再一个你看你的代码跳出这个SPDAReadScanCode函数了吗?而且跳出来后你的上升沿中断也没有重新Enable 

早就告诉你有一个方向的中断在第二次没有重新Enable,而你自己的代码中却注释着Eable interrupt?   
     g_pGPIORegs->GRER1 &=  ~GPIO_37; //Enable interrupt
    g_pGPIORegs->GFER1 |= GPIO_37;

#27


引用 26 楼 hzdysymbol 的回复:
引用 7 楼 hzdysymbol 的回复:
你把SPDAReadScanCode函数贴出来看看
这里面需要处理防抖动,repeat,长按,短按等多种处理情况
再一个你看你的代码跳出这个SPDAReadScanCode函数了吗?而且跳出来后你的上升沿中断也没有重新Enable

早就告诉你有一个方向的中断在第二次没有重新Enable,而你自己的代码中却注释着Eable interrupt?
g_pGPIORegs->GRER1 &=  ~GPIO_37; //Enable interrupt
g_pGPIORegs->GFER1 |= GPIO_37;

唉,看帖子不仔细,花了这么多时间,非常感谢。
结贴。