اطلاعیه

Collapse
No announcement yet.

کالیبره کردن xpt2046?

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    کالیبره کردن xpt2046?

    سلام
    من از برنامه زیر استفاده می کنم برای تاچ ولی چند تا مشکل داره یکی اینکه انگار خوب کالیبره نمیشه
    دوم اینکه پرش در اعداد دارم که فکر می کنم همین پرش در میزان کالیبراسیون تاثیر گذاشته
    #include "xpt2046.h"
    /* Private variables ---------------------------------------------------------*/
    Matrix matrix;
    Coordinate display;
    Coordinate ScreenSample[3];
    Coordinate DisplaySample[3] = { {30, 45}, {400, 430}, {770, 45} };
    unsigned short intrupt;

    /* Private define ------------------------------------------------------------*/
    #define THRESHOLD 2

    extern unsigned char buf[20];
    extern SPI_HandleTypeDef hspi2;

    uint16_t Read_X(void)
    {
    uint16_t curr_X;

    reset_CS();
    WR_CMD(CHX);
    curr_X=RD_AD();
    set_CS();
    return curr_X;
    }

    uint16_t Read_Y(void)
    {
    uint16_t curr_Y;

    reset_CS();
    WR_CMD(CHY);
    curr_Y=RD_AD();
    set_CS();
    return curr_Y;
    }

    void XPT2046_GetAdXY(uint16_t *x,uint16_t *y)
    {
    uint16_t adx,ady;
    //adx=Read_X();
    //ady=Read_Y();
    reset_CS();
    WR_CMD(CHX);
    adx=RD_AD();

    WR_CMD(CHY);
    ady=RD_AD();

    //WR_CMD(0XD0);
    set_CS();

    *x=adx;
    *y=ady;
    }

    Coordinate *Read_XPT2046(void)
    {
    static Coordinate screen;
    int m0,m1,m2,temp[3];
    uint16_t TP_X[1],TP_Y[1];
    uint8_t count=0;
    int buffer[2][9]={{0},{0}};

    do
    {
    XPT2046_GetAdXY(TP_X,TP_Y);
    buffer[0][count]=TP_X[0];
    buffer[1][count]=TP_Y[0];
    count++;
    }
    while(!read_IRQ()&& count<9); /* TP_INT_IN */
    if(count==9) /* Average X Y */
    {
    /* Average X */
    temp[0]=(buffer[0][0]+buffer[0][1]+buffer[0][2])/3;
    temp[1]=(buffer[0][3]+buffer[0][4]+buffer[0][5])/3;
    temp[2]=(buffer[0][6]+buffer[0][7]+buffer[0][8])/3;

    m0=temp[0]-temp[1];
    m1=temp[1]-temp[2];
    m2=temp[2]-temp[0];

    m0=m0>0?m0:(-m0);
    m1=m1>0?m1:(-m1);
    m2=m2>0?m2:(-m2);

    if( m0>THRESHOLD && m1>THRESHOLD && m2>THRESHOLD ) return 0;

    if(m0<m1)
    {
    if(m2<m0)
    screen.x=(temp[0]+temp[2])/2;
    else
    screen.x=(temp[0]+temp[1])/2;
    }
    else if(m2<m1)
    screen.x=(temp[0]+temp[2])/2;
    else
    screen.x=(temp[1]+temp[2])/2;

    /* Average Y */
    temp[0]=(buffer[1][0]+buffer[1][1]+buffer[1][2])/3;
    temp[1]=(buffer[1][3]+buffer[1][4]+buffer[1][5])/3;
    temp[2]=(buffer[1][6]+buffer[1][7]+buffer[1][8])/3;
    m0=temp[0]-temp[1];
    m1=temp[1]-temp[2];
    m2=temp[2]-temp[0];
    m0=m0>0?m0:(-m0);
    m1=m1>0?m1:(-m1);
    m2=m2>0?m2:(-m2);
    if(m0>THRESHOLD&&m1>THRESHOLD&&m2>THRESHOLD) return 0;

    if(m0<m1)
    {
    if(m2<m0)
    screen.y=(temp[0]+temp[2])/2;
    else
    screen.y=(temp[0]+temp[1])/2;
    }
    else if(m2<m1)
    screen.y=(temp[0]+temp[2])/2;
    else
    screen.y=(temp[1]+temp[2])/2;

    return &screen;
    }
    return 0;
    }

    FunctionalState setCalibrationMatrix( Coordinate * displayPtr,
    Coordinate * screenPtr,
    Matrix * matrixPtr)
    {

    FunctionalState retTHRESHOLD = ENABLE ;
    /* K£½(X0£*X2) (Y1£*Y2)£*(X1£*X2) (Y0£*Y2) */
    matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
    ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
    if( matrixPtr->Divider == 0 )
    {
    retTHRESHOLD = DISABLE;
    }
    else
    {
    /* A£½((XD0£*XD2) (Y1£*Y2)£*(XD1£*XD2) (Y0£*Y2))£¯K */
    matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
    ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
    /* B£½((X0£*X2) (XD1£*XD2)£*(XD0£*XD2) (X1£*X2))£¯K */
    matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
    ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;
    /* C£½(Y0(X2XD1£*X1XD2)+Y1(X0XD2£*X2XD0)+Y2(X1XD0£*X0XD1))£¯K */
    matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
    (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
    (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;
    /* D£½((YD0£*YD2) (Y1£*Y2)£*(YD1£*YD2) (Y0£*Y2))£¯K */
    matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
    ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
    /* E£½((X0£*X2) (YD1£*YD2)£*(YD0£*YD2) (X1£*X2))£¯K */
    matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
    ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;
    /* F£½(Y0(X2YD1£*X1YD2)+Y1(X0YD2£*X2YD0)+Y2(X1YD0£*X0YD1))£¯K */
    matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
    (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
    (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
    }
    return( retTHRESHOLD ) ;
    }

    FunctionalState getDisplayPoint(Coordinate * displayPtr,
    Coordinate * screenPtr,
    Matrix * matrixPtr )
    {
    FunctionalState retTHRESHOLD =ENABLE ;

    if( matrixPtr->Divider != 0 )
    {
    /* XD = AX+BY+C */
    displayPtr->x = ( (matrixPtr->An * screenPtr->x) +
    (matrixPtr->Bn * screenPtr->y) +
    matrixPtr->Cn
    ) / matrixPtr->Divider ;
    /* YD = DX+EY+F */
    displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +
    (matrixPtr->En * screenPtr->y) +
    matrixPtr->Fn
    ) / matrixPtr->Divider ;
    }
    else
    {
    retTHRESHOLD = DISABLE;
    }
    return(retTHRESHOLD);
    }

    void TouchPanel_Calibrate(void)
    {
    unsigned char i;
    Coordinate * Ptr;

    for(i=0;i<3;i++)
    {
    LCD_Clear(White);
    //SSD1289_CleanText(44,10,"Touch crosshair to calibrate",Red);
    HAL_Delay(250);
    //LCD_SetPoint(DisplaySample[i].x,DisplaySample[i].y, Red);
    LCD_FillArea(DisplaySample[i].x,DisplaySample[i].y,(DisplaySample[i].x)+10,(DisplaySample[i].y)+10,Maroon);
    do
    {
    Ptr = Read_XPT2046();
    }
    while(Ptr == (void*)0);
    ScreenSample[i].x= Ptr->x; ScreenSample[i].y= Ptr->y;
    }
    setCalibrationMatrix( &DisplaySample[0],&ScreenSample[0],&matrix );
    LCD_Clear(Black);
    }

    static void set_CS(void)
    {
    GPIOB->ODR |=(1<<12);
    }

    static void reset_CS(void)
    {
    GPIOB->ODR &=~(1<<12);
    }

    static uint16_t read_IRQ(void)
    {
    return (uint16_t)((GPIOB->IDR&(1<<11))>>11);
    }

    uint16_t XPT2046_Press(void)
    {
    return read_IRQ();
    }

    static void WR_CMD (uint8_t cmd)
    {
    HAL_SPI_Transmit(&hspi2,&cmd,1,100);
    }

    static uint16_t RD_AD(void)
    {
    uint16_t buf;
    uint8_t temp[2];
    WR_CMD(0x00);
    temp[0]=SPI2->DR;
    WR_CMD(0x00);
    temp[1]=SPI2->DR;
    buf = ((temp[0]<<5) | (temp[1]>>3));
    return buf;
    }



    این هم قسمت main برنامه
    TouchPanel_Calibrate();
    /* USER CODE END 2 */



    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

    getDisplayPoint(&display, Read_XPT2046(), &matrix ) ;
    sprintf(buf,"X=%5d,Y=%5d",display.x,display.y);
    LCD_ShowString(0,0,buf,Black,White);
    HAL_Delay(70);
    }
    اللهم صل علی محمد و ال محمد و عجل فرجهم
    پیامبر اکرم(ص):زکات علم نشر آن است.
    در کشور هاي غربي انتقال تجربيات و دانش به افراد مبتدي يک پيشرفت محسوب شده و به آن مديريت دانش مي گويند. ولي متاسفانه اين فرهنگ هنوز در کشور ايران رايج نشده است !!!

    #2
    پاسخ : کالیبره کردن xpt2046?

    یه تغییراتی دادم و پرش ها رو رفع کردم ولی در کالیبره شدن یه مشکلی داره
    تقریبا همه چیز خوبه به غیر از اینکه مثلا سمت چپ که x باید کم ترین مقدار باشه که هست وقتی به سمت راست حرکت می کنم یه قسمت هایی اعداد باز کم میشه و بعد دوباره رو به افزایش هست
    تغییرات مربوط به این قسمت هست
    Coordinate *Read_XPT2046(void)
    {
    static Coordinate screen;
    int m0,m1,m2,temp[3];
    uint16_t TP_X[1],TP_Y[1];
    uint8_t count=0;
    int buffer[2][9]={{0},{0}};

    do
    {
    XPT2046_GetAdXY(TP_X,TP_Y);
    buffer[0][count]=TP_X[0];
    buffer[1][count]=TP_Y[0];
    sprintf(buf,"X=%5d,Y=%5d",TP_X[0],TP_Y[0]);
    LCD_ShowString(0,20+(count*20),buf,Black,White);
    count++;
    }
    while(!read_IRQ()&& count<9); /* TP_INT_IN */
    if(count==9)
    {
    temp[0]=(buffer[0][0]+buffer[0][1]+buffer[0][2])/3;
    temp[1]=(buffer[0][3]+buffer[0][4]+buffer[0][5])/3;
    temp[2]=(buffer[0][6]+buffer[0][7]+buffer[0][8])/3;
    screen.x=(temp[0]+temp[1]+temp[2])/3;

    temp[0]=(buffer[1][0]+buffer[1][1]+buffer[1][2])/3;
    temp[1]=(buffer[1][3]+buffer[1][4]+buffer[1][5])/3;
    temp[2]=(buffer[1][6]+buffer[1][7]+buffer[1][8])/3;
    screen.y=(temp[0]+temp[1]+temp[2])/3;

    return &screen;

    }
    اللهم صل علی محمد و ال محمد و عجل فرجهم
    پیامبر اکرم(ص):زکات علم نشر آن است.
    در کشور هاي غربي انتقال تجربيات و دانش به افراد مبتدي يک پيشرفت محسوب شده و به آن مديريت دانش مي گويند. ولي متاسفانه اين فرهنگ هنوز در کشور ايران رايج نشده است !!!

    دیدگاه

    لطفا صبر کنید...
    X