LO单片机VE 发表于 2015-11-14 20:20:43

请求帮助:SK-LPC1788开发板触摸屏受4.3寸TFT(480*272)干扰

本帖最后由 LO单片机VE 于 2015-11-14 22:33 编辑

最近一直都在SK-LPC1788开发板上学习TFT显示与触摸屏功能,现在的问题是当触摸屏外接单独测试读数是很稳定的,AD值读出来跳变在1-2个码左右;如果把触摸屏贴在TFT显示屏上,同时TFT正常显示,这时触摸读取的AD值就不稳定了,跳码在几十个码之间。
我自己有做如下尝试,但效果没有改善:
1. X+,Y+,X—,Y-上各焊了一个221(220PF)的电容到地;
2. TFT显示屏外壳接地;
3. 换过TSC2046触摸芯片;
4. 换过四线制电阻触摸屏;
5. 软件上将TFT的刷新率降低;

(注:在TFT显示关闭的状态下,触摸屏贴在TFT上读取显示很稳定的,从这点可以更加确信是TFT显示干扰了触摸屏!)

我现在想不通TFT外壳都接地了怎么还会干扰到触摸屏呢,不知道该如何解决,希望各位看过这个问题能提供点意见,小弟在此先谢过了。

foric 发表于 2015-11-15 22:33:16

先发原理图 资料 共享再说

LO单片机VE 发表于 2015-11-16 10:59:20

我将与触摸和LCD相关的原理图和程序发上来,请大家帮我一起分析分析,如果资料还不够完善的我将积极配合上传,谢谢。

/***********************************Touch_SPI.c文件*************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <LPC177x_8x.h>
#include "lpc_types.h"
#include "Touch_spi.h"

/*******************************************************************************
软件模拟SPI方式读取触摸屏
*******************************************************************************/

#define TFT_TOUCH_CS_L       (LPC_GPIO0->CLR |= (0x1<<6))    //P0.6 (OUTPUT)
#define TFT_TOUCH_CS_H       (LPC_GPIO0->SET |= (0x1<<6))

#define TFT_TOUCH_INT      (LPC_GPIO2->PIN&(0x1<<15))      //P2.15 (INPUT)

#define TFT_TOUCH_BUSY       (LPC_GPIO2->PIN&(0x1<<14))      //P2.14 (INPUT)

#define TFT_TOUCH_SCK_L      (LPC_GPIO1->CLR |= (0x1<<19))   //P1.19 (OUTPUT)
#define TFT_TOUCH_SCK_H      (LPC_GPIO1->SET |= (0x1<<19))

#define TFT_TOUCH_MOSI_L   (LPC_GPIO0->CLR |= (0x1<<13))   //P0.13 (OUTPUT)
#define TFT_TOUCH_MOSI_H   (LPC_GPIO0->SET |= (0x1<<13))

#define TFT_TOUCH_MISO       (LPC_GPIO0->PIN&(0x1<<12))      //P0.12 (INPUT)


/*
#define TFT_TOUCH_CS_L       (LPC_GPIO2->CLR |= (0x1<<23))   //P2.23 (OUTPUT)
#define TFT_TOUCH_CS_H       (LPC_GPIO2->SET |= (0x1<<23))

#define TFT_TOUCH_INT      (LPC_GPIO0->PIN&(0x1<<16))      //P0.16 (INPUT)

#define TFT_TOUCH_BUSY       (LPC_GPIO0->PIN&(0x1<<15))      //P0.15 (INPUT)

#define TFT_TOUCH_SCK_L      (LPC_GPIO2->CLR |= (0x1<<22))   //P2.22 (OUTPUT)
#define TFT_TOUCH_SCK_H      (LPC_GPIO2->SET |= (0x1<<22))

#define TFT_TOUCH_MOSI_L   (LPC_GPIO2->CLR |= (0x1<<27))   //P2.27 (OUTPUT)
#define TFT_TOUCH_MOSI_H   (LPC_GPIO2->SET |= (0x1<<27))

#define TFT_TOUCH_MISO       (LPC_GPIO2->PIN&(0x1<<26))      //P2.26 (INPUT)
*/

#define DELAY_200NS         30

/*******************************************************************************
函数名称:void DelayNo(uint32_ti)
功    能:SPI延时函数
参    数:无
返回值:无
********************************************************************************/
void DelayNo(uint32_ti)
{
        for(;i>0;i--);
}
/*******************************************************************************
函数名称:void SPI_GPIOInit(void)
功    能:SPI引脚初始化配置
参    数:无
返回值:无
********************************************************************************/   
void SPI_GPIOInit(void)
{
       
        LPC_IOCON->P1_19 &= ~0x07;      //SCLKOUTPUT
        LPC_GPIO1->DIR |=(0x01<<19);
       
        LPC_IOCON->P0_6&= ~0x07;              //CSOUTPUT
        LPC_GPIO0->DIR |=(0x01<<6);
        LPC_GPIO0->SET |=(0x01<<6);
       
        LPC_IOCON->P0_12 &= ~0x07;      //MISOINPUT
LPC_GPIO0->DIR &=~(0x01<<12);               
       
        LPC_IOCON->P0_13 &= ~0x07;      //MOSIOUTPUT
        LPC_GPIO0->DIR |=(0x01<<13);
       
LPC_IOCON ->P2_15 &= ~0x07;       //PEINTINPUT
LPC_GPIO2->DIR &=~(0x01<<15);               
       
LPC_IOCON ->P2_14 &= ~0x07;       //BUSYINPUT
LPC_GPIO2->DIR &=~(0x01<<14);                       
/*
        LPC_IOCON->P2_22 &= ~0x07;      //SCLKOUTPUT
        LPC_GPIO2->DIR |=(0x01<<22);
       
        LPC_IOCON->P2_23 &= ~0x07;              //CSOUTPUT
        LPC_GPIO2->DIR |=(0x01<<23);
        LPC_GPIO2->SET |=(0x01<<23);
       
        LPC_IOCON->P2_26 &= ~0x07;      //MISOINPUT
LPC_GPIO2->DIR &=~(0x01<<26);               
       
        LPC_IOCON->P2_27 &= ~0x07;      //MOSIOUTPUT
        LPC_GPIO2->DIR |=(0x01<<27);
       
LPC_IOCON ->P0_16 &= ~0x07;       //PEINTINPUT
LPC_GPIO0->DIR &=~(0x01<<16);               
       
LPC_IOCON ->P0_15 &= ~0x07;       //BUSYINPUT
LPC_GPIO0->DIR &=~(0x01<<15);       
*/
}
/*******************************************************************************
函数名称:uint16_t SPI_WriteRead(uint8_t data)
功    能:向ADS7843/TSC2046发送一个命令字节数据同时读取数据
参    数:无
返回值:读取的坐标数据
********************************************************************************/
uint16_t SPI_WriteRead(uint8_t data)
{
        uint8_ti;
        static uint16_t ret_dat;
       
        data = data|0x80;                        //设置S位
TFT_TOUCH_CS_H;                  //CS=1;
TFT_TOUCH_SCK_L;          //DCLK=0;
TFT_TOUCH_MOSI_L;           //MOSI=0;
        DelayNo(DELAY_200NS);       

TFT_TOUCH_CS_L;                  //CS=0;
        for(i=0;i<8;i++)
        {
                if((data&0x80)!=0) TFT_TOUCH_MOSI_H;               
                else                   TFT_TOUCH_MOSI_L;               

                DelayNo(DELAY_200NS);
    TFT_TOUCH_SCK_H;
                DelayNo(DELAY_200NS);

    TFT_TOUCH_SCK_L;
                data=data<<1;
        }
TFT_TOUCH_MOSI_L;           //MOSI=0;
        DelayNo(DELAY_200NS);
        DelayNo(DELAY_200NS);
        DelayNo(DELAY_200NS);

TFT_TOUCH_SCK_H;
        DelayNo(DELAY_200NS);
TFT_TOUCH_SCK_L;
        ret_dat=0;
        while(TFT_TOUCH_BUSY)//判忙
        {
       TFT_TOUCH_SCK_H;
       DelayNo(DELAY_200NS);   //模拟1个周期的SCK信号
   TFT_TOUCH_SCK_L;       
        }
       
        for(i=0;i<12;i++)
        {
               ret_dat=ret_dat<<1;
                DelayNo(DELAY_200NS);
    TFT_TOUCH_SCK_H;
                if(TFT_TOUCH_MISO!=0)ret_dat=ret_dat|1;
                DelayNo(DELAY_200NS);
    TFT_TOUCH_SCK_L;
                if(i==6)
                {
               DelayNo(DELAY_200NS);
               DelayNo(DELAY_200NS);
                }
        }
        for(i=0;i<3;i++)
        {
                DelayNo(DELAY_200NS);
    TFT_TOUCH_SCK_H;
                DelayNo(DELAY_200NS);
    TFT_TOUCH_SCK_L;
        }
        DelayNo(DELAY_200NS);
TFT_TOUCH_CS_H;                  //CS=1;
               
        return (ret_dat);
}

/*******************************************************************************/


/***********************************TouchConf.c文件*************************************/
#include "GUI.h"
#include "stddef.h"
#include "TouchConf.h"

#ifndef _WINDOWS
#include "LPC177x_8x.h"
#include "Touch_spi.h"
#endif


/*********************************************************************/
extern short TP_X,TP_Y,Pressed_Flag;       
extern short AD_X,AD_Y;
// Touch screen

#define TCS_LOW()             (LPC_GPIO0->CLR |= (0x1<<6))   //TOUCH CSP0.6
#define TCS_HIGH()             (LPC_GPIO0->SET |= (0x1<<6))

#define PEN_State                     (LPC_GPIO2->PIN&(0x1<<15))    //P2.15
#define TOUCH_BUSY       (LPC_GPIO2->PIN&(0x1<<14))

/*
#define TCS_LOW()             (LPC_GPIO2->CLR |= (0x1<<23))   //TOUCH CSP2.23
#define TCS_HIGH()             (LPC_GPIO2->SET |= (0x1<<23))

#define PEN_State                     (LPC_GPIO0->PIN&(0x1<<16))   
#define TOUCH_BUSY       (LPC_GPIO0->PIN&(0x1<<15))
*/
/*********************************************************************
a=Aa=Ba=Ca=Da=Ea=Fa=运算除数
x y 触摸屏坐标    xfb yfb 显示屏坐标
*********************************************************************/
typedef struct {   
      int x, xfb;
      int y, yfb;
      int a;//int占4个字节
} calibration;

calibration cal;
/*********************************************************************
*
*       Global functions for GUI touch
*
**********************************************************************
*/

#if GUI_SUPPORT_TOUCH// Used when touch screen support is enabled

/*********************************************************************
*
*       Touch_Delay
*
*********************************************************************/
void Touch_Delay(void)
{
        uint32_t i;
        for(i=0;i<1000;i++);
}       
/*********************************************************************
* 函数名:Touch_Init()
* 参数:void
* 返回值:void
* 描述:触摸屏初始化
*********************************************************************/
void Touch_Init(uint16_t lcd_xsize,uint16_t lcd_ysize)
{
        /*初始化触摸屏*/
       
        LPC_IOCON->P0_6&= ~0x07;          // P0.6 - TP_CS - used as GPIO
        LPC_GPIO0->DIR |=(0x01<<6);
        LPC_GPIO0->SET |=(0x01<<6);

LPC_IOCON ->P2_15 =0x00;          //P2.15 PENIRQ INPUT
LPC_GPIO2->DIR &=~(0x01<<15);               
       
/*
        LPC_IOCON->P2_23&= ~0x07;          // P2.23 - TP_CS - used as GPIO
        LPC_GPIO2->DIR |=(0x01<<23);
        LPC_GPIO2->SET |=(0x01<<23);

LPC_IOCON ->P0_16 =0x00;          //P0.16 PENIRQ INPUT
LPC_GPIO0->DIR &=~(0x01<<16);       
*/
       
//LPC_GPIOINT->IO2IntEnF|=1<<15;                   //使能GPIO2的15管脚的下降沿中断
/*配置GPIO中断的先占优先级为1,从优先级为1*/
//NVIC_SetPriority(GPIO_IRQn, ((0x01<<3)|0x01));
/*使能GPIO的中断通道*/
//NVIC_EnableIRQ(GPIO_IRQn);
       
        SPI_GPIOInit();
}
/*********************************************************************
* Function Name: Touch_ReadAdXY
* Description    : 读取ADS7843/TSC2046通道X+ 通道Y+的ADC值
* Input          : None
* Output         : None
* Return         : ADS7843/TSC2046 返回 通道X+ 通道Y+的ADC值
* Attention               : None
*********************************************************************/
void Touch_ReadAdXY(int *x,int *y)
{
int adx=0,ady=0;
       
        adx = SPI_WriteRead(TOUCH_CHX);   //读取X坐标指令
        ady = SPI_WriteRead(TOUCH_CHY);   //读取Y坐标指令
*x=adx;
*y=ady;
}
/*********************************************************************
函 数 名:unsigned short Softfilter(int (*dat))
功    能:数据滤波
说    明:无
入口参数:(*dat)
返 回 值:无
设    计:zhou feng         日    期:2012-09-10
修    改:                  日    期:
*********************************************************************/
unsigned short Softfilter(int (*dat))
{
unsigned int dbt,tmpx =0xFFF;
        signed   int m0,m1,m2;

/******************降序排列************************
        for(m0=0;m0<13;m0++)   
        {
                for(m1=0;m1<13;m1++)
                {
                        if(dat<dat)   
                        {
                                m2         = dat;
                                dat   = dat;
                                dat = m2;
                        }
                }
        }
*******************升序排列***********************/       
        for(m0=0;m0<(13-1);m0++)   
        {
                for(m1=m0+1;m1<13;m1++)
                {
                        if(dat>dat)   
                        {
                                m2         = dat;
                                dat   = dat;
                                dat   = m2;
                        }
                }
        }
/*************************************************/
dbt = (dat+ dat+dat)/3;//取中间9个有效数据,分3组取平均
        dbt = (dat+ dat+dat)/3;
        dbt = (dat+ dat+dat)/3;

        m0 = dbt-dbt;
        m1 = dbt-dbt;
        m2 = dbt-dbt;
       
        m0 = m0>0?m0:(-m0);
        m1 = m1>0?m1:(-m1);
        m2 = m2>0?m2:(-m2);
/*************************************************/
        if(m0<THRESHOLD && m1<THRESHOLD && m2<THRESHOLD)   //调节数据跳变量门限值
        {
                if(m0<m1)
          {
               if(m2<m0)
               {
                       tmpx = (dbt+dbt)/2;
               }
               else
               {
                        tmpx = (dbt+dbt)/2;
               }
          }
                else if(m2<m1)
                {
               tmpx = (dbt+dbt)/2;
                }
                else
                {
           tmpx = (dbt+dbt)/2;
                }
        }
        else
        {
                tmpx = 0xFFF;
        }
       
        return (unsigned short)tmpx;
}
/*********************************************************************
函 数 名:Coordinate * Read_ADS7846_Filter(void)
功    能:读取触摸数据(带滤波处理)
说    明:无
入口参数:无
返 回 值:无
设    计:zhou feng         日    期:2012-09-10
修    改:                  日    期:
*********************************************************************/
Coordinate * Read_ADS7846_Filter(void)
{
static Coordinatescreen;       
        unsigned char t=0,count=0;
        intdatabuffer={{5,7,9,3,2,6,4,0,3,0,0,0,0},{5,7,9,3,2,6,4,0,3,0,0,0,0}};

do{               
          DelayNo(200);
                  DelayNo(200);
                                               
      if(!PEN_State)        //触摸按下
                        {
             databuffer = SPI_WriteRead(TOUCH_CHX);   //读取X坐标指令
             databuffer = SPI_WriteRead(TOUCH_CHY);   //读取Y坐标指令                               
       count++;                                
                        }
          }while(!PEN_State && count<13);

screen.x = 0;
screen.y = 0;
        if(count == 13)
        {
                screen.x = Softfilter(&databuffer);    //连续13组X数据滤波处理
                screen.y = Softfilter(&databuffer);        //连续13组Y数据滤波处理               
    if(screen.x==0xFFF || screen.y==0xFFF)        return 0;       
          else                                    return &screen;
}
return 0;   //没有触摸压下
}       
/*********************************************************************
*
*       GUI_TOUCH_X_ActivateX()
*
* Function decription:
*   Called from GUI, if touch support is enabled.
*   Switches on voltage on X-axis,
*   prepares measurement for Y-axis.
*   Voltage on Y-axis is switched off.
*/
//void GUI_TOUCH_X_ActivateX(void)
//{
//}
/*********************************************************************
*
*       GUI_TOUCH_X_ActivateY()
*
* Function decription:
*   Called from GUI, if touch support is enabled.
*   Switches on voltage on Y-axis,
*   prepares measurement for X-axis.
*   Voltage on X-axis is switched off.
*/
//void GUI_TOUCH_X_ActivateY(void)
//{
//}
/*********************************************************************
*
*       GUI_TOUCH_X_MeasureX()
*
* Function decription:
*   Called from GUI, if touch support is enabled.
*   Measures voltage of X-axis.
*/
//intGUI_TOUCH_X_MeasureX(void)
//{
// return 0;//_TouchX;
//}

/*********************************************************************
*
*       GUI_TOUCH_X_MeasureY()
*
* Function decription:
*   Called from GUI, if touch support is enabled.
*   Measures voltage of Y-axis.
*/
//intGUI_TOUCH_X_MeasureY(void)
//{
//return 0;//_TouchY;
//}
/*********************************************************************
* 函数名:int perform_calibration(calibration *cal)
* 参数:void
* 返回值:void
* 描述:五点触摸校准算法
*********************************************************************/
int perform_calibration(calibration *cal)
{
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;
       y += (float)cal->y;
       x2 += (float)(cal->x*cal->x);
       y2 += (float)(cal->y*cal->y);
       xy += (float)(cal->x*cal->y);
        }

//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;
       zx += (float)(cal->xfb*cal->x);
       zy += (float)(cal->xfb*cal->y);
        }

// Now multiply out to get the calibration for framebuffer x coord
        cal->a = (int)((a*z + b*zx + c*zy)*(scaling));
        cal->a = (int)((b*z + e*zx + f*zy)*(scaling));
        cal->a = (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;
       zx += (float)(cal->yfb*cal->x);
       zy += (float)(cal->yfb*cal->y);
        }

// Now multiply out to get the calibration for framebuffer y coord
        cal->a = (int)((a*z + b*zx + c*zy)*(scaling));
        cal->a = (int)((b*z + e*zx + f*zy)*(scaling));
        cal->a = (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 and return
        cal->a = (int)scaling;
        return 1;
}
/********************************************************************/
typedef struct
{
int Min;
int Max;
} tMinMax;
extern tMinMax xyMinMax;

extern int CalibrationComplete;
int ax_Phys,ay_Phys;

/*********************************************************************
* 函数名:void _ExecCalibration( int x_size, int y_size )
* 参数:void
* 返回值:void
* 描述:触摸自校准(五点校准)
*********************************************************************/
void _ExecCalibration( int x_size, int y_size )   //x_size=X尺寸y_size=Y尺寸
{
/* calculate log. Positions */
int ax, ay;
Coordinate *p;
       
ax = 20;             ay = 20;          //(20,20)               左上
ax = x_size -20;   ay = 20;          //(x_size-20,20)      右上
ax = x_size -20;   ay = y_size-20;   //(x_size-20,y_size-20) 右下
ax = 20;             ay = y_size-20;   //(20,y_size-20)      左下
ax = x_size/2;       ay = y_size/2;    //(x_size/2,y_size/2)   中心

CalibrationComplete = 0;       //标志清0
GUI_TOUCH_SetDefaultCalibration();//设置默认的校准参数(GUI)
        /*----------------左上------------------------*/
/* _Calibrate upper left */
GUI_SetFont(&GUI_Font13_ASCII);

GUI_SetBkColor(GUI_BLUE);
GUI_Clear();
GUI_SetColor(GUI_WHITE);   GUI_FillCircle(ax, ay, 10);
GUI_SetColor(GUI_BLUE);    GUI_FillCircle(ax, ay, 5);
GUI_SetColor(GUI_WHITE);
GUI_DispStringAt("Press here", ax+20, ay);
do{
                p = Read_ADS7846_Filter();    //触摸屏按下扫描
    if (p!=(void*)0)   
                {
   cal.xfb = 20;//LCD坐标
   cal.yfb = 20;
   cal.x = p->x;//TOUCH坐标
   cal.y = p->y;
   break;
    }
    GUI_Delay (10);
} while (1);
GUI_SetColor(GUI_RED);    GUI_FillCircle(ax, ay, 5);
GUI_SetColor(GUI_WHITE);       
        while(!PEN_State);/* 等待触摸放开 */       
GUI_Clear();
GUI_DispStringAt("OK", ax+20, ay);
       
        /*----------------右上------------------------*/
GUI_Delay (1000);
GUI_SetBkColor(GUI_BLUE);
GUI_Clear();
GUI_SetColor(GUI_WHITE);GUI_FillCircle(ax, ay, 10);
GUI_SetColor(GUI_BLUE);   GUI_FillCircle(ax, ay, 5);
GUI_SetColor(GUI_WHITE);
GUI_SetTextAlign(GUI_TA_RIGHT);   //文本右对齐
GUI_DispStringAt("Press here", ax-20, ay);
do {
                p = Read_ADS7846_Filter();    //触摸屏按下扫描
    if (p!=(void*)0)
                {
   cal.xfb = x_size-20;
   cal.yfb = 20;
   cal.x = p->x ;
   cal.y = p->y;
   break;
    }
    GUI_Delay (10);
} while (1);
GUI_SetColor(GUI_RED);   GUI_FillCircle(ax, ay, 5);
        GUI_SetColor(GUI_WHITE);
        while(!PEN_State);/* 等待触摸放开 */       
GUI_Clear();
GUI_DispStringAt("OK", ax-20, ay);
       
        /*----------------右下------------------------*/
        GUI_Delay (1000);
GUI_Clear();
GUI_SetColor(GUI_WHITE);GUI_FillCircle(ax, ay, 10);
GUI_SetColor(GUI_BLUE);   GUI_FillCircle(ax, ay, 5);
GUI_SetColor(GUI_WHITE);
GUI_SetTextAlign(GUI_TA_RIGHT);   //文本右对齐
GUI_DispStringAt("Press here", ax-20, ay);
do {
                p = Read_ADS7846_Filter();    //触摸屏按下扫描
    if (p!=(void*)0)
                {
   cal.xfb = x_size -20;
   cal.yfb = y_size -20;
   cal.x = p->x;
   cal.y = p->y;
   break;         
    }
    GUI_Delay (10);
} while (1);
GUI_SetColor(GUI_RED);   GUI_FillCircle(ax, ay, 5);       
        GUI_SetColor(GUI_WHITE);
        while(!PEN_State);/* 等待触摸放开 */       
GUI_Clear();
GUI_DispStringAt("OK", ax-20, ay);

        /*----------------左下------------------------*/       
        GUI_Delay (1000);
GUI_Clear();
GUI_SetColor(GUI_WHITE);GUI_FillCircle(ax, ay, 10);
GUI_SetColor(GUI_BLUE);   GUI_FillCircle(ax, ay, 5);
GUI_SetColor(GUI_WHITE);
//GUI_SetTextAlign(GUI_TA_RIGHT);
GUI_SetTextAlign(GUI_TA_LEFT);   //文本左对齐
GUI_DispStringAt("Press here", ax+20, ay);
do {
                p = Read_ADS7846_Filter();    //触摸屏按下扫描
    if (p!=(void*)0)
                {
   cal.xfb = 20;
   cal.yfb = y_size -20;
   cal.x = p->x ;
   cal.y = p->y ;
   break;
    }
    GUI_Delay (10);
} while (1);
GUI_SetColor(GUI_RED);   GUI_FillCircle(ax, ay, 5);       
        GUI_SetColor(GUI_WHITE);
        while(!PEN_State);/* 等待触摸放开 */
GUI_Clear();
GUI_DispStringAt("OK", ax+20, ay);

        /*----------------中心------------------------*/               
        GUI_Delay (1000);
GUI_Clear();
GUI_SetColor(GUI_WHITE);GUI_FillCircle(ax, ay, 10);
GUI_SetColor(GUI_BLUE);   GUI_FillCircle(ax, ay, 5);
GUI_SetColor(GUI_WHITE);
GUI_SetTextAlign(GUI_TA_LEFT);//文本左对齐
GUI_DispStringAt("Press here", ax+20, ay);
do {
                p = Read_ADS7846_Filter();    //触摸屏按下扫描
    if (p!=(void*)0)
                {
   cal.xfb = x_size/2;
   cal.yfb = y_size/2;
   cal.x = p->x ;
   cal.y = p->y ;
   break;
    }
    GUI_Delay (10);
} while (1);
GUI_SetColor(GUI_RED);   GUI_FillCircle(ax, ay, 5);       
        GUI_SetColor(GUI_WHITE);
        while(!PEN_State);/* 等待触摸放开 */       
GUI_Clear();
GUI_DispStringAt("OK", ax+20, ay);       
        /*-----------------------------------------------------*/       
/* calculate and display values for configuration file */
        /*-----------------------------------------------------*/               
{
          GUI_Delay (1000);               
    GUI_Clear();
    GUI_DispString("x0: ");        GUI_DispDec(cal.x, 4);           //显示(左上)坐标数
          GUI_DispString("y0: ");        GUI_DispDec(cal.y, 4); GUI_DispNextLine();


    GUI_DispString("x1: ");        GUI_DispDec(cal.x, 4);    //显示(右上)坐标数
    GUI_DispString("y1: ");        GUI_DispDec(cal.y, 4);        GUI_DispNextLine();

    GUI_DispString("x2: ");        GUI_DispDec(cal.x, 4);    //显示(右下)坐标数
    GUI_DispString("y2: ");        GUI_DispDec(cal.y, 4);        GUI_DispNextLine();

    GUI_DispString("x3: ");        GUI_DispDec(cal.x, 4);    //显示(左下)坐标数
    GUI_DispString("y3: ");        GUI_DispDec(cal.y, 4);        GUI_DispNextLine();

    GUI_DispString("x4: ");        GUI_DispDec(cal.x, 4);    //显示(中心)坐标数
    GUI_DispString("y4: ");        GUI_DispDec(cal.y, 4);        GUI_DispNextLine();
               
    GUI_DispString("Please touch display to continue...");
          /*-------------------------------------*/                       
    GUI_Delay(1000);
    do {
                p = Read_ADS7846_Filter();    //触摸屏按下扫描
    if (p!=(void*)0)
      break;
      GUI_Delay (10);
    } while (1);
}
        while(!PEN_State);/* 等待触摸放开 */
        /*-----------------------------------------------------*/               
        CalibrationComplete = 1;   //标志置1
perform_calibration(&cal);   //触摸校准算法(得到校准参数)
}

/*********************************************************************
* 函数名:shortCalibrate_X(unsignedint ad_x,unsigned int ad_y)
* 参数:void
* 返回值:short
* 描述:X坐标转化
*********************************************************************/
shortCalibrate_X(unsignedint ad_x,unsigned int ad_y)
{
int   temp;    //4byte
        short value;   //2byte
       
temp=(int)((ad_x*cal.a+ad_y*cal.a+cal.a)/cal.a);
        value =(short)temp;

return value;
}
/*********************************************************************
* 函数名:shortCalibrate_Y(unsignedint ad_x,unsigned int ad_y)
* 参数:void
* 返回值:short
* 描述:Y坐标转化
*********************************************************************/
shortCalibrate_Y(unsignedint ad_x,unsigned int ad_y)
{
int   temp;    //4byte
        short value;   //2byte
       
temp =(int)((ad_x*cal.a+ad_y*cal.a+cal.a)/cal.a);
        value =(short)temp;
       
return value;
}
/*********************************************************************
* 函数名:void TouchTask( int x_size, int y_size )
* 参数:void
* 返回值:void
* 描述:触摸屏扫描(10ms)
*********************************************************************/
void TouchTask( int x_size, int y_size )
{
static uint16_t xOld;
static uint16_t yOld;
static uint8_tPressedOld;
short x=0, y=0, xDiff=0, yDiff=0;
Coordinate* p;

        p = Read_ADS7846_Filter();    //触摸屏按下扫描
/*****************触摸按下(有效数据)*************************/
/*** Touch screen is pressed ***/
if (p!=(void *)0)   
        {
       Pressed_Flag = 1;    //触摸按下
       AD_X = p->x;      //X坐标AD值
       AD_Y = p->y;      //Y坐标AD值
       /*-----------LCD坐标值转换--------------*/       
   x = Calibrate_X(p->x ,p->y );// TBD: Insert function which reads current x value
   y = Calibrate_Y(p->x ,p->y );// TBD: Insert function which reads current y value
       /*----------逻辑坐标容错处理------------*/          
       if(x<0)                   x = 0;
       else if(x>x_size)       x = x_size;
       if(y<0)                   y = 0;
       else if(y>y_size)       y = y_size;               
   /*** The touch has already been pressed ***/
   if(PressedOld == 1)   //触摸(上一次)已经按下
       {
    //Calculate difference between new and old position
   xDiff = (x > xOld) ? (x - xOld) : (xOld - x);//计算出前后两次按下的X坐标差值
   yDiff = (y > yOld) ? (y - yOld) : (yOld - y);//计算出前后两次按下的Y坐标差值
    // Store state if new position differs significantly from old position
    if(xDiff + yDiff > 2)//消抖处理
                {
   xOld = x;
   yOld = y;
   TP_X = x;
               TP_Y = y;                       
   GUI_TOUCH_StoreState(x, y);       
    }
   }
   /*** The touch was previously released ***/
   // Store state regardless position
   else       //触摸(上一次)未按下
       {
    //if((x != 0) && (y != 0))
                //{
   xOld = x;
   yOld = y;
   TP_X = x;
               TP_Y = y;                               
   PressedOld = 1;
   GUI_TOUCH_StoreState(x, y);
    //}
   }
   /*** Touch screen is not pressed ***/
   // Store state if it was released recently
}
/**********************无触摸按下****************************/       
        else if(PEN_State)/* 触摸中断线高电平 */       
        {
       Pressed_Flag = 0;    //触摸未按下       
   if(PressedOld == 1)
       {
    PressedOld = 0;
    GUI_TOUCH_StoreState(-1, -1);
   }
}
/*****************触摸按下(无效野点)*************************/       
        else
        {
   /* 无效数据,不做处理*/
}       
/************************************************************/               
//GUI_X_Delay(20);
}
/*******************************************************************************************/
#endif// GUI_SUPPORT_TOUCH



/****************************************main.c文件*******************************************/

/*************************************************************************
* Function Name: GLCD_Init
* Parameters: const unsigned long *pPain, const unsigned long * pPallete
*
* Return: none
*
* Description: GLCD controller init
*
*************************************************************************/
void GLCD_Init (void)
{
        // Assign pins   
        g_pIOCON->P2_9         = 0x06;        // VD3,         R0//RGB(565)
        g_pIOCON->P2_6         = 0x07;        // VD4,                R1
        g_pIOCON->P2_7         = 0x07;        // VD5,                R2
        g_pIOCON->P4_28        = 0x05;        // VD6,                R3
        g_pIOCON->P4_29 = 0x05;        // VD7,                R4

        g_pIOCON->P1_20        = 0x07;        // VD10,        G0
        g_pIOCON->P1_21        = 0x07;        // VD11,        G1
        g_pIOCON->P1_22        = 0x07;        // VD12,        G2
        g_pIOCON->P1_23        = 0x07;        // VD13,        G3
        g_pIOCON->P1_24        = 0x07;        // VD14,        G4
        g_pIOCON->P1_25        = 0x07;        // VD15,        G5
       
        g_pIOCON->P2_13        = 0x07;        // VD19,        B0
        g_pIOCON->P1_26 = 0x07;        // VD20,        B1
        g_pIOCON->P1_27 = 0x07;        // VD21,        B2
        g_pIOCON->P1_28 = 0x07;        // VD22,        B3
        g_pIOCON->P1_29 = 0x07;        // VD23,        B4
       
        g_pIOCON->P2_2        = 0x07;        // DCLK
        g_pIOCON->P2_0        = 0x07;        // DSIP(power)
        g_pIOCON->P2_5        = 0x07;        // HSYNC
        g_pIOCON->P2_3        = 0x07;        // VSYNC
        g_pIOCON->P2_4        = 0x07;        // DataEn(LCD_ENAB_M)

        g_pIOCON->P2_1        = 0x00;        // Backlight(P21)
       
        // >>> debug >>>

        // <<< debug <<<
       
        /*Back light enable*/
        LPC_GPIO2->DIR = (1<<1);//P2.1设置为输出
        LPC_GPIO2->SET= (5<<1);   //背光高电平(点亮)

        //Turn on LCD clock
        LPC_SC->PCONP |= 1<<0;
       
        // Disable cursor
        g_pLCD->CRSR_CTRL &=~(1<<0);
       
        // disable GLCD controller       
        g_pLCD->CTRL = 0;       //LCD失能
       
        g_pLCD->CTRL &= ~(0x07 <<1);//LcdBpp 每像素LCD位 000=1bpp
        // RGB565
        g_pLCD->CTRL |= (6<<1);//RGB(565) 110=16bpp

       
        // TFT panel
        g_pLCD->CTRL |= (1<<5);    //LcdTFT=1TFT类型
        // single panel
        g_pLCD->CTRL &= ~(1<<7);   //LcdDual=0 LCD单面板
        // notmal output
        g_pLCD->CTRL &= ~(1<<8);   //RGB格式
        // little endian byte order
        g_pLCD->CTRL &= ~(1<<9);   //小端字节序
        // little endian pix order
        g_pLCD->CTRL &= ~(1<<10);
        // disable power
        g_pLCD->CTRL &= ~(1<<11);//LCD功率失能
        /*-------------------------------------------*/
        /*-------------------------------------------*/       
        // init pixel clock
        g_pSC->LCD_CFG = PeripheralClock / ((unsigned long) C_GLCD_PIX_CLK);   //LCD刷新率8M左右
        // bypass inrenal clk divider
        g_pLCD->POL |=(1<<26);    //旁路像素时钟分频器逻辑
        // clock source for the LCD block is HCLK
        g_pLCD->POL &= ~(1<<5);   //LCD时钟源为内部CCLK
        // LCDFP pin is active LOW and inactive HIGH
        g_pLCD->POL |= (1<<11);
        // LCDLP pin is active LOW and inactive HIGH
        g_pLCD->POL |= (1<<12);
        // data is driven out into the LCD on the falling edge
        g_pLCD->POL &= ~(1<<13);
        // active high
        g_pLCD->POL &= ~(1<<14);
        g_pLCD->POL &= ~(0x3FF <<16);
        g_pLCD->POL |= (C_GLCD_H_SIZE-1)<<16;//每线时钟(每行像素PPL=480)
       
        // init Horizontal Timing水平时序寄存器
        g_pLCD->TIMH = 0; //reset TIMH before set value
        g_pLCD->TIMH |= (C_GLCD_H_BACK_PORCH - 1)<<24;   //水平后沿
        g_pLCD->TIMH |= (C_GLCD_H_FRONT_PORCH - 1)<<16;//水平前沿
        g_pLCD->TIMH |= (C_GLCD_H_PULSE - 1)<<8;         //水平同步脉冲宽度
        g_pLCD->TIMH |= ((C_GLCD_H_SIZE/16) - 1)<<2;   //每行像素
       
        // init Vertical Timing垂直时序寄存器
        g_pLCD->TIMV = 0;//reset TIMV value before setting
        g_pLCD->TIMV |= (C_GLCD_V_BACK_PORCH)<<24;       //垂直后沿
        g_pLCD->TIMV |= (C_GLCD_V_FRONT_PORCH)<<16;      //垂直前沿
        g_pLCD->TIMV |= (C_GLCD_V_PULSE - 1)<<10;      //垂直同步脉冲宽度
        g_pLCD->TIMV |= C_GLCD_V_SIZE - 1;               //每面板线数
        // Frame Base Address doubleword aligned
        g_pLCD->UPBASE = LCD_VRAM_BASE_ADDR & ~7UL ;   //上面板帧基址寄存器 (低三位地址屏蔽) 注:UL = unsigned long(确定当前数值类型)
        g_pLCD->LPBASE = LCD_VRAM_BASE_ADDR & ~7UL ;   //下面板帧基址寄存器 (低三位地址屏蔽) 注:UL = unsigned long(确定当前数值类型)
        /*-------------------------------------------*/
        /*-------------------------------------------*/
}       

/*************************************************************************
* Function Name: GLCD_SetPallet
* Parameters: const unsigned long * pPallete
*
* Return: none
*
* Description: GLCD init colour pallete
*
*************************************************************************/
void GLCD_SetPallet (const unsigned long * pPallete)
{
        unsigned long i;
        unsigned long * pDst = (unsigned long *)g_pLCD->PAL;//彩色调色板寄存器
        // assert(pPallete);
        for (i = 0; i < 128; i++)//128个位置
        {
       *pDst++ = *pPallete++;
        }
}

/*************************************************************************
* Function Name: GLCD_Ctrl
* Parameters: Bool bEna
* < Bool = unsigned long >
* Return: none
*
* Description: GLCD enable disabe sequence
*
*************************************************************************/
void GLCD_Ctrl (Bool bEna)
{
        volatile unsigned long i;
if (bEna)
{
    /*LCD_CTRL_bit.LcdEn = 1;*/
    g_pLCD->CTRL |= (1<<0);       //LCD使能
    for(i = C_GLCD_PWR_ENA_DIS_DLY; i; i--);
    /*LCD_CTRL_bit.LcdPwr= 1;*/   //enable power
    g_pLCD->CTRL |= (1<<11);
}
else
{
    /*LCD_CTRL_bit.LcdPwr= 0;*/// disable power
    g_pLCD->CTRL &= ~(1<<11);
    for(i = C_GLCD_PWR_ENA_DIS_DLY; i; i--);
    /*LCD_CTRL_bit.LcdEn = 0;*/
    g_pLCD->CTRL &= ~(1<<0);   //LCD失能
}
}


/*****************************************************************************/
typedef        struct POINT
{
uint16_t x;
uint16_t y;
}Coordinate;
/*****************************************************************************/
Coordinate* ptouch;
GUI_PID_STATE Touch_State;   
int TT_buffer;
/******************************************************************************
**   Main Functionmain()
主频率为84MHz    EMC频率为84MHz   USB频率为48MHz
******************************************************************************/
int main (void)
{

HW_X_Config();      //硬件初始化
SystemInit();         //系统初始化设置
SDRAM_Init();         //SDRAM初始化
GLCD_Init ();         //LCD驱动函数
GLCD_Ctrl (1);      //LCD使能(把这条指令加上后TFT工作,但是触摸读取数据就跳变很厉害了)
Touch_Init(480,272);//触摸驱动

while(1)
{
    ptouch = Read_ADS7846_Filter();    //触摸按键扫描
    if (ptouch!=(void *)0)    //触摸按下
        {               
       TT_buffer=ptouch->x;
       TT_buffer=ptouch->y;
        }
        else                     //无触摸按键
        {
       TT_buffer=0;
       TT_buffer=0;               
        }
    i++;if(i>31) i=0;
        delayMs(0,10);
}
}


页: [1]
查看完整版本: 请求帮助:SK-LPC1788开发板触摸屏受4.3寸TFT(480*272)干扰