查看: 922|回复: 0
打印 上一主题 下一主题

驱动XPT2046一个很奇怪的现象,大家看下怎么回事

[复制链接]
跳转到指定楼层
沙发
发表于 2015-10-8 07:18:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序的功能是采集触摸屏坐标,然后在此坐标画点。但是却出现下图的现象,换了两套滤波消抖算法,甚至换了另一个方案的屏还是这样。纠结两天了,大家帮忙看下是怎么回事。


经过验证,绘图算法是没有问题的。而且根据LOG发现,问题根源应该是在触摸驱动上。但是小弟真的琢磨不出是什么原因。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "xpt2046.h"
#include "lcd.h"
#include "pin.h"

#define TP_CS_LOW() {PBout(12) = 0;}
#define TP_CS_HIGH() {PBout(12) = 1;}

#define ADJUST_TOUCH_DELAY 500

#define FILTER_SAMPLE 9

#define ADJUST_POINT1 LCD_WIDTH*1/6,LCD_HEIGHT*1/6
#define ADJUST_POINT2 LCD_WIDTH*5/6,LCD_HEIGHT*1/6
#define ADJUST_POINT3 LCD_WIDTH*1/6,LCD_HEIGHT*5/6
#define ADJUST_POINT4 LCD_WIDTH*5/6,LCD_HEIGHT*5/6
#define ADJUST_POINT5 LCD_WIDTH/2,LCD_HEIGHT/2

extern SPI_HandleTypeDef hspi2;

//X: 0.014766,-0.001094,-39.920000
//Y: -0.021198,-0.000286,618.693333

//double Ax = 0.012000,Bx = -0.001094, Cx = -39.920000;
//double Ay = -0.021198,By = -0.000286,Cy = 618.693333;

double Ax = 0.015193,Bx = 0.000179,Cx = -93.940186;
double Ay = -0.020224,By = -0.000281,Cy = 591.518222;

//double Ax,Bx,Cx;
//double Ay,By,Cy;

BOOL adjust_enable = FALSE;
BOOL adjust_pressed = FALSE;

void _sort(uint16_t dat[])
{

        uint16_t tmp;
        for(int i = 0 ; i < FILTER_SAMPLE - 1 ; i ++)
        {
                for(int j = 1 ; j < FILTER_SAMPLE; j ++)
                {
                        if(dat[i] > dat[j])
                        {
                                tmp = dat[i];
                                dat[i] = dat[j];
                                dat[j] = tmp;
                        }
                }
        }
}

/*
* Read raw ad value.
*/
void XPT2046_GetRawPos_(uint16_t *x, uint16_t *y)
{
        uint8_t tx_buf, rx_buf;
        TP_CS_LOW();

        tx_buf = 0xD0;
        HAL_SPI_TransmitReceive(&hspi2, &tx_buf, &rx_buf, 1, 2000);                                                                                                                                                                                                                                                                        

        tx_buf = 0x00;
        HAL_SPI_TransmitReceive(&hspi2, &tx_buf, &rx_buf, 1, 2000);
        *x = rx_buf << 8;

        tx_buf = 0x00;
        HAL_SPI_TransmitReceive(&hspi2, &tx_buf, &rx_buf, 1, 2000);
        *x += rx_buf;

        tx_buf = 0x90;
        HAL_SPI_TransmitReceive(&hspi2, &tx_buf, &rx_buf, 1, 2000);

        tx_buf = 0x00;
        HAL_SPI_TransmitReceive(&hspi2, &tx_buf, &rx_buf, 1, 2000);
        *y = rx_buf << 8;

        tx_buf = 0x00;
        HAL_SPI_TransmitReceive(&hspi2, &tx_buf, &rx_buf, 1, 2000);
        *y += rx_buf;

        TP_CS_HIGH();

        *y >>=2;
        *x >>=2;
}

static void _delay()
{
        for(int i = 10000; i --;);
}

/*
*        AD Fliter
*/
void XPT2046_GetRawPos(uint16_t *x, uint16_t *y)
{
        uint16_t rx[FILTER_SAMPLE], ry[FILTER_SAMPLE];
        float jx[FILTER_SAMPLE/3],jy[FILTER_SAMPLE/3];
        int m0,m1,m2;
        int tmx,tmy;

        RESTART:

        for(int i = 0 ; i < FILTER_SAMPLE ; i ++)
        {
                XPT2046_GetRawPos_(&rx[i],&ry[i]);
                printf("=%hd,%hd=",rx[i],ry[i]);
                HAL_Delay(1);
        }

        jx[0] = (rx[0] + rx[1] + rx[2])/3;
        jx[1] = (rx[3] + rx[4] + rx[5])/3;
        jx[2] = (rx[6] + rx[7] + rx[8])/3;
        m0 = jx[0] - jx[1];
        m1 = jx[1] - jx[2];
        m2 = jx[2] - jx[0];
        m0=m0>0? m0-m0);
        m1=m1>0? m1-m1);
        m2=m2>0? m2-m2);

        //printf("%d,%d,%d\r\n",m0,m1,m2);

        if(m0 > 200 && m1 > 200 && m2 > 200)
                goto RESTART;

        if(m0<m1) {
                if(m2<m0)
                        tmx=(jx[0]+jx[2])/2;
                else
                        tmx=(jx[0]+jx[1])/2;
        }else {
                if(m2<m1)
                        tmx=(jx[0]+jx[2])/2;
                else
                        tmx=(jx[1]+jx[2])/2;
        }

        jy[0] = (ry[0] + ry[1] + ry[2])/3;
        jy[1] = (ry[3] + ry[4] + ry[5])/3;
        jy[2] = (ry[6] + ry[7] + ry[8])/3;
        m0 = jy[0] - jy[1];
        m1 = jy[1] - jy[2];
        m2 = jy[2] - jy[0];
        m0=m0>0? m0-m0);
        m1=m1>0? m1-m1);
        m2=m2>0? m2-m2);

        if(m0 > 200 && m1 > 200 && m2 > 200)
                goto RESTART;

        if(m0<m1) {
                if(m2<m0)
                        tmy=(jy[0]+jy[2])/2;
                else
                        tmy=(jy[0]+jy[1])/2;
        }else {
                if(m2<m1)
                        tmy=(jy[0]+jy[2])/2;
                else
                        tmy=(jy[1]+jy[2])/2;
        }

        *x = tmx;
        *y = tmy;
}

void Touch_GetPosition(uint16_t *x, uint16_t *y)
{
        uint16_t rx,ry;
        XPT2046_GetRawPos(&rx, &ry);

        *x = Ax * rx + Bx * ry + Cx;
        *y = Ay * ry + By * rx + Cy;

        printf("--%hd,%hd,%hd,%hd \r\n",*x,*y,rx,ry);
}

static void _draw_cross(uint16_t x, uint16_t y)
{
        x -= 10;
        for(uint16_t i = 0; i < 20; i++)
        {
                Lcd_DrawPixel(x + i, y,Red);
        }
        x += 10;
        y -= 10;
        for(uint16_t i = 0; i < 20; i++)
        {
                Lcd_DrawPixel(x, y + i,Red);
        }
}

static void calculate(int X1, int Y1, int C1,
                           int X2, int Y2, int C2,
                           int X3, int Y3, int C3,
                           double *A ,double *B ,double *C)
{
        double a = X1;
        double b = Y1;
        double c = 1;
        double d = C1;

        double e = X2;
        double f = Y2;
        double g = 1;
        double h = C2;

        double i = X3;
        double j = Y3;
        double k = 1;
        double l = C3;

        //<!--EVALUATING THE DELTA DETERMINANT -->
        double delta = (a*f*k)+(b*g*i)+(c*e*j)-(c*f*i)-(a*g*j)-(b*e*k);

        //<!--EVALUATING THE X NUMERATOR & ANSWER -->
        double xnum = (d*f*k)+(b*g*l)+(c*h*j)-(c*f*l)-(d*g*j)-(b*h*k);
        double xans = xnum/delta;
        *A = xans;

        //<!--EVALUATING THE Y NUMERATOR & ANSWER -->
        double ynum = (a*h*k)+(d*g*i)+(c*e*l)-(c*h*i)-(a*g*l)-(d*e*k);
        double yans = ynum/delta;
        *B = yans;

        //<!--EVALUATING THE Z NUMERATOR & ANSWER -->
        double znum = (a*f*l)+(b*h*i)+(d*e*j)-(d*f*i)-(a*h*j)-(b*e*l);
        double zans = znum/delta;
        *C = zans;
}

BOOL ADJUST_TOUCH_IRQ(void)
{
        adjust_pressed = TRUE;
        return adjust_enable;
}

void Touch_Adjust(void)
{
        uint16_t x1,x2,x3,x4,x5;
        uint16_t y1,y2,y3,y4,y5;
        adjust_enable = TRUE;

        Lcd_Clear(White);
        _draw_cross(ADJUST_POINT1);
        while(adjust_pressed != TRUE){}
        XPT2046_GetRawPos(&x1,&y1);
        HAL_Delay(ADJUST_TOUCH_DELAY);
        adjust_pressed = FALSE;

        Lcd_Clear(White);
        _draw_cross(ADJUST_POINT2);
        while(adjust_pressed != TRUE){}
        XPT2046_GetRawPos(&x2,&y2);
        HAL_Delay(ADJUST_TOUCH_DELAY);
        adjust_pressed = FALSE;

        Lcd_Clear(White);
        _draw_cross(ADJUST_POINT3);
        while(adjust_pressed != TRUE){}
        XPT2046_GetRawPos(&x3,&y3);
        HAL_Delay(ADJUST_TOUCH_DELAY);
        adjust_pressed = FALSE;

        Lcd_Clear(White);
        _draw_cross(ADJUST_POINT4);
        while(adjust_pressed != TRUE){}
        XPT2046_GetRawPos(&x4,&y4);
        HAL_Delay(ADJUST_TOUCH_DELAY);
        adjust_pressed = FALSE;

        Lcd_Clear(White);
        _draw_cross(ADJUST_POINT5);
        while(adjust_pressed != TRUE){}
        XPT2046_GetRawPos(&x5,&y5);
        HAL_Delay(ADJUST_TOUCH_DELAY);
        adjust_pressed = FALSE;

        printf("%hx,%hx,%hx,%hx,%hx,\r\n",x1,x2,x3,x4,x5);
        printf("%hx,%hx,%hx,%hx,%hx,\r\n",y1,y2,y3,y4,y5);

        calculate(x1,y1,LCD_WIDTH*1/6,
                                                x2,y2,LCD_WIDTH*5/6,
                                                x4,y4,LCD_WIDTH*5/6,
                                                &Ax,&Bx,&Cx);

        calculate(y1,x1,LCD_HEIGHT*1/6,
                                                y2,x2,LCD_HEIGHT*1/6,
                                                y4,x4,LCD_HEIGHT*5/6,
                                                &Ay,&By,&Cy);

        printf("X: %f,%f,%f\r\n",Ax,Bx,Cx);
        printf("Y: %f,%f,%f\r\n",Ay,By,Cy);

        Lcd_Clear(White);
        adjust_enable = FALSE;
}
复制代码转载

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表