OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5349|回复: 4

触摸屏的不解??????

[复制链接]

36

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
340
金钱
340
注册时间
2013-4-22
在线时间
36 小时
发表于 2013-6-15 16:06:31 | 显示全部楼层 |阅读模式

原子哥:
            最近一直在调试触摸屏,遇到好多问题,用你的程序移植到我的屏上没有问题,我自己写了一个,用的SPI(原子哥的触摸是模拟的),
             主要的问题就是触摸PEN脚,一直检测不到低电平,不知道为什么?经过多次尝试,发现只要把  Read_XPT2046();      
             屏蔽掉,是可以检测到PEN脚的,我为这个问题搞了一个星期了,一直无果,希望原子哥抽点时间帮我看看吧~~~~~



#define  TP_CS  PEout(0)
#define  PEN    PEin(1)

  int main(void)

      unsigned short a;       
     Stm32_Clock_Init(9);//系统时钟设置
     delay_init(72);  //延时初始化
     uart_init(72,9600); //串口1初始化    
     LCD_Init();   //初始化液晶
     TP_Init();        //SPI 触摸电路初始化 
     LED_Init();         //LED初始化                    
     LCD_Clear(WHITE);
     LCD_ShowString(20,60,"Touch the first point");
      for(a=0; a<10; a++){         //在竖屏模式下,左上角显示第一个校正点点击区域
          drawbigpoint(0,0+a);
           drawbigpoint(a,0);
          } 
     while (1)                          //等待点击第一个触摸校正点
    {            
         if(PEN==0){          //点击第一个校正点 等待触摸检测电平变低     (此处一直进不去)
                delay_ms(340);        //延时340ms 消除抖动
                if(PEN==0){          //检测触摸中断线是否可靠点击
                 while(PEN==0){        //点击未松开,持续读取触摸坐标
                  delay_ms(100);
                  Read_XPT2046();       //读取触摸坐标     (屏蔽掉这个函数就可以检测到PEN的低电平)
                  Xs=X; Ys=Y;        //获得第一个校正点的X,Y 
                  Delay_ms(340);      //延时340ms 消除抖动  
                  }
                  break; 
               }  
            }    
       }
       LCD_ShowNum(90,2,Ye,4,16);        //显示触摸屏的X值
       LCD_ShowNum(90,17,Xe,4,16);      //显示触摸屏的Y值

       LCD_ShowString(20,120,"Touch the SECOND point"); 
        for(a=0; a<20; a++){       //在竖屏模式下,左上角显示第二个校正点点击区域
                drawbigpoint(120,190+a);
                drawbigpoint(110+a,200);
               }     
       while (1)                        //等待点击第二个触摸校正点
      {            
            if(PEN==0){          //点击第二个校正点 等待触摸检测电平变低
              delay_ms(340);         //延时340ms 消除抖动
                 if(PEN==0){           //检测触摸中断线是否可靠点击
                  while(PEN==0){         //点击未松开,持续读取触摸坐标
                     delay_ms(100);
                         Read_XPT2046();        //读取触摸坐标
                          Xe=X; Ye=Y;         //获得第二个校正点的X,Y
                          delay_ms(500);      //延时340ms 消除抖动     
                          }
                         break;  
                      }  
              }    
       }

      LCD_ShowNum(130,2,Ye,4,16);       //显示触摸屏的X值
      LCD_ShowNum(130,17,Xe,4,16);      //显示触摸屏的Y值

  /* 根据第一个校正点和第二个校正点的数据计算出屏幕上一个像素对应的触摸X,Y变化值,为保持精度,此值是浮点数 */
  X2=Xs-Xe; X2=X2/120; 
  Y2=Ys-Ye; Y2=Y2/200; 
  dw=1;           //校正完成标志
   LCD_Clear(WHITE);           //清屏    
  /* 在屏幕的指定区域显示调色板图形 */
  FillColor(  0, 0, 30,30, RED);
  FillColor( 30, 0, 60,30, BLUE);
  FillColor( 60, 0, 90,30, GREEN);
  FillColor( 90, 0,120,30, YELLOW);
  FillColor(120, 0,150,30, BROWN);
  FillColor(150, 0,180,30, CYAN);        

  LCD_ShowString(220,0,"Cl");
  while (1)                                      //等待中断到来
  {             
        if(PEN==0){
         delay_ms(50);        //延时50ms用于触笔消抖
          while(PEN==0){           //未抬起触笔的情况下画图
                Read_XPT2046();      
                }
           }
     } 

}

void TP_Init(void)
{
   RCC->APB2ENR|=1<<6;    //开启时钟E   
   SPIx_Init();                      //SPI初始化
   SPIx_SetSpeed(256);
   GPIOE->CRL&=0XFFFFFF00;  //E0  为TP_CS 片选
   GPIOE->CRL|=0X00000083;  //E1 为 PEN 输入
   GPIOE->ODR|=1<<0;
   GPIOE->ODR|=1<<1;
}



   /****************************************************************************
* 名    称:u16 TPReadX(void)
* 功    能:触摸屏X轴数据读出
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:
****************************************************************************/ 
u16 TPReadX(void)
{
   u16 x=0;
   TP_CS=0;                            //选择XPT2046
   delay_us(20);                        //延时
   SPIx_ReadWriteByte(0x90);    //设置X轴读取标志
   delay_us(20);                           //延时
   x=SPIx_ReadWriteByte(0x00); //连续读取16位的数据
   x<<=8;
   x+=SPIx_ReadWriteByte(0x00);
   delay_us(20);                         //禁止XPT2046
   TP_CS=1;                   
   x = x>>3;                                  //移位换算成12位的有效数据0-4095
   return (x);
}
/****************************************************************************
* 名    称:u16 TPReadY(void)
* 功    能:触摸屏Y轴数据读出
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:
****************************************************************************/
u16 TPReadY(void)
{
   u16 y=0;
   TP_CS=0;                         //选择XPT2046
   delay_us(20);      //延时
   SPIx_ReadWriteByte(0xD0);    //设置Y轴读取标志
   delay_us(20);      //延时
   y=SPIx_ReadWriteByte(0x00   //连续读取16位的数据
   y<<=8;
   y+=SPIx_ReadWriteByte(0x00);
   delay_us(20);      //禁止XPT2046
   TP_CS=1;                   
   y = y>>3;      //移位换算成12位的有效数据0-4095
   return (y);
}

/****************************************************************************
* 名    称:void Read_XPT2046(void)
* 功    能:读取触摸坐标,进行采样计算,并画点
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:
****************************************************************************/
void Read_XPT2046(void)

      float X1,Y1;   
      u8 t,t1,count=0;  
      u16 databuffer[2][30];                 //触摸坐标过采样缓冲区
       u16 temp=0; 
    do{                                  //循环读数30次  
           Y=TPReadX();    
            X=TPReadY();
            if(X>100&&X<4000&&Y>100&&Y<4000)             //如果是在触摸显示有效区范围的值,标示此读数有效
               {  
                 databuffer[0][count]=X;
                 databuffer[1][count]=Y;
                 count++;  
                }   
          }while((PEN==0)&&count<30);        
         if(count==30)                                    //每次度数一定要读到30次数据,否则丢弃
         { 
               do                                            //将数据X升序排列
                   { 
                       t1=0;   
                       for(t=0;t<count-1;t++)
                        {
                            if(databuffer[0][t]>databuffer[0][t+1])//升序排列
                            {
                               temp=databuffer[0][t+1];
                               databuffer[0][t+1]=databuffer[0][t];
                               databuffer[0][t]=temp;
                               t1=1;
                             } 
                          }
                    }while(t1);   
              do                                              //将数据Y升序排列
                 { 
                    t1=0;  
                    for(t=0;t<count-1;t++)
                    {
                        if(databuffer[1][t]>databuffer[1][t+1])//升序排列
                          {
                              temp=databuffer[1][t+1];
                              databuffer[1][t+1]=databuffer[1][t];
                             databuffer[1][t]=temp;
                              t1=1; 
                           } 
                     }
                }while(t1);
           }   
          /* 从排序过的数组里中间抽取连续的10组数据,进行取平均值,获得较高的精度 */
        X1=0; Y1=0;
        for(count=10;count<20; count++){
        X1=X1+databuffer[0][count];
       Y1=Y1+databuffer[1][count];
     } 
       X1=X1/10;  Y1=Y1/10;
      LCD_ShowNum(190,2,Y1,4,16);
       LCD_ShowNum(190,17,X1,4,16);
    if(X1<=4096&&Y1<=4096)                       //触摸坐标值应小于4096
    { 
       X=X1;
      Y=Y1;               
       iif(dw==1){          //如果进行了校正过程
          if(X1>=Xs)X1=0;       //对该点的触摸X值进行界限判别,如果小于于第一个校正点的触摸X值,该点和校正点的差值初始化为0(和屏有关)
             else X1=Xs-X1;       //如果小于第一个校正点的触摸X值,计算出该点和校正点的差值(和屏有关)
               if(Y1>=Ys)Y1=0;      //如果小于第一个校正点的触摸Y值,计算出该点和校正点的差值(和屏有关)
                     else Y1=Ys-Y1;         //对该点的触摸Y值进行界限判别,如果大于第一个校正点的触摸Y值,该点和校正点的差值初始化为0(和屏有关)
                          X=X1/X2;         //根据一个像素对应的触摸值,算出屏幕上的实际X坐标
                          Y=Y1/Y2;        //根据一个像素对应的触摸值,算出屏幕上的实际Y坐标
                           drawbigpoint(X,Y);       //在该坐标画点
                       }
            }
}


做技术的一定要谦虚,但不能轻易服输!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-6-15 18:26:55 | 显示全部楼层
不屏蔽的话,一次也无法进入吗?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

36

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
340
金钱
340
注册时间
2013-4-22
在线时间
36 小时
 楼主| 发表于 2013-6-16 12:34:01 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
偶尔能进第一个矫正,第二个就进不去了,不知道怎么回事??
做技术的一定要谦虚,但不能轻易服输!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-6-16 14:07:16 | 显示全部楼层
进去没退出吧
这个要加点延时,比较奇怪的一个问题.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

36

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
340
金钱
340
注册时间
2013-4-22
在线时间
36 小时
 楼主| 发表于 2013-6-16 15:18:23 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
我再调调吧,也不知道这地方花这么多时间值不值!!谢谢原子哥。
做技术的一定要谦虚,但不能轻易服输!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-18 19:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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