搜索
bottom↓
回复: 253

最完美的触摸屏校正算法tslib——STM32实现(源码+图)

  [复制链接]

出0入0汤圆

发表于 2013-3-15 01:21:59 | 显示全部楼层 |阅读模式
1、实现SPI驱动TSC2046,读取X,Y触摸坐标
2、触摸坐标和LCD坐标的对应关系可由矩阵平移、旋转、缩放三者来表示
XL=XT*A+XT*B+C
YL=YT*D+YT*E+F
采用五点校正算法,计算出参数A,B,C,D,E,F
因为参数多为小数不易存放,所以乘以一个参数作为整数存放。
3、每次读取触摸按下的坐标时,读TSC2046的是触摸坐标,
而需要的是LCD坐标,所以把触摸坐标和上述参数代入上面等式即可获得

程序源码




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-3-18 01:39:24 | 显示全部楼层
XL=XT*A+XT*B+C
YL=YT*D+YT*E+F
这两个三元一次方程的求解用到克拉姆法则
这是线性代数的内容,看不懂的先看下线性代数里行列式和矩阵的运算

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-3-15 01:28:22 | 显示全部楼层
参考资料


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-3-15 03:24:19 | 显示全部楼层
幫頂一下~

出0入0汤圆

发表于 2013-3-15 08:06:12 | 显示全部楼层
才改了野火了,今天试试这个。

出0入0汤圆

发表于 2013-3-15 08:26:24 | 显示全部楼层
不错。。顶一下

出0入0汤圆

发表于 2013-3-15 09:09:04 | 显示全部楼层
学习触屏校准

出0入0汤圆

发表于 2013-3-15 09:11:24 | 显示全部楼层
收le ~~~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-3-15 09:29:16 | 显示全部楼层
学习,谢谢!!!

出0入0汤圆

发表于 2013-3-15 09:52:42 | 显示全部楼层
不错下来学习下

出0入90汤圆

发表于 2013-3-15 10:55:52 | 显示全部楼层
标题起的很牛,但是能否介绍下,到底是怎么样做到更完美呢?

出0入0汤圆

发表于 2013-3-15 11:09:04 | 显示全部楼层
过来是顶一下支持一下的

出0入0汤圆

 楼主| 发表于 2013-3-15 22:10:32 | 显示全部楼层
honami520 发表于 2013-3-15 10:55
标题起的很牛,但是能否介绍下,到底是怎么样做到更完美呢?

tslib是嵌入式系统里用得最多的触摸屏校正算法.充分利用了矩阵的平移,旋转和缩放等运算.
原理和代码结合得很好,具体就不多说了

出0入0汤圆

发表于 2013-3-15 23:36:22 | 显示全部楼层
这个要得,不错。

出0入0汤圆

发表于 2013-3-15 23:56:46 | 显示全部楼层
这个标记下
头像被屏蔽

出0入0汤圆

发表于 2013-3-16 00:01:53 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-3-16 02:18:15 | 显示全部楼层
这个我也在用着,感觉很不错~

出0入0汤圆

发表于 2013-3-16 07:32:17 | 显示全部楼层
标记,顶一下。

出0入0汤圆

发表于 2013-3-16 07:40:45 | 显示全部楼层
牛牛牛

出0入0汤圆

发表于 2013-3-16 07:59:34 | 显示全部楼层
用的着,谢谢。

出0入0汤圆

发表于 2013-3-16 08:09:57 | 显示全部楼层
新公司准备搞STM32了,这个说不定有用哦。MARK一下

出0入0汤圆

发表于 2013-3-16 08:44:40 | 显示全部楼层
谢谢楼主

出0入0汤圆

发表于 2013-3-16 10:06:25 | 显示全部楼层
先mark 了

出0入0汤圆

发表于 2013-3-16 10:25:11 | 显示全部楼层
MARK

出0入0汤圆

发表于 2013-3-16 11:01:33 | 显示全部楼层
好 东西啊啊  哈哈

出0入0汤圆

发表于 2013-3-16 11:30:48 | 显示全部楼层
好东西 mark一下

出0入0汤圆

发表于 2013-3-16 11:36:30 | 显示全部楼层
给力,顶起来。。。。。。。。。

出0入90汤圆

发表于 2013-3-16 12:50:37 | 显示全部楼层
谢谢百为的解答,看来这个应该比我自己写的要好很多了,下载下来看看先

出0入0汤圆

发表于 2013-3-16 12:58:27 来自手机 | 显示全部楼层
有用,谢谢

出0入0汤圆

发表于 2013-3-16 17:35:32 | 显示全部楼层
mark,顶一下

出0入4汤圆

发表于 2013-3-16 17:41:53 | 显示全部楼层
楼主将tslib研究得很透彻。向你学习!

出0入0汤圆

发表于 2013-3-16 21:43:52 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2013-3-16 21:45:35 | 显示全部楼层
xiexie


出0入0汤圆

发表于 2013-3-16 22:43:14 来自手机 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2013-3-17 00:08:06 | 显示全部楼层
收藏备用.

出0入0汤圆

发表于 2013-3-17 00:19:48 | 显示全部楼层
mark 学习

出0入0汤圆

发表于 2013-3-18 08:38:52 | 显示全部楼层
好东西,从理论到实践,全了

出0入0汤圆

发表于 2013-3-18 08:58:04 | 显示全部楼层
不错,学习之。。。

出0入0汤圆

发表于 2013-3-18 12:32:46 | 显示全部楼层
程序太多      在哪个文件夹啊

出0入0汤圆

发表于 2013-3-18 13:19:24 | 显示全部楼层

出0入0汤圆

发表于 2013-3-18 14:02:00 | 显示全部楼层
mkmk先!!!!!

出0入0汤圆

 楼主| 发表于 2013-3-18 14:20:54 | 显示全部楼层
eryueniao 发表于 2013-3-18 12:32
程序太多      在哪个文件夹啊

用3.5固件库模板建的工程,在目录touch\Project\STM32F10x_StdPeriph_Template\MDK-ARM下面

出0入0汤圆

发表于 2013-3-18 14:27:45 | 显示全部楼层
好东东, 一定要顶和MARK

出0入0汤圆

发表于 2013-3-18 17:36:59 | 显示全部楼层
马克思

出0入0汤圆

发表于 2013-3-18 19:38:35 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2013-3-18 20:43:12 | 显示全部楼层
这个可以mark,谢谢

出0入0汤圆

发表于 2013-3-18 20:47:43 | 显示全部楼层

出0入0汤圆

发表于 2013-3-19 09:56:23 | 显示全部楼层
顶一下,先看看再说,感谢分享。下了备用,MARK了

出0入18汤圆

发表于 2013-3-19 11:59:20 | 显示全部楼层
五点校正 不粗的说

出0入0汤圆

发表于 2013-3-19 16:20:08 | 显示全部楼层
以前我也是做触摸屏的.先下了再说..感谢楼主

出0入0汤圆

发表于 2013-3-19 18:41:20 | 显示全部楼层
學習了!

出0入0汤圆

 楼主| 发表于 2013-3-26 01:01:39 | 显示全部楼层
9320貌似只能改变扫描方向,并不能真正改变硬件坐标原点,只能用软件去调整。

出0入0汤圆

发表于 2013-3-26 10:38:57 | 显示全部楼层
不错啊~~~~~

出0入0汤圆

发表于 2013-3-26 10:59:48 | 显示全部楼层
我去试试 ,谢谢LZ

出0入0汤圆

发表于 2013-3-26 11:20:18 | 显示全部楼层
触摸屏校准,谢谢

出0入0汤圆

发表于 2013-3-26 14:28:06 | 显示全部楼层
非常感谢楼主分享。

出0入0汤圆

发表于 2013-3-27 00:00:12 来自手机 | 显示全部楼层
顶一个,学习中!!!

出0入0汤圆

发表于 2013-3-28 11:19:40 | 显示全部楼层
谢谢楼主分享!

出0入0汤圆

发表于 2013-3-28 12:10:23 | 显示全部楼层
这个很不错啊。。

出0入0汤圆

发表于 2013-3-28 21:44:31 | 显示全部楼层
参考一下,应该很有用

出0入0汤圆

发表于 2013-3-29 08:01:30 来自手机 | 显示全部楼层
马克一下

出0入0汤圆

发表于 2013-3-29 19:15:47 | 显示全部楼层
收藏下,谢谢分享

出0入0汤圆

发表于 2013-3-29 19:39:02 来自手机 | 显示全部楼层
最完美,看看。

出0入0汤圆

发表于 2013-3-29 21:42:24 | 显示全部楼层
好资源,谢谢楼主

出0入0汤圆

发表于 2013-3-30 11:37:52 | 显示全部楼层
market                           

出0入0汤圆

发表于 2013-3-30 14:52:10 | 显示全部楼层
路过,顶楼主!

出0入0汤圆

发表于 2013-3-30 16:49:26 | 显示全部楼层
很好的资料收藏了!~

出0入0汤圆

发表于 2013-4-1 19:50:31 | 显示全部楼层
好东西,多谢了。

出0入0汤圆

发表于 2013-4-1 19:56:57 | 显示全部楼层
看看这个算法怎样

出0入0汤圆

发表于 2013-4-1 20:27:15 | 显示全部楼层
不错顶起

出0入0汤圆

发表于 2013-4-20 22:19:37 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2013-4-20 22:43:57 | 显示全部楼层
xi_liang 发表于 2013-3-15 01:28
参考资料

帮顶一下

出0入0汤圆

发表于 2013-4-21 00:45:03 | 显示全部楼层
必须顶,好资料~~~

出0入0汤圆

发表于 2013-4-21 00:56:39 | 显示全部楼层
xi_liang 发表于 2013-3-26 01:01
9320貌似只能改变扫描方向,并不能真正改变硬件坐标原点,只能用软件去调整。 ...

错误。。。可以调节物理坐标原点。。4个角都可以作为屏幕的物理原点。。不需要任何软件的调整。

出0入0汤圆

 楼主| 发表于 2013-4-21 01:16:37 | 显示全部楼层
myqiang1990 发表于 2013-4-21 00:56
错误。。。可以调节物理坐标原点。。4个角都可以作为屏幕的物理原点。。不需要任何软件的调整。 ...

哈哈,正等人回答我这个问题。R20h =0, R21h =0时,可以在四个角作为原点吗?需要设置什么寄存器呢

出0入0汤圆

发表于 2013-4-21 01:51:15 | 显示全部楼层
顶一下                                   

出0入0汤圆

发表于 2013-4-21 02:03:25 | 显示全部楼层
xi_liang 发表于 2013-4-21 01:16
哈哈,正等人回答我这个问题。R20h =0, R21h =0时,可以在四个角作为原点吗?需要设置什么寄存器呢 ...



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-4-21 02:10:01 | 显示全部楼层
本帖最后由 myqiang1990 于 2013-4-21 02:26 编辑

不理解的,自己拿仿真器,单步,完完全全就可以理解了!!!!所以不需要任何软件处理,有些人为了让图像反过来或者改变图像顺序,她们会这样做:320-Y,或者240-X,其实没必要~~这样是没有理解这些寄存器的设置(XY是你设置的坐标点)

还有一点要注意的是XY的定义,也就是水平和垂直,按照SSD1289,那么0--240是水平也就是我们常说的X,0--320是垂直也就是Y!!!这是硬件XY,我看了,9320的也是这样的,但是有时候程序上逻辑XY并不是这样定义的!!!比如UCGUI就不是!!!!!!他的X(水平)是0--320,而Y(垂直)是0--240!!!所以设定坐标的时候要注意了!!!一定要注意!!只要把XY交换,就OK乐!!!!!!

出0入0汤圆

 楼主| 发表于 2013-4-21 02:38:42 | 显示全部楼层
myqiang1990 发表于 2013-4-21 02:10
不理解的,自己拿仿真器,单步,完完全全就可以理解了!!!!所以不需要任何软件处理,有些人为了让图像反 ...

我看图那么详细,很感动。以后问题解决了,但仔细一看,可能我要令你失望了,这个实验我是有做过的,不需要仿真器,
在刷屏的时候延时长一点,就可以看到具体的刷屏过程了。可能是我手上的屏不支持,我再做下实验看

出0入0汤圆

发表于 2013-4-21 02:48:31 | 显示全部楼层
xi_liang 发表于 2013-4-21 02:38
我看图那么详细,很感动。以后问题解决了,但仔细一看,可能我要令你失望了,这个实验我是有做过的,不需 ...

我觉得很多人搞不清楚LCD这种扫描方向和原点设置的!!!!!等你实验搞清楚了,开一个贴教教大家!!!哈哈哈哈哈~~~让每个人都搞清楚,以后想怎么显示就怎么显示,图像也不会错了~~~

出0入0汤圆

发表于 2013-4-21 08:49:08 | 显示全部楼层
收藏,有机会看看

出0入0汤圆

发表于 2013-4-21 09:48:17 | 显示全部楼层
你好,我怎么模拟测试起来不对啊,我执行是先调用perform_calibration,再调用Touch,得到按下处的lcd坐标,用的是iar,CPU是mega32,模拟测试

//x和y分别表示五个点在触摸板上的坐标,xfb和yfb分别表示5个点在lcd屏幕上的坐标,
//a数组从a[0]到a[5]分别为A、B、C、D、E、F和一个除数,用于模拟浮点运算
typedef struct {
        int16 x[5];         //校准5个点在触摸板上的x坐标
    int16 xfb[5];       //校准5个点在lcd屏幕上的x坐标
        int16 y[5];         //校准5个点在触摸板上的y坐标
    int16 yfb[5];       //校准5个点在lcd屏幕上的y坐标
        int16 a[7];         //A、B、C、D、E、F和一个除数,用于模拟浮点运算           
    uint16 Sevx;        //采样x电压
    uint16 Sevy;        //采样y电压
    int16 Touchx;       //转换后的触摸板x坐标
    int16 Touchy;       //转换后的触摸板y坐标
} calibration;
int perform_calibration(calibration *cal);
void Touch(calibration *cal);
calibration cs;
//校准触摸屏
int perform_calibration(calibration *cal)
{
        cal->x[0] = 10;
    cal->x[1] = 10;
    cal->x[2] = 310;
    cal->x[3] = 310;
    cal->x[4] = 160;
    cal->y[0] = 10;
    cal->y[1] = 230;
    cal->y[2] = 10;
    cal->y[3] = 230;
    cal->y[4] = 120;//设置校准时,模拟按下的触摸屏坐标
    //
    cal->xfb[0] = 10;
    cal->xfb[1] = 10;
    cal->xfb[2] = 310;
    cal->xfb[3] = 310;
    cal->xfb[4] = 160;
    cal->yfb[0] = 10;
    cal->yfb[1] = 230;
    cal->yfb[2] = 10;
    cal->yfb[3] = 230;
    cal->yfb[4] = 120;//设置校准时,模拟按下的触摸屏坐标,对应下的lcd坐标,假设触摸屏和lcd尺寸都是,320x240
    //
        int j;
        float n, x, y, x2, y2, xy, z, zx, zy;
        float det, a, b, c, e, f, i;
        float scaling = 65536.0;

// Get sums for matrix
        n = x = y = x2 = y2 = xy = 0;
        for(j=0;j<5;j++) {
                n += 1.0;
                x += (float)cal->x[j];
                y += (float)cal->y[j];
                x2 += (float)(cal->x[j]*cal->x[j]);
                y2 += (float)(cal->y[j]*cal->y[j]);
                xy += (float)(cal->x[j]*cal->y[j]);
        }

// Get determinant of matrix -- check if determinant is too small
        det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);
        if(det < 0.1 && det > -0.1) {
                printf("ts_calibrate: determinant is too small -- %f\n\r",det);
                return 0;
        }

// Get elements of inverse matrix
        a = (x2*y2 - xy*xy)/det;
        b = (xy*y - x*y2)/det;
        c = (x*xy - y*x2)/det;
        e = (n*y2 - y*y)/det;
        f = (x*y - n*xy)/det;
        i = (n*x2 - x*x)/det;

// Get sums for x calibration
        z = zx = zy = 0;
        for(j=0;j<5;j++) {
                z += (float)cal->xfb[j];
                zx += (float)(cal->xfb[j]*cal->x[j]);
                zy += (float)(cal->xfb[j]*cal->y[j]);
        }

// Now multiply out to get the calibration for framebuffer x coord
        cal->a[0] = (int)((a*z + b*zx + c*zy)*(scaling));
        cal->a[1] = (int)((b*z + e*zx + f*zy)*(scaling));
        cal->a[2] = (int)((c*z + f*zx + i*zy)*(scaling));

        printf("%f %f %f\n\r",(a*z + b*zx + c*zy),
                                (b*z + e*zx + f*zy),
                                (c*z + f*zx + i*zy));

// Get sums for y calibration
        z = zx = zy = 0;
        for(j=0;j<5;j++) {
                z += (float)cal->yfb[j];
                zx += (float)(cal->yfb[j]*cal->x[j]);
                zy += (float)(cal->yfb[j]*cal->y[j]);
        }

// Now multiply out to get the calibration for framebuffer y coord
        cal->a[3] = (int)((a*z + b*zx + c*zy)*(scaling));
        cal->a[4] = (int)((b*z + e*zx + f*zy)*(scaling));
        cal->a[5] = (int)((c*z + f*zx + i*zy)*(scaling));

        printf("%f %f %f\n\r",(a*z + b*zx + c*zy),
                                (b*z + e*zx + f*zy),
                                (c*z + f*zx + i*zy));

// If we got here, we're OK, so assign scaling to a[6] and return
        cal->a[6] = (int)scaling;
        return 1;
/*       
// This code was here originally to just insert default values
        for(j=0;j<7;j++) {
                c->a[j]=0;
        }
        c->a[1] = c->a[5] = c->a[6] = 1;
        return 1;
*/

}
//这个函数模拟结果错误
void Touch(calibration *cal)
{
   cal->Sevx = 160;        //采样x电压,   手动设置为160,lcd,x的中心
  cal->Sevy =120;        //采样y电压   手动设置为120,lcd,y的中心
   //XL=XT*A+XT*B+C
    cal->Touchx = cal->Sevx*cal->a[0]+cal->Sevx*cal->a[1]+cal->a[2];     //得到的是480,不是lcd的横向中心160
    //YL=YT*D+YT*E+F   
    cal->Touchy = cal->Sevy*cal->a[3]+cal->Sevy*cal->a[4]+cal->a[5];     //得到的是0,不是lcd的竖向中心120

}

出0入0汤圆

发表于 2013-4-21 10:35:00 | 显示全部楼层
好东西  MARK

出0入0汤圆

发表于 2013-4-21 13:09:50 | 显示全部楼层
mark'!!!!!!!!!!!!

出0入0汤圆

发表于 2013-4-21 13:55:26 | 显示全部楼层
mark,最近也在用着库文件

出30入0汤圆

发表于 2013-4-21 23:37:55 | 显示全部楼层
算法很精妙,以前我是用查表的方法,又RZ又麻烦。

出0入0汤圆

发表于 2013-4-21 23:55:24 来自手机 | 显示全部楼层
学习一哈

出0入0汤圆

发表于 2013-4-22 09:15:14 | 显示全部楼层
谢谢LZ,顶起,很不错

出0入0汤圆

发表于 2013-4-22 09:22:28 | 显示全部楼层
留名,不错啊

出0入0汤圆

发表于 2013-4-22 10:55:26 | 显示全部楼层
必须mark一下

出0入0汤圆

发表于 2013-4-22 21:08:49 | 显示全部楼层
恩,很实用的东西。先Mark一下吧

出0入0汤圆

发表于 2013-4-22 22:27:18 | 显示全部楼层
正需要这个呢!谢谢了!

出0入0汤圆

发表于 2013-4-22 22:31:31 | 显示全部楼层
收藏了!!!

出0入0汤圆

发表于 2013-4-22 22:46:10 | 显示全部楼层
收了

出0入0汤圆

发表于 2013-4-23 21:09:00 | 显示全部楼层
学习了,顶起!!!

出0入0汤圆

发表于 2013-4-23 21:18:03 | 显示全部楼层
记录一下吧。触摸校正当时也做过,不知这个是否更简练一点呢。
还是下载试下。

出0入0汤圆

发表于 2013-5-2 18:37:40 | 显示全部楼层
mark,  顶一个

出0入0汤圆

发表于 2013-5-2 19:08:16 | 显示全部楼层
不错来学习学习。

出0入0汤圆

发表于 2013-5-2 20:34:19 | 显示全部楼层
mark。。。。

出0入0汤圆

发表于 2013-5-2 20:45:06 | 显示全部楼层
好东西,收藏之...........
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 19:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表