|
发表于 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
}
|
|