本帖最后由 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)//
空闲时,每进入10次CTP_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函数的疑惑:
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
又是这么描述?
0x8150这个地址怎么对应两个解释呢??
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
@正点原子@各位大神
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??
不存在 这个bug,tp_dev.x[4]=tp_dev.x[0]; //保存触点0的数据
发生在读取数据之前。
一周热门 更多>