STM32F4开发板 实验28触摸屏实验中 u8 GT9147_Scan(u8 mode)和GT9147驱动有点疑惑

2019-07-20 18:12发布

本帖最后由 shblh 于 2016-4-22 16:59 编辑

原子大哥和各位大神,对STM32F4开发板 实验28触摸屏实验中 u8 GT9147_Scan(u8 mode)这个函数有点疑惑
贴代码如下:

u8 GT9147_Scan(u8 mode)
{
        u8 buf[4];
        u8 i=0;
        u8 res=0;
        u8 temp;
        u8 tempsta;
        static u8t=0;//控制查询间隔,从而降低CPU占用率   
        t++;
       if((t%10)==0||t<10)//空闲时,每进入10CTP_Scan函数才检测1,从而节省CPU使用率
        {
               GT9147_RD_Reg(GT_GSTID_REG,&mode,1);       //读取触摸点的状态  
               if(mode&0X80&&((mode&0XF)<6))
               {
                       temp=0;
                      GT9147_WR_Reg(GT_GSTID_REG,&temp,1);//清标志               
               }               
               if((mode&0XF)&&((mode&0XF)<6))
               {
                      temp=0XFF<<(mode&0XF);               //将点的个数转换为1的位数,匹配tp_dev.sta定义         将mode转化为temp后把temp存到tp_dev.sta
                      tempsta=tp_dev.sta;                       //保存当前的tp_dev.sta值

                      tp_dev.sta=(~temp)|TP_PRES_DOWN|TP_CATH_PRES;
   
                  tp_dev.x[4]=tp_dev.x[0];       //保存触点0的数据
                       tp_dev.y[4]=tp_dev.y[0];

                       for(i=0;i<5;i++)
                       {
                              if(tp_dev.sta&(1<<i))       //触摸有效?
                              {
                                      GT9147_RD_Reg(GT9147_TPX_TBL,buf,4);       //
读取XY坐标值
            
                          if(tp_dev.touchtype&0X01)//横屏
                                      {
                                             tp_dev.y=((u16)buf[1]<<8)+buf[0];
                                             tp_dev.x=800-(((u16)buf[3]<<8)+buf[2]);
                                      }else//默认是竖屏

                                      {
                                             tp_dev.x=((u16)buf[1]<<8)+buf[0];
                                             tp_dev.y=((u16)buf[3]<<8)+buf[2];
                                      }  
                                     //printf("x[%d]:%d,y[%d]:%d ",i,tp_dev.x,i,tp_dev.y);
                              }                       
                       }
                       res=1;
                       if(tp_dev.x[0]>lcddev.width||tp_dev.y[0]>lcddev.height)//非法数据(坐标超出了)
                       {
                              
if((mode&0XF)>1)               //有其他点有数据,则复第二个触点的数据到第一个触点.
                               {
                                      tp_dev.x[0]=tp_dev.x[1];
                                      tp_dev.y[0]=tp_dev.y[1];
                                      t=0;                              //
触发一次,则会最少连续监测10,从而提高命中率
                              }else                                      //
非法数据,则忽略此次数据(还原原来的)  
                               {
                                      tp_dev.x[0]=tp_dev.x[4];
                                      tp_dev.y[0]=tp_dev.y[4];
                                      mode=0X80;               
                                      tp_dev.sta=tempsta;        //
恢复tp_dev.sta
                               }

                       }else t=0;                                     //触发一次,则会最少连续监测10次,从而提高命中率

               }
        }
       if((mode&0X8F)==0X80)//无触摸点按下
        {
               if(tp_dev.sta&TP_PRES_DOWN)        //
之前是被按下的
                {
                       tp_dev.sta&=~(1<<7);       //
标记按键松开
                }else                                             //
之前就没有被按下
                {
                       tp_dev.x[0]=0xffff;
                       tp_dev.y[0]=0xffff;
                       tp_dev.sta&=0XE0;       //
清除点有效标记        
                }        
        }
         
       if(t>240)t=10;//重新从10开始计数

        return res;
}

对于此程序,有点不懂:1、红 {MOD}粗体标记的地方,为什么这个时候要保存触电0的数据到触电4呢?
2、GT9147读出来的触电坐标不需要根据LCD的分辨率吧进行转换吗?代码中好像没有进行转换?
3、蓝 {MOD}粗体标记的地方,这部分代码有什么意义??
4、绿 {MOD}粗体标记的地方,有非法数据,为什么只是对触点1的数据进行了处理?为什么这么处理呢?
5、该触摸屏可以支持5点触摸,但我实际测试的时候,比如两个点同时按下去,会直接用红 {MOD}线连成线??是不是最好只是一个点触摸会比较好???
6、根据GT9147编程手册P13-P16的介绍对[size=15.199999809265137px]GT9147_Scan函数的疑惑:

QQ截图20160422150457.png QQ截图20160422150837.png QQ截图20160422150845.png QQ截图20160422150856.png

6.1、
上图一(GT9147编程手册P13)显示的0x8150  R  PxyOk  Reserved   
                                                           0x8151  R  PxyOk  Reserved
上图二(GT9147编程手册P14)显示0X8178~0x817B才是第5个触电的坐标
例程中读取5个触电的坐标信息是读0X8150~0x8153、0X8158~0x815B、0X8160~0x8163、0X8168~0x816B、0X8170~0x8173这些寄存器读出的,这样处理的是对的吗??
6.2、
上图三(GT9147编程手册P15)怎么对0x8150 1.png 又是这么描述?
0x8150这个地址怎么对应两个解释呢??

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
shblh
1楼-- · 2019-07-20 18:47
本帖最后由 shblh 于 2016-4-22 21:12 编辑

@正点原子@各位大神
正点原子
2楼-- · 2019-07-20 22:05
这些问题,楼主自己一一验证就知道了。手册不一定对。
shblh
3楼-- · 2019-07-21 01:24
本帖最后由 shblh 于 2016-4-25 11:36 编辑
正点原子 发表于 2016-4-23 13:49
这些问题,楼主自己一一验证就知道了。手册不一定对。

if((mode&0XF)&&((mode&0XF)<6))
               {
                      temp=0XFF<<(mode&0XF);               //将点的个数转换为1的位数,匹配tp_dev.sta定义         将mode转化为temp后把temp存到tp_dev.sta
                      tempsta=tp_dev.sta;                       //保存当前的tp_dev.sta值
                      tp_dev.sta=(~temp)|TP_PRES_DOWN|TP_CATH_PRES;
                      tp_dev.x[4]=tp_dev.x[0];       //保存触点0的数据
                       tp_dev.y[4]=tp_dev.y[0];

                       for(i=0;i<5;i++)
                       {
                              if(tp_dev.sta&(1<<i))       //触摸有效?
                              {
                                      GT9147_RD_Reg(GT9147_TPX_TBL,buf,4);       //读取XY坐标值
                                      if(tp_dev.touchtype&0X01)//横屏
                                      {
                                             tp_dev.y=((u16)buf[1]<<8)+buf[0];
                                             tp_dev.x=800-(((u16)buf[3]<<8)+buf[2]);
                                      }else//默认是竖屏
                                      {
                                             tp_dev.x=((u16)buf[1]<<8)+buf[0];
                                             tp_dev.y=((u16)buf[3]<<8)+buf[2];
                                      }  
                                     //printf("x[%d]:%d,y[%d]:%d ",i,tp_dev.x,i,tp_dev.y);
                              }                       
                       }
                       res=1;
                       if(tp_dev.x[0]>lcddev.width||tp_dev.y[0]>lcddev.height)//非法数据(坐标超出了)
                       {
                              if((mode&0XF)>1)               //有其他点有数据,则复第二个触点的数据到第一个触点.
                               {
                                      tp_dev.x[0]=tp_dev.x[1];
                                      tp_dev.y[0]=tp_dev.y[1];
                                      t=0;                              //触发一次,则会最少连续监测10次,从而提高命中率
                              }else                                      //非法数据,则忽略此次数据(还原原来的)  
                               {
                                     tp_dev.x[0]=tp_dev.x[4];
                                      tp_dev.y[0]=tp_dev.y[4];

                                      mode=0X80;               
                                      tp_dev.sta=tempsta;        //恢复tp_dev.sta
                               }
                       }else t=0;                                     //触发一次,则会最少连续监测10次,从而提高命中率
               }
原子大哥,如果是5个点同时按下,然后第一个点超出范围,按程序的话,就是   tp_dev.x[0]=tp_dev.x[4]; tp_dev.y[0]=tp_dev.y[4];,可是上面程序已经读取坐标到tp_dev.x[4]、dev.y[4],dev.x[4]、dev.y[4]已经不是   tp_dev.x[4]=tp_dev.x[0];       //保存触点0的数据        tp_dev.y[4]=tp_dev.y[0];,这个地方是不是有bug??

正点原子
4楼-- · 2019-07-21 02:33
shblh 发表于 2016-4-25 11:35
if((mode&0XF)&&((mode&0XF)

不存在 这个bug,tp_dev.x[4]=tp_dev.x[0];       //保存触点0的数据
发生在读取数据之前。
shblh
5楼-- · 2019-07-21 03:36
 精彩回答 2  元偷偷看……
正点原子
6楼-- · 2019-07-21 05:32
 精彩回答 2  元偷偷看……

一周热门 更多>