首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > WinCE >

请问ZLG7290双边沿触发的奇怪有关问题

2012-02-11 
请教ZLG7290双边沿触发的奇怪问题平台2440 5.0 BSP我使用ZLG7290这个键盘驱动芯片,如果有键按下就会在它的

请教ZLG7290双边沿触发的奇怪问题
平台2440 5.0 BSP
我使用ZLG7290这个键盘驱动芯片,如果有键按下就会在它的INT引脚发出一个低电平,如果没有按键按下就是高电平。
现在我采用双边沿触发中断,但是出现只要按下一个键,这个键的功能就会不段重复执行,看打印信息中断线程却执行了一次而已。
后来在老帖看到,这个是由于没有处理按键弹起就会这样。可是我明明配置了双边沿触发,并且我用应用程序读出相应的寄存器,和
数据手册吻合。
后来我把键盘的IST部分移植到BSP下加入了打印信息。
BOOL
KeybdIstLoop(
  PKEYBD_IST pKeybdIst
  )
{
  SETFNAME(_T("KeybdIstLoop"));

  UINT32 rguiScanCode[16];
  BOOL rgfKeyUp[16];
  UINT cEvents;
 // add by wogo at 2009-03-12
 RETAILMSG(1, (TEXT("In KeybdIstLoop Funtion:\r\n")));
  DEBUGCHK(pKeybdIst->hevInterrupt != NULL);
  DEBUGCHK(pKeybdIst->pfnGetKeybdEvent != NULL);
  DEBUGCHK(pKeybdIst->pfnKeybdEvent != NULL);

  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

wait_for_keybd_interrupt:
  if (WaitForSingleObject(pKeybdIst->hevInterrupt, INFINITE) == WAIT_OBJECT_0)
  {
  // add by wogo at 2009-03-12
  RETAILMSG(1, (TEXT("Deal with hevInterrupt@@@!!! :\r\n")));
  cEvents = (*pKeybdIst->pfnGetKeybdEvent)
  (pKeybdIst->uiPddId, rguiScanCode, rgfKeyUp);
   
  for (UINT iEvent = 0; iEvent < cEvents; ++iEvent) {
  (*pKeybdIst->pfnKeybdEvent)(pKeybdIst->uiPddId, 
  rguiScanCode[iEvent], rgfKeyUp[iEvent]);
  }
  // cEvents could be 0 if this was a partial scan code, like 0xE0

  InterruptDone(pKeybdIst->dwSysIntr_Keybd);
  // add by wogo at 2009-03-12
  RETAILMSG(1, (TEXT("InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :\r\n")));
  }

  goto wait_for_keybd_interrupt;

  ERRORMSG(1, (TEXT("KeybdIstLoop: Keyboard driver thread terminating.\r\n")));
 RETAILMSG(1, (TEXT("KeybdIstLoop: Keyboard driver thread terminating!!! :\r\n")));
  return TRUE;
}

 

  果然按下一次按键只打印了如下信息

Deal with hevInterrupt@@@!!! :
InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :
  按照常理,使用双边触发,按一次应该打印如下。

Deal with hevInterrupt@@@!!! :
InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :
Deal with hevInterrupt@@@!!! :
InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :

  现在难搞了,使用应用程序去读中断寄存器的设置,读出是0x22226242,这个和要求完全吻合,怎么就不产生双边沿触发呢?难道是干扰?我的天啊,真是越来越神奇了。
  后来,我又单独把EINT11配置成上升沿触发,结果也打印了
Deal with hevInterrupt@@@!!! :
InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :
这说明这时候才响应了键盘弹起中断。但是不知道为什么配置成双边触发的时候,响应了键按下之后,键弹起中断就不响应了。

shuiyan牛人,你经验丰富,救救小弟吧。谢谢。




[解决办法]
三星的东东没有用过。
我在270上,是在kernle里面将GPIO先设成input,然后将上下边沿检测的寄存器都设置成1,即只要引脚上有跳变,不管是上升还是下降,GPIO都可以检测到。
g_pGPIORegs->GFER1 |= GPIO_37;
g_pGPIORegs->GRER1 |= GPIO_37;

收到中断后,先disable中断,然后扫描键盘,然后再enable…………

不知道这样能不能帮到你呢?
[解决办法]
这个芯片如何处理多键呢?“有键按下是低,没键按下是高”,那按下一个不放->中断低->再按另一个呢?


先这样做:
使能下降沿,等待按键按下 -> 按下触发下降沿中断,进入处理流程,在其中将这个脚设置成上升沿触发 -> 结束处理,等待按键释放。

人的机械操作肯定远远超过程序处理时间,所以不用担心会错过上升沿。

然后再看2440的双沿触发为什么没起效果。以前没用过双沿的方式。

270跟2440不一样:270的上升、下降沿是分别在两个寄存器里设置,而2440却是在同一个寄存器的2个bit来配置。不确定这是否是引起不同结果的原因。

[解决办法]

探讨
我不明白我双边沿触发只能产生一个中断,
但是我分开来两个中断都能产生,不知道是怎么回事。

------解决方案--------------------


isr
[解决办法]
应该是线程处理时间太长。
在最初的设计中,我在扫描函数中等待的时间是大概20多毫秒,结果经常发生按下一个键,屏幕上就出现一堆字母的情况,这个就是没有检测到up中断。
于是就减少时间,………………,直到减小到1uS,才算不会出现此问题。
我有时候再想,这1uS到底有没有用,不过也没有把它拿掉。
[解决办法]
那就把这个GetEvent里面用二分法来找最耗时的那个语句(估计是ZLG7290_GetKey(key);),找到后再决定怎么处理。

MAX7349只支持按下触发下降沿中断,释放不触发。MAX7359支持按下、释放都触发下降沿中断。

所以,这个功能是由扫描芯片决定的。
[解决办法]
随便说一下。你的系统是不是很忙?把IST的线程优先级调高点看看:
SetThreadPriority(GetCurrentThread(), 100);


[解决办法]
IIC时钟是多少?你看看WaitForSingleObject到InterruptDone花了多长时间?
[解决办法]
还有,可以用示波器量波形。看中断产生到IIC上有数据延迟是多少,IIC读数据花多长时间,IIC波形好不好,等等。
[解决办法]
你那样的解决办法可能会有副作用的。有问题应该找出根源,work-around实在没办法的时候才用。

热点排行