1,防止点击一个点,显示出5个点

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_执行过程

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_触摸屏_02

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_执行过程_03

Isr_Adc中同理也许要上报数据。

这里在touchscreen.c中还补充了上报压力值,当isr_adc上报data时,同时上报了压力值, 这样在ts_read_raw时能够读到压力值讯息。

分析下面这个函数:

当用户点击校准点A时,进入isr_Tc(), 检测到按下,启动adc,adc转换结束产生adc中断,进入isr_adc。然后adc上报坐标和压力值数据。

补充了rs_read_raw时,只有当松开时,也就是read raw读出来的压力值=0的时候才会返回数据。最上面的do while (pressure == 0)是为了过滤掉上一次松开后,下一次还没来得及点击就进入了get_calibrate_point_data,导致下次拿到的raw 坐标为0.

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_执行过程_04

修改完后验证就不会再出现点击一下出现5个十字架的情况。

2,  对于触摸屏要多次测量求平均值

经过长按A点测试发现,触摸屏的点在松开前得到的几组raw数据会很不稳定.

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_触摸屏_05

因此我们需要多次测量求平均。在adc_isr中,

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_数据_06

来分析下执行过程,当adc中断产生后读取ADCDAT数据,会统计坐标数据,当满16次后才会上报数据,否则继续启动ADC,统计坐标数据。

如果没满16次却检测到松开了,则执行else ,清零,并且上报坐标为0,压力值为0.

3. 要丢弃非法值(以LCD分辨率作为判断准备)

int get_lcd_x_frm_ts_x(int ts_x)
    {
        return g_kx * (ts_x - g_ts_xc) + g_lcd_xc;
    }
    
    int get_lcd_y_frm_ts_y(int ts_y)
    {
        return g_ky * (ts_y - g_ts_yc) + g_lcd_yc;
    }
    /*确定公式*/
    void ts_calibrate(void)
    {
    
        int a_ts_x, a_ts_y;
        int b_ts_x, b_ts_y;
        int c_ts_x, c_ts_y;
        int d_ts_x, d_ts_y;
        int e_ts_x, e_ts_y;
    
        /* X轴方向 */
        int ts_s1, ts_s2;
        int lcd_s;
    
        /* Y轴方向 */
        int ts_d1, ts_d2;
        int lcd_d;
    
        /* 获得LCD的参数: fb_base, xres, yres, bpp */
        get_lcd_params(&fb_base, &xres, &yres, &bpp);
    
        /* 对于ABCDE, 循环: 显示"+"、点击、读ts原始值 */
        /* A(50, 50) */
        get_calibrate_point_data(50, 50, &a_ts_x, &a_ts_y);    
    
        /* B(xres-50, 50) */
        get_calibrate_point_data(xres-50, 50, &b_ts_x, &b_ts_y);
    
        /* C(xres-50, yres-50) */
        get_calibrate_point_data(xres-50, yres-50, &c_ts_x, &c_ts_y);
    
        /* D(50, yres-50) */
        get_calibrate_point_data(50, yres-50, &d_ts_x, &d_ts_y);
        
        /* E(xres/2, yres/2) */
        get_calibrate_point_data(xres/2, yres/2, &e_ts_x, &e_ts_y);
    
        /* 确定触摸屏数据XY是否反转 */
        g_ts_xy_swap = is_ts_xy_swap(a_ts_x, a_ts_y, b_ts_x, b_ts_y);
    
        if (g_ts_xy_swap)
        {
            /* 对调所有点的XY坐标 */
            swap_xy(&a_ts_x, &a_ts_y);
            swap_xy(&b_ts_x, &b_ts_y);
            swap_xy(&c_ts_x, &c_ts_y);
            swap_xy(&d_ts_x, &d_ts_y);
            swap_xy(&e_ts_x, &e_ts_y);
        }
    
        /* 确定公式的参数并保存 */
        ts_s1 = b_ts_x - a_ts_x;
        ts_s2 = c_ts_x - d_ts_x;
        lcd_s = xres-50 - 50;
    
        ts_d1 = d_ts_y - a_ts_y;
        ts_d2 = c_ts_y - b_ts_y;
        lcd_d = yres-50-50;
    
        g_kx = ((double)(2*lcd_s)) / (ts_s1 + ts_s2);
        g_ky = ((double)(2*lcd_d)) / (ts_d1 + ts_d2);
    
        g_ts_xc = e_ts_x;
        g_ts_yc = e_ts_y;
    
        g_lcd_xc = xres/2;
        g_lcd_yc = yres/2;
    
        printf("A lcd_x = %08d, lcd_y = %08d\n\r", get_lcd_x_frm_ts_x(a_ts_x), get_lcd_y_frm_ts_y(a_ts_y));
        printf("B lcd_x = %08d, lcd_y = %08d\n\r", get_lcd_x_frm_ts_x(b_ts_x), get_lcd_y_frm_ts_y(b_ts_y));
        printf("C lcd_x = %08d, lcd_y = %08d\n\r", get_lcd_x_frm_ts_x(c_ts_x), get_lcd_y_frm_ts_y(c_ts_y));
        printf("D lcd_x = %08d, lcd_y = %08d\n\r", get_lcd_x_frm_ts_x(d_ts_x), get_lcd_y_frm_ts_y(d_ts_y));
        printf("E lcd_x = %08d, lcd_y = %08d\n\r", get_lcd_x_frm_ts_x(e_ts_x), get_lcd_y_frm_ts_y(e_ts_y));
    }
    
    /*
     * 确定好公式后,读TS原始数据, 转换为期待的坐标
     */
    int ts_read(int *lcd_x, int *lcd_y, int *lcd_pressure)
    {
        int ts_x, ts_y, ts_pressure;
        int tmp_x, tmp_y;
        
        ts_read_raw(&ts_x, &ts_y, &ts_pressure);
    
        if (g_ts_xy_swap)
        {
            swap_xy(&ts_x, &ts_y);
        }
    
        /* 使用公式计算 */
        tmp_x = g_kx * (ts_x - g_ts_xc) + g_lcd_xc;
        tmp_y = g_ky * (ts_y - g_ts_yc) + g_lcd_yc;
    
        if (tmp_x < 0 || tmp_x >= xres || tmp_y < 0 || tmp_y >= yres)
            return -1;
        
        *lcd_x = tmp_x;
        *lcd_y = tmp_y;
        *lcd_pressure = ts_pressure;
        return 0;
    }

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_数据_07

这样touchscreen_test就对触摸屏进行了校准,并且把校准后的坐标显示在对应的LCD上。可以看到点击一个位置,

校准后的触摸屏数据是和LCD显示位置的点是符合的。

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_执行过程_08

优化

遗留的问题:

①第一次点击触摸屏,LCD显示出两个点

②长按,lcd上的点越来越大要如何改进

根本原因是由于adc转换出来的x,y不稳定,动来动去,导致在LCD上画出来的点无法集中在一个点上。

下图很好的体现出来了上报数据的时序。

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_执行过程_09

1.当adc中断时,会启动连续16次adc中断,然后上报数据,上报数据的同时启动定时器

2.10ms定时时间到,timer中断,又再次启动adc,产生adc中断

3.循环1,2过程

 

当进入adc中断时,ts处于“自动测量模式”测量结束后需要进入等待中断模式。

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_执行过程_10

启动adc时,不能进入“等待中断模式”。

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_数据_11

那为什么adc转换出来的x,y不稳定,动来动去呢?

通过测试发现,在定时器中断中,还没松开就会打印出timer set pen up.通过查询寄存器得知,只有在“等待中断模式”,bit[15]才能作为判断松开按下的标志。

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_数据_12

 

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_触摸屏_13

那么有可能出现ADC中断过程中,定时器中断产生,如下图:

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_触摸屏_14

 

 

同理,adc_isr也是一样:

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_执行过程_15

最后在校准的时候,获取校准点坐标的时候,也取平均值。

 

android tslib电阻触摸屏校准 电阻式触摸屏怎么校正_执行过程_16