今天早上将昨天修改的触摸屏程序(http://www.openedv.com/posts/list/58361.htm)进一步做了修改。加入了按住状态下,每次的上一次坐标,方便使用。
对三态的处理,是:
按下,在按下位置画黄圈;
按住,画与上一个点的连线,并画白圈;
抬起,在最后一次点按住点位置画红圈。
先附上代码,随后说说遇到的问题:
[mw_shl_code=c,true]void TOUCH_Scan(u8 aType)
{
if(PEN == 0) // 如果按住触屏
{
u16 lX, lY;
bool lOk = _TOUCH_ReadXY2(&lX, &lY); // 读取物理坐标
if(aType == TOUCH_COORD_SCREEN && lOk == TRUE) // 如果希望读取的是屏幕坐标,则进行转换
{
// 将结果转换为屏幕坐标
lX = lX * gEnvironment.TouchFactorX + gEnvironment.TouchOffsetX;
lY = lY * gEnvironment.TouchFactorY + gEnvironment.TouchOffsetY;
}
// 如果上次扫描既不是按下,也不是按住,则本次为第一次按下
if((gTouchDevice.State & (TOUCH_STATE_DOWN | TOUCH_STATE_HOLD)) == 0)
{
// 清除可能的抬起状态(刚抬起瞬间,再按下),并标记为按下
gTouchDevice.State &= ~TOUCH_STATE_UP;
gTouchDevice.State |= TOUCH_STATE_DOWN;
// 同时在首次按下时,记录按下的坐标到 FirstX 和 FirstY。
gTouchDevice.FirstX = lX;
gTouchDevice.FirstY = lY;
// 按下后可能直接跳过按住发生抬起。抬起时要访问 LastX 和 LastY 就是本次扫描到的点,因此需要记录。
gTouchDevice.LastX = lX;
gTouchDevice.LastY = lY;
}
else // 上次扫描可能是按下,也可能是按住,本次均应为按住状态。为简单起见(不必做过多的逻辑判断),按下状态始终清除。
{
// 取消按下状态,标记为按住
gTouchDevice.State &= ~TOUCH_STATE_DOWN;
gTouchDevice.State |= TOUCH_STATE_HOLD;
// 按住的情况下,LastX 和 LastY 均应是上一次的当前坐标
gTouchDevice.LastX = gTouchDevice.CurrentX;
gTouchDevice.LastY = gTouchDevice.CurrentY;
}
// 最终将本次扫描的坐标放入 CurrentX 和 CurrentY 中。
gTouchDevice.CurrentX = lX;
gTouchDevice.CurrentY = lY;
// 结论:当本次是按下时:First, Last, Current 是一致的;
// 当本次是按住时:First 为按下时的点,Last 为上一次的点(第一次按住时,First 和 Last 相同),Current 为本次的点。
}
else // 如果没有按住触屏
{
// 如果上次扫描扫描是按下或按住状态
if((gTouchDevice.State & (TOUCH_STATE_DOWN | TOUCH_STATE_HOLD)) != 0)
{
// 清除按下或按住标记,并标记为抬起
gTouchDevice.State &= ~(TOUCH_STATE_DOWN | TOUCH_STATE_HOLD);
gTouchDevice.State |= TOUCH_STATE_UP;
// 抬起时的 Last 是上一次的 Current
gTouchDevice.LastX = gTouchDevice.CurrentX;
gTouchDevice.LastY = gTouchDevice.CurrentY;
// 抬起时,当前点坐标是无效的,因为扫描不到。所以,抬起时,应使用 LastX 和 LastY。
gTouchDevice.CurrentX = 0xFFFF;
gTouchDevice.CurrentY = 0xFFFF;
}
else if((gTouchDevice.State & TOUCH_STATE_UP) != 0) // 如果上次是抬起状态
{
// 本次已为空闲状态,清空所有已扫描信息
gTouchDevice.State &= ~TOUCH_STATE_UP;
// 已经过了抬起状态,所有坐标点失效。
gTouchDevice.FirstX = 0xFFFF;
gTouchDevice.FirstY = 0xFFFF;
gTouchDevice.LastX = 0xFFFF;
gTouchDevice.LastY = 0xFFFF;
}
// 结论:当本次是抬起时:First 和 Last 可用;
// 当本次是空闲时:全部坐标不可用。
}
}
// TIM3 每 50ms 检测一次。
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{
TOUCH_Scan(TOUCH_COORD_SCREEN);
if((gTouchDevice.State & TOUCH_STATE_DOWN) != 0) // 第一次按下
{
oDebug("按下  %3d, %3d)\r\n", gTouchDevice.FirstX, gTouchDevice.FirstY);
LCD_DrawCircle(gTouchDevice.FirstX, gTouchDevice.FirstY, 3, COLOR_YELLOW);
}
else if((gTouchDevice.State & TOUCH_STATE_HOLD) != 0) // 按住
{
oDebug("按住  %3d, %3d)\r\n", gTouchDevice.CurrentX, gTouchDevice.CurrentY);
LCD_DrawLine(gTouchDevice.LastX, gTouchDevice.LastY, gTouchDevice.CurrentX, gTouchDevice.CurrentY, COLOR_WHITE);
LCD_DrawCircle(gTouchDevice.CurrentX, gTouchDevice.CurrentY, 3, COLOR_WHITE);
}
else if((gTouchDevice.State & TOUCH_STATE_UP) != 0)
{
oDebug("抬起  %3d, %3d)\r\n", gTouchDevice.LastX, gTouchDevice.LastY);
LCD_DrawCircle(gTouchDevice.LastX, gTouchDevice.LastY, 3, COLOR_RED);
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
}[/mw_shl_code]
出现的问题是,当从左往右画线时,还算可以,但是从右往左画线时,总是画不出来。
而且,斜线的每段的结束位置有偏差。(画线用的原子的代码,做了名称的改变,算法没变)
具体如下图:
请原子兄和高手们帮忙看看,问题出在哪里?
|