最完美的触摸屏校正算法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坐标,所以把触摸坐标和上述参数代入上面等式即可获得
程序源码
XL=XT*A+XT*B+C
YL=YT*D+YT*E+F
这两个三元一次方程的求解用到克拉姆法则
这是线性代数的内容,看不懂的先看下线性代数里行列式和矩阵的运算
参考资料
幫頂一下~{:smile:} 才改了野火了,今天试试这个。 不错。。顶一下 学习触屏校准 收le ~~~
学习,谢谢!!! 不错下来学习下 标题起的很牛,但是能否介绍下,到底是怎么样做到更完美呢? 过来是顶一下支持一下的 honami520 发表于 2013-3-15 10:55 static/image/common/back.gif
标题起的很牛,但是能否介绍下,到底是怎么样做到更完美呢?
tslib是嵌入式系统里用得最多的触摸屏校正算法.充分利用了矩阵的平移,旋转和缩放等运算.
原理和代码结合得很好,具体就不多说了 这个要得,不错。 这个标记下 这个我也在用着,感觉很不错~ 标记,顶一下。 牛牛牛 用的着,谢谢。 新公司准备搞STM32了,这个说不定有用哦。MARK一下{:lol:} 谢谢楼主 先mark 了 {:hug:}{:hug:}{:hug:}{:hug:}{:hug:}MARK 好 东西啊啊哈哈 好东西 mark一下 给力,顶起来。。。。。。。。。 谢谢百为的解答,看来这个应该比我自己写的要好很多了,下载下来看看先 有用,谢谢 mark,顶一下 楼主将tslib研究得很透彻。向你学习! 谢谢分享
xiexie
谢谢分享! 收藏备用. mark 学习 好东西,从理论到实践,全了 不错,学习之。。。 程序太多 在哪个文件夹啊 {:titter:}{:titter:} mkmk先!!!!! eryueniao 发表于 2013-3-18 12:32 static/image/common/back.gif
程序太多 在哪个文件夹啊
用3.5固件库模板建的工程,在目录touch\Project\STM32F10x_StdPeriph_Template\MDK-ARM下面 好东东, 一定要顶和MARK 马克思{:lol:} 学习一下 这个可以mark,谢谢 {:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:} 顶一下,先看看再说,感谢分享。下了备用,MARK了 五点校正 不粗的说 以前我也是做触摸屏的.先下了再说..感谢楼主 學習了! 9320貌似只能改变扫描方向,并不能真正改变硬件坐标原点,只能用软件去调整。 不错啊~~~~~ 我去试试 ,谢谢LZ 触摸屏校准,谢谢 非常感谢楼主分享。 顶一个,学习中!!! 谢谢楼主分享! 这个很不错啊。。 参考一下,应该很有用 马克一下 收藏下,谢谢分享 最完美,看看。 好资源,谢谢楼主 market 路过,顶楼主! 很好的资料收藏了!~ 好东西,多谢了。 看看这个算法怎样 不错顶起{:smile:} 谢谢分享 xi_liang 发表于 2013-3-15 01:28 static/image/common/back.gif
参考资料
帮顶一下 必须顶,好资料~~~ xi_liang 发表于 2013-3-26 01:01 static/image/common/back.gif
9320貌似只能改变扫描方向,并不能真正改变硬件坐标原点,只能用软件去调整。 ...
错误。。。可以调节物理坐标原点。。4个角都可以作为屏幕的物理原点。。不需要任何软件的调整。 myqiang1990 发表于 2013-4-21 00:56 static/image/common/back.gif
错误。。。可以调节物理坐标原点。。4个角都可以作为屏幕的物理原点。。不需要任何软件的调整。 ...
哈哈,正等人回答我这个问题。R20h =0, R21h =0时,可以在四个角作为原点吗?需要设置什么寄存器呢 顶一下 xi_liang 发表于 2013-4-21 01:16 static/image/common/back.gif
哈哈,正等人回答我这个问题。R20h =0, R21h =0时,可以在四个角作为原点吗?需要设置什么寄存器呢 ...
本帖最后由 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乐!!!!!! myqiang1990 发表于 2013-4-21 02:10 static/image/common/back.gif
不理解的,自己拿仿真器,单步,完完全全就可以理解了!!!!所以不需要任何软件处理,有些人为了让图像反 ...
我看图那么详细,很感动。以后问题解决了,但仔细一看,可能我要令你失望了,这个实验我是有做过的,不需要仿真器,
在刷屏的时候延时长一点,就可以看到具体的刷屏过程了。可能是我手上的屏不支持,我再做下实验看 xi_liang 发表于 2013-4-21 02:38 static/image/common/back.gif
我看图那么详细,很感动。以后问题解决了,但仔细一看,可能我要令你失望了,这个实验我是有做过的,不需 ...
我觉得很多人搞不清楚LCD这种扫描方向和原点设置的!!!!!等你实验搞清楚了,开一个贴教教大家!!!哈哈哈哈哈~~~让每个人都搞清楚,以后想怎么显示就怎么显示,图像也不会错了~~~ 收藏,有机会看看 你好,我怎么模拟测试起来不对啊,我执行是先调用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
}
好东西MARK mark'!!!!!!!!!!!! mark,最近也在用着库文件 算法很精妙,以前我是用查表的方法,又RZ又麻烦。 学习一哈 谢谢LZ,顶起,很不错 留名,不错啊 必须mark一下 恩,很实用的东西。先Mark一下吧 正需要这个呢!谢谢了! 收藏了!!! {:lol:}收了 学习了,顶起!!! 记录一下吧。触摸校正当时也做过,不知这个是否更简练一点呢。
还是下载试下。 mark,顶一个 不错来学习学习。 mark。。。。 好东西,收藏之...........