搜索
bottom↓
回复: 300

触摸屏控制方法,个人总结(欢迎拍砖,但不要打脸)

  [复制链接]

出0入0汤圆

发表于 2011-10-18 21:56:36 | 显示全部楼层 |阅读模式
最近几天研究了下触摸屏,发现也并不像感觉中的那么神秘。

本人用的触摸屏方案是 4线电阻屏+xpt2046(这个和ADS7843完全一样)。

控制过程主要分一下几步:

1,读数——这里读出来的是触摸屏控制芯片的AD值,是屏的物理坐标
2,滤波——触摸屏类似按键,按下和放开时会有抖动
3,转化——把屏的物理坐标转化成逻辑坐标,这里的逻辑坐标在LCD的范围内对应LCD的像素点坐标。
4,定位——触摸屏的定位,这个其实应该放到最开始。

读数:

这里按照控制芯片的时序使用管脚模拟SPI的方式读出来的,用过STM32的SPI,也可以,不过习惯模拟,不用那么复杂的配置了。
(程序见后面部分)

滤波:

这里使用了2种方式的滤波,一种是像按键一样,检测到控制芯片INT引脚变低之后,延时20ms,然后如果在检测还是为低,则是真正的按下。
第二种是软件滤波,程序读取了10次触摸屏的物理坐标,然后冒泡排序,最后去掉最前面的和最后面的,只保留中间3个,再对中间3个取平均。
(程序见后面部分)

转化:

这个很简单,在任何一个介绍触摸屏的文章估计都能见到。
xp——x的物理坐标  xl—— x的逻辑坐标  LCDXSIZE ——LCD的x方向做大值   xpmin —— 在LCD(0,0)坐标处的x的物理坐标 xpmax LCD最大处x物理坐标
yp——y的物理坐标  yl—— y的逻辑坐标  LCDYSIZE ——LCD的y方向最大值   ypmin —— 在LCD(0,0)坐标处的y的物理坐标 ypmax LCD最大处y物理坐标

xl = (xp-xpmin)*LCDXSIZE/(xpmax-xpmin)
yl = (yp-ypmin)*LCDYSIZE/(ypmax-ypmin)

定位:

这里定位的作用是求处上面的xpmin,xpmax,ypmin和ypmax,方法就是在屏幕上知道2点,求这两点所在直线上的一点(而且知道要求点的某一个坐标)
在屏上分别画出4个点,其实3个点足以,但是一般都用4个点,取得这四个点的物理坐标。假设分别为:
          |                        |
       --x1,y1-------------------x2,y2----
          |                        |
       --x3,y3-------------------x4,y4----
          |                        |
对应的物理坐标为 cx1,cy1     cx2,cy2,    cx3,cy3    cx4,cy4

利用比例关系                   x1/(cx1-xpmin)   =  x2/(cx2-xpmin)    —————————————— 这里x1和x2不相等
可以求出xpmin,同样用比例关系   x2/(cx2-xpmin)   =  LCDXSIZE/(xpmax-xpmin)———————————— 这里最好x2>x1,更准些
可以求出xpmax

然后用同样的方法求出ypmin和ypmax
_____________________________________________________分割线__________________________________________________________________
————————————————————————————————————————————————————————————————
用中断读控制芯片的INT引脚还是用定时器读?

用中断比较节省资源,但是我在做一个画图板的时候,发现滑动坐标没办法求出来,于是就去想定时器读。
用定时器读有个好处:延时操作可以在定时器里设置一个标志字,然后如果有按下就置位这个标志,下次再去真正读取。
                    定时器里可以给触摸屏设置多种不同的状态,这里按照Windows的情况设置了down,move,up还有none4种状态
这样用定时器解决了一个消抖和滑动坐标检测的问题,我选择定时器。

无图无真相,无码无真相:下面是真相


(原文件名:touch.jpg)

头文件::
#ifndef __TOUCH_H__
#define __TOUCH_H__

#include "stm32f10x_lib.h"

enum
{
    TOUCH_NONE=0,             //
    TOUCH_DOWN,
    TOUCH_MOVE,
    TOUCH_UP,
};


#define TOUCH_CLK_LOW()     GPIO_ResetBits(GPIOB, GPIO_Pin_13)
#define TOUCH_CLK_HIGH()    GPIO_SetBits(GPIOB, GPIO_Pin_13)
#define TOUCH_DOUT_LOW()    GPIO_ResetBits(GPIOB, GPIO_Pin_15)
#define TOUCH_DOUT_HIGH()   GPIO_SetBits(GPIOB, GPIO_Pin_15)

#define TOUCH_READ_DIN()    GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)

#define TOUCH_CS_LOW()     GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define TOUCH_CS_HIGH()    GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define TOUCH_READ_INT()   GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_7)
#define TOUCH_READ_BUSY()  GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_8)

#define TOUCH_CHX   0x90                //差分方式读取
#define TOUCH_CHY   0xD0
#define TOUCH_GETTIMES  10

extern vu16 TouchX, TouchY;
extern vu8 TouchPress,TouchState;
extern u8 TouchCalibrated;

void Touch_Init(void);
u16 Touch_GetX(void);
u16 Touch_GetY(void);
void Touch_Calibrate(void);
void Touch_GetState(void);

#endif


C文件::
#include "Touch.h"
#include "systick.h"
#include "Graphics.h"


vu16 TouchX, TouchY;
vu8 TouchPress=0, TouchState=TOUCH_NONE; //state有4种状态,0无按键,1按下,2抬起,3move
u8 TouchCalibrated = 0;

u16 TouchXMin, TouchXMax, TouchYMin, TouchYMax;
/********************************
初始化触摸屏需要的端口
芯片--TSC2046
********************************/
void Touch_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    //EXTI_InitTypeDef EXTI_InitStructure;
    //NVIC_InitTypeDef NVIC_InitStructure;
    //SPI_InitTypeDef  SPI_InitStructure;
     
    /* Enable GPIOB, GPIOC and AFIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOG|RCC_APB2Periph_AFIO, ENABLE);  //RCC_APB2Periph_AFIO
    //RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    //SPI
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    //SPI_MISO
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

        /* CS pins configuration */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /*INI Pin*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOG, &GPIO_InitStructure);
/*   
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                      //时钟空闲为低
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                    //上升沿所存
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
    SPI_Init(SPI2, &SPI_InitStructure);
    SPI_Cmd(SPI2,ENABLE);  */
#if 0
    EXTI_ClearITPendingBit(EXTI_Line7);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOG, GPIO_PinSource7);  

    /* Configure Button EXTI line */
    EXTI_InitStructure.EXTI_Line = EXTI_Line7;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
#endif

}

/*=====================================================================*/
u16 Touch_AdjY(u16 adx) //240
{
  u16 sx=0;
  int r = adx - TouchYMin;
  r *= 240;
  sx=r / (TouchYMax - TouchYMin);
  if (sx>=240)
    return 0xFFFF;
  return sx;
}


u16 Touch_AdjX(u16 ady) //320
{
  u16 sy=0;
  int r = ady - TouchXMin;
  r *= 320;
  sy=r/(TouchXMax - TouchXMin);
  if (sy>=320)
    return 0xFFFF;
  return sy;
}


u16 Touch_Read(u8 cmd)
{
    u8 i;
    u16 pos=0;

    TOUCH_CLK_LOW();
    TOUCH_CS_LOW();
    for(i=0; i<8; i++)
    {
        if(cmd&0x80) TOUCH_DOUT_HIGH();
        else TOUCH_DOUT_LOW();
        cmd <<= 1;
        TOUCH_CLK_HIGH();
        TOUCH_CLK_LOW();
    }
    Delay(50);
    for(i=0; i<12 ;i++)
    {
       pos <<= 1;
       TOUCH_CLK_HIGH();
       if(TOUCH_READ_DIN() == Bit_SET)
        pos |= 0x01;
       TOUCH_CLK_LOW();
    }
    TOUCH_CS_HIGH();

    return pos;
}

u16 Touch_GetX(void)
{
    u8 count=0, i,j;
    u16 pos[TOUCH_GETTIMES]={0};
    u16 res=0xffff, temp;

    while((count<TOUCH_GETTIMES)&&(TOUCH_READ_INT() == Bit_RESET))
    {
        count++;
        //TOUCH_CS_LOW();                                           //选中器件
        //SPI_I2S_SendData(SPI2,TOUCH_CHX);                           //
        //while(TOUCH_READ_BUSY() == Bit_SET);                      //等待busy信号
        //pos[count] = (u8 )SPI_I2S_ReceiveData(SPI2);
        //TOUCH_CS_HIGH();
        pos[count] = Touch_Read(TOUCH_CHX);
    }
    if(count < TOUCH_GETTIMES)                                                  //干扰,丢弃
        return res;
    for(i=0; i<TOUCH_GETTIMES-1; i++)
    {
        for(j=0; j<TOUCH_GETTIMES-i-1; j++)  
        {
            if(pos[j]>pos[j+1])
            {
                temp = pos[j];
                pos[j] = pos[j+1];
                pos[j+1] = temp;
            }
        }
    }
   
    res = (pos[TOUCH_GETTIMES/2-1]+pos[TOUCH_GETTIMES/2]+pos[TOUCH_GETTIMES/2+1])/3;
    if(TouchCalibrated==1) //已经校准过了,否则这里只输出物理值
        res = Touch_AdjX(res);
                           
    return res;   
}

u16 Touch_GetY(void)
{
    u8 count=0, i,j;
    u16 pos[TOUCH_GETTIMES]={0};
    u16 res = 0xffff, temp;

    while((count<TOUCH_GETTIMES)&&(TOUCH_READ_INT() == Bit_RESET))
    {
        count++;
       // TOUCH_CS_LOW();                                           //选中器件
        //SPI_I2S_SendData(SPI2,TOUCH_CHY);                           //
        //while(TOUCH_READ_BUSY() == Bit_SET);                      //等待busy信号
        //pos[count] = (u8 )SPI_I2S_ReceiveData(SPI2);  
        //TOUCH_CS_HIGH();  
        pos[count] = Touch_Read(TOUCH_CHY);
    }
    if(count < TOUCH_GETTIMES)                                                  //干扰,丢弃
        return 0xffff;
    for(i=0; i<TOUCH_GETTIMES-1; i++)
    {
        for(j=0; j<TOUCH_GETTIMES-i-1; j++)  
        {
            if(pos[j]>pos[j+1])
            {
                temp = pos[j];
                pos[j] = pos[j+1];
                pos[j+1] = temp;
            }
        }
    }
   
    res = (pos[TOUCH_GETTIMES/2-1]+pos[TOUCH_GETTIMES/2]+pos[TOUCH_GETTIMES/2+1])/3;
    if(TouchCalibrated==1) //已经校准过了,否则这里只输出物理值
        res = Touch_AdjY(res);

    return res;
}


void Touch_Calibrate(void)
{
  u16 x[4] = {30, 290, 30, 290};
  u16 y[4] = {20, 20, 220, 220};
  u16 cx[4],cy[4], tempx[2], tempy[2];
  u8 i;
  u16 color;
   
  //画出需要的点,然后点击  
  TouchXMin = 0;
  TouchYMin = 0;

  color = GetColor();
  SetColor(BLUE);
  ClearDevice();
  
  while(TRUE)
  {
    for(i=0; i<4; i++)                  //画出5个点,点击后记录标志值
    {
        SetColor(RED);
        FillCircle(x,y,3);
        while((TouchPress==0)||(TouchState!=TOUCH_DOWN));
        TouchPress = 0;
        cx= TouchX;
        cy= TouchY;
        SetColor(BLUE);
        ClearDevice();
    }
   
    tempx[0] = (290*cx[0]-30*cx[1])/260;
    tempx[1] = (290*cx[2]-30*cx[3])/260;
    tempy[0] = (220*cy[0]-20*cy[2])/200;
    tempy[1] = (220*cy[1]-20*cy[3])/200;

    if( (tempx[0]>tempx[1]-20) && ((tempx[0]<tempx[1]+20)))
    {
        TouchXMin = (tempx[0]+tempx[1])/2;
    }
    if( (tempy[0]>tempy[1]-20) && ((tempy[0]<tempy[1]+20)))
    {
        TouchYMin = (tempy[0]+tempy[1])/2;
    }
    if(TouchXMin != 0 && TouchYMin !=0)
    {
        TouchXMax = (cx[1]-TouchXMin)*320/290 + TouchXMin;
        TouchYMax = (cy[2]-TouchYMin)*240/220 + TouchYMin;
        break;
    }
  }
  SetColor(color);
  TouchCalibrated = 1;
}



void Touch_GetState(void)           //定时器里调用
{
    u16 x, y;
    static BOOL islow = FALSE;   

    if(TOUCH_READ_INT() != Bit_RESET)          //没有按下的情况下,如果之前是按下的,则
    {                                           //是抬起
        if((TouchState == TOUCH_DOWN)||(TouchState == TOUCH_MOVE))
        {
            TouchState = TOUCH_UP;
            TouchPress = 1;
        }
        else
            TouchState = TOUCH_NONE;
        return;
    }
    else
    {
        if(islow == FALSE)
            islow = TRUE;
        else
        {
            x = Touch_GetX();         
            y = Touch_GetY();
            if((x != 0xffff) && (x != 0xffff))      //有真的按下
            {
              switch(TouchState)
              {
                case TOUCH_NONE:            //原来没有按下,现在一定是按下了
                    TouchState = TOUCH_DOWN;
                    break;
                case TOUCH_DOWN:            //原来按下了,现在一定是move了
                    TouchState = TOUCH_MOVE;
                    break;
                case TOUCH_MOVE:            //之前是move,现在还是move
                    
                    break;
                case TOUCH_UP:              //之前是up,这种情况应该不会出现
                default:
                    TouchState = TOUCH_NONE;
                    break;
              }
              TouchX = x;
              TouchY = y;
              TouchPress = 1;
            }
            islow = FALSE;
        }
    }
   

}

出0入0汤圆

发表于 2011-10-18 22:05:38 | 显示全部楼层
谢谢楼主分享~应该给个裤子啦

出0入0汤圆

 楼主| 发表于 2011-10-18 22:12:35 | 显示全部楼层
白天看到原子哥对神舟的批判, 哎!这就是那个破屏,背光很不均匀,颜色暗淡。

出0入42汤圆

发表于 2011-10-18 22:20:03 | 显示全部楼层
滤波那里可以采用状态机的方法,还可以实现长按、短按、连_发等功能,非常方便

出0入0汤圆

发表于 2011-10-18 22:26:09 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-10-18 22:29:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-18 22:32:43 | 显示全部楼层
我是用三点定位的,四点的话,当时看资料以后实验效果不好。而且资料讲不清楚

出0入0汤圆

发表于 2011-10-18 22:57:16 | 显示全部楼层
回复【3楼】my_avr  
-----------------------------------------------------------------------

能说说具体算法或例程么

出0入0汤圆

发表于 2011-10-18 23:20:16 | 显示全部楼层
记号!

出0入0汤圆

发表于 2011-10-18 23:44:47 | 显示全部楼层
MK

出0入0汤圆

发表于 2011-10-18 23:50:14 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2011-10-19 00:07:30 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2011-10-19 00:25:00 | 显示全部楼层
MK

出0入0汤圆

发表于 2011-10-19 07:09:31 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-10-19 07:39:44 | 显示全部楼层
mark。。。

出0入0汤圆

发表于 2011-10-19 07:52:21 | 显示全部楼层
小屏幕好办,大屏幕消抖就麻烦多了。我买的7寸800*480的带触摸屏,数据完全混乱,以为TP芯片不行,换了一个依然如此,最后换了个触摸屏才好点,但是即使用延时采集多点的办法还是有飞点,估计屏幕贴的不够紧的原因。

出0入0汤圆

发表于 2011-10-19 08:29:21 | 显示全部楼层
mark!!!!谢谢楼主分享!!!!

出0入0汤圆

发表于 2011-10-19 08:40:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-19 08:56:34 | 显示全部楼层
好资料.谢谢!

出0入0汤圆

发表于 2011-10-19 09:04:17 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-10-19 09:09:29 | 显示全部楼层
回复【7楼】hiluck
回复【3楼】my_avr   
-----------------------------------------------------------------------
能说说具体算法或例程么
-----------------------------------------------------------------------

我在采集的时候使用了4种不同的状态,其中判断move可以做到滑动,长按等一些识别。

回复【6楼】zouyf12
-----------------------------------------------------------------------
关于定位我见过2点的,其实2点也可以,3点肯定可以,不过没见过哪个设备用过。

我想4点的最后一点,可能用来判断前面3点是否有偏差的,WINCE的5点(4点+中间一点,中间这个是确认无疑吧)。

出0入0汤圆

发表于 2011-10-19 09:13:01 | 显示全部楼层
纯支持一下!!

出0入0汤圆

发表于 2011-10-19 09:48:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-19 09:54:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-19 10:10:34 | 显示全部楼层
好貼

出0入0汤圆

发表于 2011-10-19 11:08:51 | 显示全部楼层
mark,good!

出0入0汤圆

发表于 2011-10-19 12:30:26 | 显示全部楼层
最近也在搞触摸屏

x y的逻辑坐标和对应的物理坐标 怎么确定呢?!

出0入0汤圆

发表于 2011-10-19 13:00:01 | 显示全部楼层
手机上网留记号

出0入0汤圆

 楼主| 发表于 2011-10-19 13:03:41 | 显示全部楼层
回复【26楼】lang1437 瘸腿狼
-----------------------------------------------------------------------

xy的逻辑坐标就是LCD的像素坐标, 你在LCD上画点的时候就确定了。
对应的物理坐标,是点击的时候读取的。

出0入0汤圆

发表于 2011-10-19 13:14:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-19 13:16:24 | 显示全部楼层
前几天用红牛的板子 自己做的触摸屏部分  但是发现x轴采集回来的数据最大值从500--2500左右,后来把红牛出厂程序烧进去,也没法校准,郁闷

出0入0汤圆

发表于 2011-10-19 13:26:33 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-10-19 13:28:03 | 显示全部楼层
回复【28楼】yanxiao1227
回复【26楼】lang1437 瘸腿狼
-----------------------------------------------------------------------
xy的逻辑坐标就是lcd的像素坐标, 你在lcd上画点的时候就确定了。
对应的物理坐标,是点击的时候读取的。
-----------------------------------------------------------------------

哦 大概明白了 我再继续试试呵呵

出0入0汤圆

发表于 2011-10-19 13:32:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-19 16:02:34 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-10-19 16:35:14 | 显示全部楼层
cool!
顶楼主!

出0入0汤圆

发表于 2011-10-19 20:09:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-19 22:45:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-19 23:08:22 | 显示全部楼层
好贴!

出0入0汤圆

发表于 2011-10-19 23:16:45 | 显示全部楼层
留爪

出0入0汤圆

发表于 2011-10-19 23:33:05 | 显示全部楼层
mark!

出10入0汤圆

发表于 2011-10-20 00:12:27 | 显示全部楼层
mark!!!
头像被屏蔽

出0入0汤圆

发表于 2011-10-20 00:32:00 | 显示全部楼层
mark!!!

出0入0汤圆

发表于 2011-10-20 08:57:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-20 09:14:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-20 09:15:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-20 11:05:34 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-10-20 11:36:03 | 显示全部楼层
mark!!!

出0入0汤圆

发表于 2011-10-20 12:27:43 | 显示全部楼层
(实际项目中用了的,非理论推测)
ADS78xx的片子,X/Y切换后第一次的数据丢弃就可以了,切换后第一次读取的值不丢弃的话,
误差特别大。

出0入0汤圆

发表于 2011-10-20 13:02:04 | 显示全部楼层
关注一下,

出0入0汤圆

 楼主| 发表于 2011-10-20 22:56:26 | 显示全部楼层
回复【48楼】usecool
-----------------------------------------------------------------------

这个问题我调试的时候也发现了,第一次基本都不准,很多时候是0.

程序中,我取了10次,排序后只取了中间的3次,这3次我测试发现只有1-3的差距,大部分时候一样。

出0入0汤圆

发表于 2011-10-21 10:59:08 | 显示全部楼层
是这样 我单片机+7843只需要检测发送触摸屏的坐标给核心处理板就行,不需要校验,转换的

但跟参照的那个板子发送的坐标值范围要小,我就想着说给两个触摸屏的坐标进行下映射。

如果我对两个触摸屏的坐标进行映射应该怎么算啊?

还是说有别的思路啊

出0入0汤圆

发表于 2011-10-21 11:14:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-21 15:58:29 | 显示全部楼层
当手点击触摸不动,不断读取的坐标值,坐标值的差值也很大。为什么啊?如果有这么一段函数的话,就无法发送坐标了都

#define ERR_RANGE 50                        //误差范围

uint8 RD_TWO_ADS7843(uint16 *x,uint16 *y)
{
        uint16 x1,y1;
        uint16 x2,y2;
        uint8 flag;
        flag = RD_ADS7843(&x1,&y1);
        if(flag == 0)
                return(0);
        flag = RD_ADS7843(&x2,&y2);
        if(flag == 0)
                return(0);
        if((((x2<=x1)&&(x1<(x2+ERR_RANGE)))||((x1<=x2)&&(x2<(x1+ERR_RANGE))))
                &&(((y2<y1)&&(y1<(y2+ERR_RANGE))||((y1<=y2)&&(y2<y1+(ERR_RANGE))))))
        {
                *x = (x1+x2)/2;
                *y = (y1+y2)/2;
                return 1;
        }
        else
                return 0;
               
}

出0入0汤圆

发表于 2011-10-21 16:12:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-21 17:03:15 | 显示全部楼层
就是读一个点的坐标时候 就是从ADS7843里获取的数据 经过排序 去头 去尾,取均值,波动还是挺大,LZ还有好的建议没啊呵呵

出0入0汤圆

发表于 2011-10-21 17:17:44 | 显示全部楼层
硬件问题已排除!关键还是程序的处理上吧!还望指教!

出0入0汤圆

 楼主| 发表于 2011-10-21 17:20:22 | 显示全部楼层
回复【55楼】lang1437 瘸腿狼
-----------------------------------------------------------------------

实验发现,发现INT引脚变低之后直接读取,第一次通常是0。 所以你的程序发现是0就直接返回,这可能会出错。

还有ADS7843的ADC转换频率是125KHZ,计算下,两次读取之间要有一定的时间间隔,读完一次直接读第二次,可能
AD转换并没有结束,导致结果出错。也许第一次的结果为0也是这个原因。

建议ls按这个思路修改下程序。

出0入0汤圆

发表于 2011-10-21 21:00:37 | 显示全部楼层
回复【59楼】yanxiao1227
-----------------------------------------------------------------------

谢谢LZ

我在控制命令和读取数据间 增大延时 就能够正确的校正了! 但还是不够精确!在最大值角的位置有很明显的误差。

回头根据你的思路 我再细分析下 也许能好的!等我反馈吧呵呵

出0入0汤圆

发表于 2011-10-23 14:53:02 | 显示全部楼层
标记,学习

出0入0汤圆

发表于 2011-10-23 15:47:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-23 17:01:47 | 显示全部楼层
高手啊

出0入0汤圆

发表于 2011-10-23 22:21:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-27 15:38:49 | 显示全部楼层
哎 我是过来反馈的 终于弄好了 简直就是个悲剧啊!绕了个大圈 还是延时的问题。

关键原因是在于中断后要延时;设置和接收之间要延时。

可能跟滤波的算法也有关系吧,我的板子用中值平均滤波算法要好一点。从小到大 冒泡的那种排序算法,实时性不高,出现鼠标拖动很生硬。


反正现在是好了 还是比较准确的!

对于我个人分析问题的能力要重新审视,哎。。。

出0入0汤圆

发表于 2011-10-27 15:41:03 | 显示全部楼层
参考的一篇文章后惊醒,让我又回头检查延时的问题了
http://blog.chinaunix.net/space.php?uid=20658736&do=blog&id=1587611

五、软件实现细节:

软件滤波比较简单,在获取触摸屏坐标时,可以连续获取5次得到5组数据,之后用“冒泡算法”将它们按大小排列,然后去掉一个最大值和一个最小值,最后取剩下的3组坐标数据的平均值即可。

但软件的设计还有个要点和难点。根据ADS7843的特性,对触摸屏的采样过程中,触摸屏提供给ADS7843的电压必须保持稳定。但由于前面的硬件电路添加了一个“一阶无源低通滤波器”电路,由于RC电路存在充放电延迟的特性,势必造成被采样电压的变化存在几个ms的延迟。因此在软件处理开/关ADS7843的采样时,延迟的控制至关重要。也就是说,当CPU接收到ADS7843的触摸中断后,必须延迟几个ms才能开启采样,否则采样到的电压值并非是真实的电压值。

出0入4汤圆

发表于 2011-10-27 16:14:05 | 显示全部楼层
以前做过类似的程序,当时是参照palm进行的两点定位:
左上+右下(或者右上+左下),然后在点中间1点,判断误差大不大。不大就定位好了,开始正常应用。否则重新定位。

看到现在iphone之类的,开机都不用在进行定位了,还觉得很奇怪呢,搞不懂是什么原理。有哪位明白给讲讲?

出0入0汤圆

发表于 2011-10-27 16:23:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-27 22:04:00 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-10-28 08:36:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-28 10:08:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-28 21:40:16 | 显示全部楼层
楼主,方便的话能否发给小弟一份源码?282529350@qq.com,最近在搞触摸,画线画的跟泼墨似的.....

出0入0汤圆

发表于 2011-10-28 23:30:39 | 显示全部楼层
回复【楼主位】yanxiao1227
-----------------------------------------------------------------------

学习了。公司一产品正准备打算用触摸屏重新设计

出0入0汤圆

发表于 2011-10-29 17:47:41 | 显示全部楼层
good 喜欢 帮顶

出0入0汤圆

发表于 2011-10-29 18:20:31 | 显示全部楼层
mark!

出0入10汤圆

发表于 2011-10-29 20:06:55 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-10-29 20:27:54 | 显示全部楼层
有点兴趣

出20入12汤圆

发表于 2011-10-29 21:15:55 | 显示全部楼层
开始学习

出0入0汤圆

发表于 2011-10-29 21:16:14 | 显示全部楼层
mark 触摸屏

出0入0汤圆

发表于 2011-10-29 21:32:21 | 显示全部楼层
学习一下。网上有针对ADS7843的驱动。不过好像没有移动功能。你这个不错,学习一下。

出0入0汤圆

发表于 2011-10-29 22:13:42 | 显示全部楼层
顶.

出0入0汤圆

发表于 2011-10-30 11:04:08 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-10-30 13:08:02 | 显示全部楼层
回复【67楼】get500wan  
以前做过类似的程序,当时是参照palm进行的两点定位:
左上+右下(或者右上+左下),然后在点中间1点,判断误差大不大。不大就定位好了,开始正常应用。否则重新定位。
看到现在iphone之类的,开机都不用在进行定位了,还觉得很奇怪呢,搞不懂是什么原理。有哪位明白给讲讲?
-----------------------------------------------------------------------

应该是用存储芯片将矫正的信息储存吧

出0入0汤圆

发表于 2011-10-30 13:10:28 | 显示全部楼层
回复【67楼】get500wan  
以前做过类似的程序,当时是参照palm进行的两点定位:
左上+右下(或者右上+左下),然后在点中间1点,判断误差大不大。不大就定位好了,开始正常应用。否则重新定位。
看到现在iphone之类的,开机都不用在进行定位了,还觉得很奇怪呢,搞不懂是什么原理。有哪位明白给讲讲?
-----------------------------------------------------------------------

应该是用存储芯片将矫正的信息储存吧

出0入0汤圆

发表于 2011-10-30 14:52:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-2 11:28:57 | 显示全部楼层
标记下   别人帮忙选的 神舟板子 拿回来后杯具了

出0入0汤圆

发表于 2011-11-2 12:54:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-2 13:24:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-2 20:31:53 | 显示全部楼层
mark 最近在用ADS7843

出0入0汤圆

发表于 2011-11-3 09:06:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-3 11:40:22 | 显示全部楼层
好,值得收藏!

出0入0汤圆

发表于 2011-11-13 17:31:32 | 显示全部楼层
回复【66楼】lang1437 瘸腿狼
-----------------------------------------------------------------------

出厂已经校正过,使用过程中利用这个中心值会实时补偿!

出0入0汤圆

 楼主| 发表于 2011-11-22 14:18:53 | 显示全部楼层
回复【92楼】charleslfw  
回复【66楼】lang1437 瘸腿狼
-----------------------------------------------------------------------
出厂已经校正过,使用过程中利用这个中心值会实时补偿!
-----------------------------------------------------------------------

是的,大部分的手机等设备出厂的时候会在流水上进行测试和设置,比如时间、触摸屏等,
这个过程中,就教正过了,我们现在的产品是通过一些测试,确定了一些经验值之后直接
直接写入,也不需要教正,如果使用中真的不准,也可以校准。

出0入0汤圆

发表于 2011-11-22 16:04:42 | 显示全部楼层
mark 学习了

出0入0汤圆

发表于 2011-11-24 09:15:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-24 09:20:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-7 15:02:51 | 显示全部楼层
谢谢楼主。ads7843成功了。但是只有一块板子,其他板子不行。郁闷

出0入0汤圆

发表于 2011-12-7 16:21:07 | 显示全部楼层
必须mark

出0入0汤圆

发表于 2011-12-7 16:33:24 | 显示全部楼层
必须mark

出0入0汤圆

发表于 2011-12-7 16:38:30 | 显示全部楼层
触摸屏的控制芯片选择ADS7846,ADS7846是TI(BB)公司生产的12位四线触摸屏控制芯片,因为该芯片是12Bit精度,所以可以提供的水平和垂直分辨率均为4096,而屏幕大小为240*320,所以,有很高的分辨率,有利于屏幕控制精度的提高。

出0入0汤圆

发表于 2011-12-7 17:25:46 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 08:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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