触摸屏的校准与坐标变换

 最近做了一点触摸屏的驱动工作,总结了一下,触摸屏的校准的核心其实就是坐标的变换问题。

下面将触屏校准的思路简单记录一下:

第一步,记录LCD的4个角上的Touch坐标值(不是LCD坐标值,而是Touch传出来的坐标值)

(x1,y1) ----- (x2,y2) | | | | | | (x4,y4) ----- (x3,y3)

第二步,根据这4个点判断触屏的坐标原点的位置,思路如下:

1. 校准坐标值,即如果x1,x2,x3,x4中任意二者之间误差在某个值(如:20)以内,则将这二者置为一致;y坐标做一样的处理。

2. 得到最小的x,y值,找到(x,y)与4个角的哪一个重叠,如此就找到了原点。

找原点的示例代码如下:

/* Check touch screen coordinate origin point location */ /* It should be in (4 corner) : */ /* 1 -- 2 */ /* 4 -- 3 */ int check_origin_point(void) { /* Get the minimal X,Y */ u16 minX = astLeftTop.x; u16 minY = astLeftTop.y; minX = min(astRightTop.x, minX); minX = min(astRightBottom.x, minX); minX = min(astLeftBottom.x, minX); minY = min(astRightTop.y, minY); minY = min(astRightBottom.y, minY); minY = min(astLeftBottom.y, minY); /* Adjust the 4 standard points X values */ if ((astRightTop.x >= (minX - TOUCH_DIFF_MAX)) && (astRightTop.x <= (minX + TOUCH_DIFF_MAX))) astRightTop.x = minX; if ((astRightBottom.x >= (minX - TOUCH_DIFF_MAX)) && (astRightBottom.x <= (minX + TOUCH_DIFF_MAX))) astRightBottom.x = minX; if ((astLeftTop.x >= (minX - TOUCH_DIFF_MAX)) && (astLeftTop.x <= (minX + TOUCH_DIFF_MAX))) astLeftTop.x = minX; if ((astLeftBottom.x >= (minX - TOUCH_DIFF_MAX)) && (astLeftBottom.x <= (minX + TOUCH_DIFF_MAX))) astLeftBottom.x = minX; /* Adjust the 4 standard points Y values */ if ((astRightTop.y >= (minY - TOUCH_DIFF_MAX)) && (astRightTop.y <= (minY + TOUCH_DIFF_MAX))) astRightTop.y = minY; if ((astRightBottom.y >= (minY - TOUCH_DIFF_MAX)) && (astRightBottom.y <= (minY + TOUCH_DIFF_MAX))) astRightBottom.y = minY; if ((astLeftTop.y >= (minY - TOUCH_DIFF_MAX)) && (astLeftTop.y <= (minY + TOUCH_DIFF_MAX))) astLeftTop.y = minY; if ((astLeftBottom.y >= (minY - TOUCH_DIFF_MAX)) && (astLeftBottom.y <= (minY + TOUCH_DIFF_MAX))) astLeftBottom.y = minY; /* check which one is origin point */ if (astLeftTop.x == minX && astLeftTop.y == minY) return 1; if (astRightTop.x == minX && astRightTop.y == minY) return 2; if (astRightBottom.x == minX && astRightBottom.y == minY) return 3; if (astLeftBottom.x == minX && astLeftBottom.y == minY) return 4; return -1; }

 

第三步,判断触摸屏的坐标类型:

可能的坐标类型有8种,列举如下:

CS-0: 0 —X1 | Y1 CS-1: 0 —Y1 | X1 CS-2: X1 —0 | Y1 CS-3: Y1 —0 | X1 CS-4: Y1 | X1 —0 CS-5: X1 | Y1 —0 CS-6: Y1 | 0 —X1 CS-7: X1 | 0 —Y1

根据原点位置和4个点的坐标可以判断当前touch screen的坐标类型(其实就是知道触屏是怎么放的):

如果(x1,y1)为坐标原点 if (x1 == x2) && (y1 < y2) CS-0 else CS-1 如果(x2,y2)为坐标原点 if (x1 > x2) && (y1 == y2) CS-2 else CS-3 如果(x3,y3)为坐标原点 if (x4 > x3) && (y4 == y3) CS-4 else CS-5 如果(x4,y4)为坐标原点 if (x3 > x4) && (y4 == y3) CS-6 else CS-7

得到了当前触屏的坐标类型,LCD的坐标类型又是已知的(如:CS-0)就能知道3个信息:

1)X,Y坐标是否需要对调(坐标旋转)

2)X坐标是否需要折叠

3)Y坐标是否需要折叠

记住:坐标变换遵循先旋转,后折叠的计算方法

 

第四步,坐标值计算:

把其他坐标转换成CS-0类型的标准坐标的计算方法:

  (x', y'): 参考坐标系中的坐标 (x, y): 实际坐标系中的坐标 CS-0: x' = x, y' = y CS-1: x' = y, y' = x CS-2: x' = xmax - x, y' = y CS-3: x' = ymax - y, y' = x CS-4: x' = xmax - x, y' = ymax - y CS-5: x' = ymax - y, y' = xmax - x CS-6: x' = x, y' = ymax - y CS-7: x' = y, y' = xmax - x

 xmax,ymax就是折叠轴。

 

第五步,坐标伸缩:

因为LCD尺寸像素与TouchScreen的采样值是不一样的,所以需要坐标伸缩:

  x伸缩系数 = (x坐标距离/x像素值) y伸缩系数 = (y坐标距离/y像素值) x"=x' * x伸缩系数 y"=y' * y伸缩系数

好了,方法大概就是这样了,当然,最后还需要一个中心点来判断校准结果是否正确。。。。

你可能感兴趣的:(Linux,ARM嵌入式)