最近在wince 6.调试了多个电容屏驱动,参考了很多前辈的代码,发现基本上有两种做法。一种是直接写另一个流动驱动,在中断线程中读取坐标和状态,然后使用mouse_move等wince api点击模拟鼠标,实现触摸功能。另一种是使用s3c 6410自带的触摸屏驱动,在其中实现读取坐标的方法。我第一次使用第一种方法,因为网上有很多代码,可以直接使用,但有一个问题是鼠标移动有点慢(在wince桌面画框可见),简单点击没问题。后面经过测试,发现去掉mouse_move可在1秒钟内接收处理约30个中断.但是加上mouse_move之后,变得只有几个。后来,尝试不直接调用中断线程,而是使用消息队列,即接收中断并读取坐标数据,发送到消息队列,然后处理其他线程。但是没有太大的改进,可能是消息队列不是很有效(对于中断)。如果直接自己写一个队列,保存到这个队列(都是纯内存操作),然后通过事件通知其他线程,可以解决。但由于时间问题,我没有尝试这个计划。想到之前的电阻屏是6410带来的,效果也不错,就用第二种方式来做。事实上,用第二种方法来做,变化添加第一种方法的初始代码s3c6410_touch里面一般是初始化IIC,也可能需要初始化GPIO。然后重点是DdsiTouchPanelGetPoint当触摸中断时,该方法,wince会自动调用。在这种方法中,只需要读取触摸屏的坐标和状态OK了。读取的具体代码和触摸屏ic相关基本上是通过的IIC读取一个地址的数据,将在芯片手册中写入,最多支持几个触摸点,并根据您需要支持的触摸点读取。设置读取坐标pUncalX, pUncalY,要注意pTipState ,由于电容屏读取的坐标已经校准,需要设置pTipState |= TouchSampleIsCalibratedFlag;这个标志,否则wince侧坐标会重新校准,导致触摸不准确。
有趣的是,6410的驱动器采用定时器查询触摸屏的状态。例如,按下触摸屏后,启动定时器,开始轮询,检测手指抬起后停止定时器。事实上,许多电容屏都不推荐轮询,因为按下和抬起都是中断的,move还有,不需要用定时器检查。不仅代码逻辑相当复杂,而且效率也很低。下面是我改过之后的方法的代码
VOID DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS *pTipState, INT *pUncalX, INT *pUncalY) { static int PrevX=0; static int PrevY=0; DWORD InterruptType = SYSINTR_NOP; PrevX = *pUncalX; PrevY = *pUncalY; if(PDDSampleTouchScreen(pTipState,pUncalX,pUncalY)) { *pUncalX = *pUncalX*X_SCALE_FACTOR; *pUncalY = *pUncalY*Y_SCALE_FACTOR; } else { *pTipState = TouchSampleIgnore; *pUncalX = PrevX; *pUncalY = PrevY; } RETAILMSG(TOUCH_DEBUG_MSG,(_T("[TSP] Point(%d,%d,%d) \r\n"),*pUncalX,*pUncalY,*pTipState)); InterruptType = gIntrTouch; L1: InterruptDone(InterruptType); // Not handled in MDD }
PDDSampleTouchScreen这是一种与芯片相关的读取坐标和状态的方法,代码不会粘贴。我希望它能给你一点参考,如果有问题,请纠正它。