OpenEdv-开源电子网

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

[阿波罗F429] 阿波罗F429/F767接10.1寸触摸屏偶尔出现乱点bug解决办法

[复制链接]

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2018-10-26 21:10:13 | 显示全部楼层 |阅读模式
阿波罗STM32F429/F767在接10.1寸屏的时候,偶尔会出现乱点(不会画出来,但是程序可以监控到)的情况。其原因是我们添加10.1寸屏代码的时候tp_dev结构体的sta成员,必须改成u16,因为10.1寸屏支持10点触摸。
改完以后代码(在touch.h里面)如下:
[mw_shl_code=c,true]//触摸屏控制器
typedef struct
{
        u8 (*init)(void);                        //初始化触摸屏控制器
        u8 (*scan)(u8);                                //扫描触摸屏.0,屏幕扫描;1,物理坐标;         
        void (*adjust)(void);                //触摸屏校准
        u16 x[CT_MAX_TOUCH];                 //当前坐标
        u16 y[CT_MAX_TOUCH];                //电容屏有最多10组坐标,电阻屏则用x[0],y[0]代表:此次扫描时,触屏的坐标,用
                                                                //x[9],y[9]存储第一次按下时的坐标.
        u16 sta;                                        //笔的状态
                                                                //b15:按下1/松开0;
                                    //b14:0,没有按键按下;1,有按键按下.
                                                                //b13~b10:保留
                                                                //b9~b0:电容触摸屏按下的点数(0,表示未按下,1表示按下)
/////////////////////触摸屏校准参数(电容屏不需要校准)//////////////////////                                                               
        float xfac;                                       
        float yfac;
        short xoff;
        short yoff;          
//新增的参数,当触摸屏的左右上下完全颠倒时需要用到.
//b0:0,竖屏(适合左右为X坐标,上下为Y坐标的TP)
//   1,横屏(适合左右为Y坐标,上下为X坐标的TP)
//b1~6:保留.
//b7:0,电阻屏
//   1,电容屏
        u8 touchtype;
}_m_tp_dev;[/mw_shl_code]

除了将sta的u8改成u16之外,和sta相关的处理代码,宏定义等,都要改成u16类型的处理方式:
[mw_shl_code=c,true]#define TP_PRES_DOWN         0x8000  //触屏被按下          
#define TP_CATH_PRES         0x4000  //有按键按下了 [/mw_shl_code]

gt9271.c里面GT9271_Scan函数改为:
[mw_shl_code=c,true]//扫描触摸屏(采用查询方式)
//mode:0,正常扫描.
//返回值:当前触屏状态.
//0,触屏无触摸;1,触屏有触摸
u8 GT9271_Scan(u8 mode)
{
        u8 buf[4];
        vu8 i=0;
        u8 res=0;
        u16 temp;
        u16 tempsta;
        static u8 t=0;//控制查询间隔,从而降低CPU占用率   
        t++;
        if((t%10)==0||t<10)//空闲时,每进入10次CTP_Scan函数才检测1次,从而节省CPU使用率
        {
                GT9271_RD_Reg(GT9271_GSTID_REG,&mode,1);        //读取触摸点的状态  
                if(mode&0X80&&((mode&0XF)<11))
                {
                        i=0;
                        GT9271_WR_Reg(GT9271_GSTID_REG,(u8*)&i,1);        //清标志                
                }               
                if((mode&0XF)&&((mode&0XF)<11))
                {
                        temp=0XFFFF<<(mode&0XF);        //将点的个数转换为1的位数,匹配tp_dev.sta定义
                        tempsta=tp_dev.sta;                        //保存当前的tp_dev.sta值
                        tp_dev.sta=(~temp)|TP_PRES_DOWN|TP_CATH_PRES;
                        tp_dev.x[9]=tp_dev.x[0];        //保存触点0的数据
                        tp_dev.y[9]=tp_dev.y[0];
                        for(i=0;i<10;i++)
                        {
                                if(tp_dev.sta&(1<<i))        //触摸有效?
                                {
                                        GT9271_RD_Reg(GT9271_TPX_TBL,buf,6);        //读取XY坐标值
                                        if(tp_dev.touchtype&0X01)//横屏
                                        {
                                                tp_dev.y=((u16)buf[3]<<8)+buf[2];
                                                tp_dev.x=((u16)buf[1]<<8)+buf[0];
                                                 
                                        }else
                                        {
                                                tp_dev.x=800-(((u16)buf[3]<<8)+buf[2]);
                                                tp_dev.y=((u16)buf[1]<<8)+buf[0];
                                        }  
                                        printf("x[%d]:%d,y[%d]:%d\r\n",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[9];
                                        tp_dev.y[0]=tp_dev.y[9];
                                        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&=~TP_PRES_DOWN;        //标记按键松开
                }else                                                        //之前就没有被按下
                {
                        tp_dev.x[0]=0xffff;
                        tp_dev.y[0]=0xffff;
                        tp_dev.sta&=0XE000;                        //清除点有效标记       
                }         
        }        
        if(t>240)t=10;//重新从10开始计数
        return res;
}[/mw_shl_code]

当然还有其他触摸屏处理函数,都要做相应的修改,这里就不一一列举了,详见附件。
改完以后,10.1寸屏的触摸屏使用的时候,就不会有乱点了。

实验30 触摸屏实验_new.rar (294.5 KB, 下载次数: 65)
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

465

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2142
金钱
2142
注册时间
2013-1-11
在线时间
504 小时
发表于 2018-12-20 11:46:56 | 显示全部楼层
知识是你最好的财富
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2019-2-25
在线时间
3 小时
发表于 2019-2-25 18:15:36 | 显示全部楼层
本帖最后由 long5313828 于 2019-2-25 18:17 编辑

关于这个bug的问题,新版的程序依然没有改到位,任然会出现乱点的情况,只是会持续点一个点而已,使用emwin的时候就会发现,出现的原因在于GT9271驱动上。GT9271_Scan函数改为以下这样就行
[mw_shl_code=c,true]//扫描触摸屏(采用查询方式)
//mode:0,正常扫描.
//返回值:当前触屏状态.
//0,触屏无触摸;1,触屏有触摸
u8 GT9271_Scan(u8 mode)
{
        u8 buf[4];
        vu8 i=0;
        u8 res=0;
        u16 temp;
        u16 tempsta;
         static u8 t=0;//控制查询间隔,从而降低CPU占用率   
        t++;
        if((t%10)==0||t<10)//空闲时,每进入10次CTP_Scan函数才检测1次,从而节省CPU使用率
        {
                GT9271_RD_Reg(GT9271_GSTID_REG,&mode,1);        //读取触摸点的状态  
                 if((mode&0x80)&&((mode&0XF)<11))
                {
                        i=0;
                        GT9271_WR_Reg(GT9271_GSTID_REG,(u8*)&i,1);        //清标志                 
            if(mode&0xF) // **这一行就是需要修改的部分,将这个判断包含在上一个if语句里
            {
                temp=0XFFFF<<(mode&0XF);        //将点的个数转换为1的位数,匹配tp_dev.sta定义
                tempsta=tp_dev.sta;                        //保存当前的tp_dev.sta值
                tp_dev.sta=(~temp)|TP_PRES_DOWN|TP_CATH_PRES;
                tp_dev.x[9]=tp_dev.x[0];        //保存触点0的数据
                tp_dev.y[9]=tp_dev.y[0];
                for(i=0;i<10;i++)
                {
                    if(tp_dev.sta&(1<<i))        //触摸有效?
                    {
                        GT9271_RD_Reg(GT9271_TPX_TBL,buf,6);        //读取XY坐标值
                        if(tp_dev.touchtype&0X01)//横屏
                        {
                            tp_dev.y=((u16)buf[3]<<8)+buf[2];
                            tp_dev.x=((u16)buf[1]<<8)+buf[0];
                             
                        }else
                        {
                            tp_dev.x=800-(((u16)buf[3]<<8)+buf[2]);
                            tp_dev.y=((u16)buf[1]<<8)+buf[0];
                        }  
                        //printf("x[%d]:%d,y[%d]:%d\r\n",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[9];
                        tp_dev.y[0]=tp_dev.y[9];
                        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&=~TP_PRES_DOWN;        //标记按键松开
                }else                                                        //之前就没有被按下
                {
                        tp_dev.x[0]=0xffff;
                        tp_dev.y[0]=0xffff;
                        tp_dev.sta&=0XE000;                        //清除点有效标记        
                }         
        }         
        if(t>240)t=10;//重新从10开始计数
        return res;
}[/mw_shl_code]
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2019-2-25
在线时间
3 小时
发表于 2019-2-25 18:18:04 | 显示全部楼层
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 22:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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