韦东山ARM裸机和uboot大全(第1期加强版)学习笔记18-第018课_ADC和触摸屏_第009~012节_触摸屏编程_较准原理

参考文章:STM32f103的电阻触摸屏的五点校正算法

一 校准原理

  1. 如下图,假如底下是LCD,上面是触摸屏膜(TS)。假设分辨率是480*272,那么在LCD坐标为(0,0)的地方,TS对应的点坐标为(x1’,y1’)。LCD坐标为(479,271)的地方,TS对应的点为(x2’,y2’)。
    那么,假如触点的坐标为(x’,y’),对应的LCD的点坐标呢?
    在这里插入图片描述

  2. 为了简化,我们先看x轴的坐标:
    在这里插入图片描述
    由上图我们可以得到一个等式,

(x' - x1')/(x2' - x1') = (x - 0)/(479 - 0)
 x = (479 - 0)*(x' - x1')/(x2' - x1')
  1. 但是上面的图,我们是选择了(0,0)和(479,271)这种边界点,一般这种点我们都点不准,所以下面我们选择一般的点。
    在这里插入图片描述
(x' - x1')/(x2' - x1') = (x - x1)/(x2 - x1)
x = (x2 - x1)*(x' - x1')/(x2' - x1') + x1

假设 k  = (x2 - x1)*(x' - x1'),
所以
x = k * (x' - x1') + x1
X轴方向:
Kx = (s1 + s2) / (s1' + s2') = 2s / (s1' + s2')     -----------   (假设的s1 = s2)
Y轴方向:
Ky = (d1 + d2) / (d1' + d2') = 2d / (d1' + d2')   ----------   (假设d1 = d2)

在这里插入图片描述
选取TS中心点的坐标为(xc’, yc’),LCD中心点的坐标为(xc,yc)
那么就可以由TS点击的点得到LCD上对应的点坐标,

x = (x' - xc')*Kx + xc
y = (y' - yc')*Ky + yc

二 校准和画线的代码编写

代码设计步骤:

1. 在A点显示十字架-“+”------------------------------------------------->fb_disp_cross(int x,int y)
2. 客户点击十字架-“+”
3. 记录触摸屏坐标-------------------------------------------------------->ts_read_raw()
4. 在B点/C点/D点/E点重复步骤1.~3.
5. 根据这些数据确定上述公式的各个参数-------------------------->ts_calibrate()
6. 后续即可根据以上公式由触点坐标转换出LCD的坐标-------->ts_read()

主函数执行流程:

main.c->
touchscreen_test()->
ts_calibrate()->
get_calibrate_point_data()//A点B点C点D点E点绘制“+”并读取触摸屏点值->
fb_disp_cross()//绘制“+”->
ts_read_raw()//等待点击并回读位置数据。注:此时已经获得所有点的触摸屏坐标和LCD坐标->

is_ts_xy_swap()//判断触摸屏XY坐标是否反->
swap_xy()//如果反需要调换->
XXXX//计算各个校准参数->

//实际应用调准参数进行计算
while (1)
{
    
    
	ts_read(&x, &y)
	{
    
    
		ts_read_raw(&ts_x, ts_y);//读取触摸屏原始坐标
		if (g_ts_xy_swap)
		{
    
    
			swap_xy(&ts_x, &ts_y);//调换触摸屏原始坐标
		}
		/* 使用公式计算 */
		*lcd_x = g_kx * (ts_x - g_ts_xc) + g_lcd_xc;
		*lcd_y = g_ky * (ts_y - g_ts_yc) + g_lcd_yc;
	}
	fb_put_pixel(x, y, 0xff00);
}

中断执行:

等待触摸屏中断->
进入触摸屏中断函数->
启动自动测量模式,启动ADC中断->
ADC中断程序执行,读取触摸屏的点位->
置位标志位g_ts_data_valid提示主程序继续执行

三 调试过程-发现问题和解决问题

  1. 问题:当触摸屏被按下的时候,底层定时器中断一直在执行启动ADC,ADC产生新的中断生成触摸屏数据;旧的数据直接丢掉;而触摸屏由按下到松开的时刻的触摸屏数据很不稳定导致校准数据生成有问题。
    解决方案:多次累加取平均。在ADC中断中,需要采样点数为16次之后才会上报本次转换结果并置位数据有效位。
  2. 问题:当显示A点“+”时,触摸屏按下;当触摸屏松开的时候,触摸屏的触摸松开中断首先触发调用report_ts_xy(0, 0, 0);底层ADC转换器转换完成中断稍后触发检测到此时触摸屏已经松开,再次调用report_ts_xy(0, 0, 0);
    两次调用之间间隔最大可达到10ms:AD转换完成中断刚刚触发(此时,再次启动定时中断)->触摸屏松开->触摸松开中断触发调用report_ts_xy(0, 0, 0);->定时中断启动使能AD转换完成中断->AD转换完成中断触发再次调用report_ts_xy(0, 0, 0);
    当最后一次AD转换完成中断完成之前,程序已经开始执行显示B点的“+”了。所以本次上报被认为是B点触摸屏数据的上报。
    解决方案:程序读取当前触摸屏坐标点之前设置阈值条件:必须按键按下才会继续向下执行,从而拦截住问题描述中的最后一次AD转换完成中断的误报。
  3. 问题:当计算出的校准后的LCD坐标值需要进行非法判断,如果超出屏幕分辨率则需要返回异常。
  4. 参考网络上tslib库。

四 继续完善

问题:a.点击触摸屏会出现两个点;b.长按LCD上的点会越来越大;
原因:
1.校准非常重要:ADC转换出来的坐标值不稳定,需要在校准的时候多次采样取平均值(不仅仅在ADC中断中求平均值);
2.定时器中断服务程序中:只有在"等待中断模式"下才可以使用ADCDAT0’BIT 15来判断触摸笔状态;当等待触发16次AD中断的过程中,已经进入自动测量模式,所以此时进入定时中断应当直接退出。
在这里插入图片描述
3.启动AD时不应该进入等待中断模式,它会影响数据(此时触摸屏控制开关均为关闭状态)

参考tslib:
a.使用矩阵进行校准,适应性更强;
b.使用多种方法消除误差:
多次测量取平均值;
判断相邻点的距离,如果突然变化很大就有可能时错误值
c. …

猜你喜欢

转载自blog.csdn.net/xiaoaojianghu09/article/details/104446884