xi_liang 发表于 2013-3-15 01:21:59

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

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坐标,所以把触摸坐标和上述参数代入上面等式即可获得

程序源码




xi_liang 发表于 2013-3-18 01:39:24

XL=XT*A+XT*B+C
YL=YT*D+YT*E+F
这两个三元一次方程的求解用到克拉姆法则
这是线性代数的内容,看不懂的先看下线性代数里行列式和矩阵的运算

xi_liang 发表于 2013-3-15 01:28:22

参考资料


john800422 发表于 2013-3-15 03:24:19

幫頂一下~{:smile:}

chaoyue0376 发表于 2013-3-15 08:06:12

才改了野火了,今天试试这个。

dabi 发表于 2013-3-15 08:26:24

不错。。顶一下

ngyg12 发表于 2013-3-15 09:09:04

学习触屏校准

myqiang1990 发表于 2013-3-15 09:11:24

收le ~~~

dory_m 发表于 2013-3-15 09:29:16

学习,谢谢!!!

zhikai_wu 发表于 2013-3-15 09:52:42

不错下来学习下

honami520 发表于 2013-3-15 10:55:52

标题起的很牛,但是能否介绍下,到底是怎么样做到更完美呢?

nazily215 发表于 2013-3-15 11:09:04

过来是顶一下支持一下的

xi_liang 发表于 2013-3-15 22:10:32

honami520 发表于 2013-3-15 10:55 static/image/common/back.gif
标题起的很牛,但是能否介绍下,到底是怎么样做到更完美呢?

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

kinsno 发表于 2013-3-15 23:36:22

这个要得,不错。

chengpiaopiao 发表于 2013-3-15 23:56:46

这个标记下

Eve昔枫 发表于 2013-3-16 00:01:53

nongxiaoming 发表于 2013-3-16 02:18:15

这个我也在用着,感觉很不错~

eric.zhc 发表于 2013-3-16 07:32:17

标记,顶一下。

zoto 发表于 2013-3-16 07:40:45

牛牛牛

Excellence 发表于 2013-3-16 07:59:34

用的着,谢谢。

bruce_helen 发表于 2013-3-16 08:09:57

新公司准备搞STM32了,这个说不定有用哦。MARK一下{:lol:}

James_King 发表于 2013-3-16 08:44:40

谢谢楼主

sync765 发表于 2013-3-16 10:06:25

先mark 了

cjt5132 发表于 2013-3-16 10:25:11

{:hug:}{:hug:}{:hug:}{:hug:}{:hug:}MARK

cdlxzlp 发表于 2013-3-16 11:01:33

好 东西啊啊哈哈

zfx19890921 发表于 2013-3-16 11:30:48

好东西 mark一下

tiramisu0501 发表于 2013-3-16 11:36:30

给力,顶起来。。。。。。。。。

honami520 发表于 2013-3-16 12:50:37

谢谢百为的解答,看来这个应该比我自己写的要好很多了,下载下来看看先

ljqlaq 发表于 2013-3-16 12:58:27

有用,谢谢

dayaue 发表于 2013-3-16 17:35:32

mark,顶一下

sunliezhi 发表于 2013-3-16 17:41:53

楼主将tslib研究得很透彻。向你学习!

1501697860 发表于 2013-3-16 21:43:52

谢谢分享

Stone_up 发表于 2013-3-16 21:45:35

xiexie


chaled 发表于 2013-3-16 22:43:14

谢谢分享!

mf_zou 发表于 2013-3-17 00:08:06

收藏备用.

wcm_e 发表于 2013-3-17 00:19:48

mark 学习

amwox 发表于 2013-3-18 08:38:52

好东西,从理论到实践,全了

Shaw.Embedi 发表于 2013-3-18 08:58:04

不错,学习之。。。

eryueniao 发表于 2013-3-18 12:32:46

程序太多      在哪个文件夹啊

pchf005 发表于 2013-3-18 13:19:24

{:titter:}{:titter:}

eaglelpx 发表于 2013-3-18 14:02:00

mkmk先!!!!!

xi_liang 发表于 2013-3-18 14:20:54

eryueniao 发表于 2013-3-18 12:32 static/image/common/back.gif
程序太多      在哪个文件夹啊

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

Antony 发表于 2013-3-18 14:27:45

好东东, 一定要顶和MARK

Ytu-xiaolizig 发表于 2013-3-18 17:36:59

马克思{:lol:}

lncwangfeilnc 发表于 2013-3-18 19:38:35

学习一下

lbing2002 发表于 2013-3-18 20:43:12

这个可以mark,谢谢

cjc2010 发表于 2013-3-18 20:47:43

{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}

crose0106 发表于 2013-3-19 09:56:23

顶一下,先看看再说,感谢分享。下了备用,MARK了

himan 发表于 2013-3-19 11:59:20

五点校正 不粗的说

高达 发表于 2013-3-19 16:20:08

以前我也是做触摸屏的.先下了再说..感谢楼主

zhengyang 发表于 2013-3-19 18:41:20

學習了!

xi_liang 发表于 2013-3-26 01:01:39

9320貌似只能改变扫描方向,并不能真正改变硬件坐标原点,只能用软件去调整。

mypear 发表于 2013-3-26 10:38:57

不错啊~~~~~

安静 发表于 2013-3-26 10:59:48

我去试试 ,谢谢LZ

hxke 发表于 2013-3-26 11:20:18

触摸屏校准,谢谢

clian1314 发表于 2013-3-26 14:28:06

非常感谢楼主分享。

睿翼1992 发表于 2013-3-27 00:00:12

顶一个,学习中!!!

fayuanye 发表于 2013-3-28 11:19:40

谢谢楼主分享!

limxuzheng 发表于 2013-3-28 12:10:23

这个很不错啊。。

357853730 发表于 2013-3-28 21:44:31

参考一下,应该很有用

ZXL1969 发表于 2013-3-29 08:01:30

马克一下

mvip 发表于 2013-3-29 19:15:47

收藏下,谢谢分享

ljt80158015 发表于 2013-3-29 19:39:02

最完美,看看。

2006lc 发表于 2013-3-29 21:42:24

好资源,谢谢楼主

moouse 发表于 2013-3-30 11:37:52

market                           

eehong 发表于 2013-3-30 14:52:10

路过,顶楼主!

jsxzfxcg 发表于 2013-3-30 16:49:26

很好的资料收藏了!~

huangxuankui 发表于 2013-4-1 19:50:31

好东西,多谢了。

bwb0518 发表于 2013-4-1 19:56:57

看看这个算法怎样

zwgmail 发表于 2013-4-1 20:27:15

不错顶起{:smile:}

enovo2468 发表于 2013-4-20 22:19:37

谢谢分享

wallacer 发表于 2013-4-20 22:43:57

xi_liang 发表于 2013-3-15 01:28 static/image/common/back.gif
参考资料

帮顶一下

chenfzg 发表于 2013-4-21 00:45:03

必须顶,好资料~~~

myqiang1990 发表于 2013-4-21 00:56:39

xi_liang 发表于 2013-3-26 01:01 static/image/common/back.gif
9320貌似只能改变扫描方向,并不能真正改变硬件坐标原点,只能用软件去调整。 ...

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

xi_liang 发表于 2013-4-21 01:16:37

myqiang1990 发表于 2013-4-21 00:56 static/image/common/back.gif
错误。。。可以调节物理坐标原点。。4个角都可以作为屏幕的物理原点。。不需要任何软件的调整。 ...

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

2005n2005 发表于 2013-4-21 01:51:15

顶一下                                 

myqiang1990 发表于 2013-4-21 02:03:25

xi_liang 发表于 2013-4-21 01:16 static/image/common/back.gif
哈哈,正等人回答我这个问题。R20h =0, R21h =0时,可以在四个角作为原点吗?需要设置什么寄存器呢 ...



myqiang1990 发表于 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乐!!!!!!

xi_liang 发表于 2013-4-21 02:38:42

myqiang1990 发表于 2013-4-21 02:10 static/image/common/back.gif
不理解的,自己拿仿真器,单步,完完全全就可以理解了!!!!所以不需要任何软件处理,有些人为了让图像反 ...

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

myqiang1990 发表于 2013-4-21 02:48:31

xi_liang 发表于 2013-4-21 02:38 static/image/common/back.gif
我看图那么详细,很感动。以后问题解决了,但仔细一看,可能我要令你失望了,这个实验我是有做过的,不需 ...

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

JACK847070222 发表于 2013-4-21 08:49:08

收藏,有机会看看

cnxh 发表于 2013-4-21 09:48:17

你好,我怎么模拟测试起来不对啊,我执行是先调用perform_calibration,再调用Touch,得到按下处的lcd坐标,用的是iar,CPU是mega32,模拟测试

//x和y分别表示五个点在触摸板上的坐标,xfb和yfb分别表示5个点在lcd屏幕上的坐标,
//a数组从a到a分别为A、B、C、D、E、F和一个除数,用于模拟浮点运算
typedef struct {
        int16 x;         //校准5个点在触摸板上的x坐标
    int16 xfb;       //校准5个点在lcd屏幕上的x坐标
        int16 y;         //校准5个点在触摸板上的y坐标
    int16 yfb;       //校准5个点在lcd屏幕上的y坐标
        int16 a;         //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 = 10;
    cal->x = 10;
    cal->x = 310;
    cal->x = 310;
    cal->x = 160;
    cal->y = 10;
    cal->y = 230;
    cal->y = 10;
    cal->y = 230;
    cal->y = 120;//设置校准时,模拟按下的触摸屏坐标
    //
    cal->xfb = 10;
    cal->xfb = 10;
    cal->xfb = 310;
    cal->xfb = 310;
    cal->xfb = 160;
    cal->yfb = 10;
    cal->yfb = 230;
    cal->yfb = 10;
    cal->yfb = 230;
    cal->yfb = 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;
                y += (float)cal->y;
                x2 += (float)(cal->x*cal->x);
                y2 += (float)(cal->y*cal->y);
                xy += (float)(cal->x*cal->y);
        }

// 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;
                zx += (float)(cal->xfb*cal->x);
                zy += (float)(cal->xfb*cal->y);
        }

// Now multiply out to get the calibration for framebuffer x coord
        cal->a = (int)((a*z + b*zx + c*zy)*(scaling));
        cal->a = (int)((b*z + e*zx + f*zy)*(scaling));
        cal->a = (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;
                zx += (float)(cal->yfb*cal->x);
                zy += (float)(cal->yfb*cal->y);
        }

// Now multiply out to get the calibration for framebuffer y coord
        cal->a = (int)((a*z + b*zx + c*zy)*(scaling));
        cal->a = (int)((b*z + e*zx + f*zy)*(scaling));
        cal->a = (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 and return
        cal->a = (int)scaling;
        return 1;
/*       
// This code was here originally to just insert default values
        for(j=0;j<7;j++) {
                c->a=0;
        }
        c->a = c->a = c->a = 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+cal->Sevx*cal->a+cal->a;   //得到的是480,不是lcd的横向中心160
    //YL=YT*D+YT*E+F   
    cal->Touchy = cal->Sevy*cal->a+cal->Sevy*cal->a+cal->a;   //得到的是0,不是lcd的竖向中心120

}

430504 发表于 2013-4-21 10:35:00

好东西MARK

babyhua 发表于 2013-4-21 13:09:50

mark'!!!!!!!!!!!!

lidapang 发表于 2013-4-21 13:55:26

mark,最近也在用着库文件

linquan315 发表于 2013-4-21 23:37:55

算法很精妙,以前我是用查表的方法,又RZ又麻烦。

abc 发表于 2013-4-21 23:55:24

学习一哈

mypc16888 发表于 2013-4-22 09:15:14

谢谢LZ,顶起,很不错

farmerzhangdl 发表于 2013-4-22 09:22:28

留名,不错啊

pdabug 发表于 2013-4-22 10:55:26

必须mark一下

windancerhxw 发表于 2013-4-22 21:08:49

恩,很实用的东西。先Mark一下吧

chunri 发表于 2013-4-22 22:27:18

正需要这个呢!谢谢了!

LK9286 发表于 2013-4-22 22:31:31

收藏了!!!

ZCLiu 发表于 2013-4-22 22:46:10

{:lol:}收了

冰冻三尺_liming 发表于 2013-4-23 21:09:00

学习了,顶起!!!

TANK99 发表于 2013-4-23 21:18:03

记录一下吧。触摸校正当时也做过,不知这个是否更简练一点呢。
还是下载试下。

LZW520 发表于 2013-5-2 18:37:40

mark,顶一个

fanwenqiang666 发表于 2013-5-2 19:08:16

不错来学习学习。

仇先天 发表于 2013-5-2 20:34:19

mark。。。。

wenunit 发表于 2013-5-2 20:45:06

好东西,收藏之...........
页: [1] 2 3
查看完整版本: 最完美的触摸屏校正算法tslib——STM32实现(源码+图)