OpenEdv-开源电子网

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

XPT2046触摸屏容易飞点。

[复制链接]

21

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
273
金钱
273
注册时间
2017-7-19
在线时间
89 小时
发表于 2018-2-21 22:52:32 | 显示全部楼层 |阅读模式
1金钱
已经进行滤波,算法和原子哥的基本一样。长按屏幕的时候坐标值挺稳定的,一旦松手,坐标值有几率变成  0,4095。只能用松手检测while(!PEN);来固定坐标值。如果要做手写之类的功能就不行了


[mw_shl_code=c,true]/******* IO口模拟时序 *******/
/*------- 写数据时序 -------*/
//写入1字节数据
void TP_SPI_Write(uchar dat)
{                                                       
        uchar i;
       
        DCLK = 0;//时钟先拉低
       
        for(i=0;i<8;i++)
        {
                if(dat & 0x80) DIN = 1;//从最高位开始
                else DIN = 0;
                dat <<= 1;
               
                DCLK = 0;
//                delay_us(1);
                DCLK = 1;//上升沿开始进行传输
        }
}

/*------ 读数据时序 -------*/
//读出12位的数据
u16 TP_SPI_Read()
{
        uchar i;
        u16 dat = 0;

        for(i=0;i<12;i++)//AD数据只有12位
        {
                dat <<= 1;
                DCLK = 0;//下降沿后可以接收数据
//                delay_us(1);
                DCLK = 1;//为下个的下降沿准备
               
                if(DOUT) dat++;
        }
       
        return dat;
}

/********* 功能函数 **********/
/*------ 读取ADC值 ------*/
//读取一次,一个坐标的ADC值,X或者Y的
u16 TP_Read_AD(uchar cmd)
{
        u16 value;
       
        DCLK = 0; //时钟线拉低
        DIN = 0; //输入数据线拉低
        CS = 0; //片选拉低
       
        TP_SPI_Write(cmd);//发送命令
        delay_us(6);
       
        DCLK = 0;
//        delay_us(1);
        DCLK = 1;//清除BUSY
//        delay_us(1);
        DCLK = 0;
       
        value = TP_SPI_Read();//读取数据
       
        CS = 1;//拉高片选
       
        return value;
}

/*---- 读取坐标值后进行软件滤波 ----*/
//读取一个坐标值进行滤波,X或Y。
//Coo:TP_CMD_RDX或TP_CMD_RDY
u16 TP_Read_Coo(uchar Coo)
{
        uchar i,j;
        u16 CooValues[READSAMP];
        u16 tmp,sum=0;
       
        for(i=0;i<READSAMP;i++)        CooValues = TP_Read_AD(Coo);
       
        for(i=0;i<READSAMP-1;i++) //冒泡排序
        {
                for(j=0;j<READSAMP-1-i;j++)
                {
                        if(CooValues[j] > CooValues[j+1])
                        {
                                tmp = CooValues[j];
                                CooValues[j] = CooValues[j+1];
                                CooValues[j+1] = tmp;
                        }
                }
        }
       
        for(i=USELESS;i<READSAMP-USELESS;i++) sum = sum + CooValues; //全加起来
        tmp = sum / (READSAMP - USELESS*2); //求平均值
       
        return tmp;
}

/*--------- 读取X和Y的坐标 ----------*/
//*x,*y:X和Y的坐标值。
uchar TP_Read_XY(u16 *x,u16 *y)
{
        u16 x1,y1,x2,y2;
       
        x1 = TP_Read_Coo(TP_CMD_RDX);//第一次
        y1 = TP_Read_Coo(TP_CMD_RDY);
       
        x2 = TP_Read_Coo(TP_CMD_RDX);//第二次
        y2 = TP_Read_Coo(TP_CMD_RDY);
       
        /*计算两次的差值*/
        if(x1 > x2)  *x = x1 - x2; //x坐标的差值
        else  *x = x2 - x1;
       
        if(y1 > y2)         *y = y1 - y2; //y坐标的差值
        else  *y = y2 - y1;
       
        /*判断差值是否在误差范围内*/
        if((*x > ALLOWABLE_ERR) || (*y > ALLOWABLE_ERR)) return 1;//超出范围
       
        *x = (x1 + x2) / 2;
        *y = (y1 + y2) / 2;//求出平均值就是实际的坐标
       
        return 0; //读取坐标成功
}[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

还是自己解决了,再加一个判断就行了 if((*x > RANGE_X_MAX) | (*x < RANGE_X_MIN) | (*y > RANGE_Y_MAX) | (*y < RANGE_Y_MIN)) return 1; //判断是否超过限定的触摸范围。判断只要超过这四个值就是读取失败,我的飞点总是在左下角(0,4095),用这个方法能解决。如果出现其他三个极点的情况也可以解决的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

21

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
273
金钱
273
注册时间
2017-7-19
在线时间
89 小时
 楼主| 发表于 2018-2-21 22:52:33 | 显示全部楼层
本帖最后由 飛饵 于 2018-2-23 17:00 编辑

还是自己解决了,再加一个判断就行了
        if((*x > RANGE_X_MAX) | (*x < RANGE_X_MIN) | (*y > RANGE_Y_MAX) | (*y < RANGE_Y_MIN)) return 1; //判断是否超过限定的触摸范围。判断只要超过这四个值就是读取失败,我的飞点总是在左下角(0,4095),用这个方法能解决。如果出现其他三个极点的情况也可以解决的
回复

使用道具 举报

21

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
273
金钱
273
注册时间
2017-7-19
在线时间
89 小时
 楼主| 发表于 2018-2-23 16:18:42 | 显示全部楼层
都没人知道什么回事吗
回复

使用道具 举报

2

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2018-3-6
在线时间
13 小时
发表于 2018-4-16 14:42:37 | 显示全部楼层
RANGE_X_MAX你的这个值是多少
回复

使用道具 举报

21

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
273
金钱
273
注册时间
2017-7-19
在线时间
89 小时
 楼主| 发表于 2018-4-16 21:55:59 | 显示全部楼层
月下时光浓 发表于 2018-4-16 14:42
RANGE_X_MAX你的这个值是多少

#define RANGE_X_MAX 3900
#define RANGE_X_MIN 300
#define RANGE_Y_MAX 3900
#define RANGE_Y_MIN 150
回复

使用道具 举报

2

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2018-3-6
在线时间
13 小时
发表于 2018-4-17 20:38:21 | 显示全部楼层
你好,我的程序校正后 ,再次点击屏幕并显示触摸点时候,只有四个角周边点才是正常触摸显示,可是屏幕中央触摸就会漂移。能不能把你程序分享给我下1004485609@qq.com谢谢您了 我参考下
回复

使用道具 举报

2

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2018-3-6
在线时间
13 小时
发表于 2018-4-17 20:43:36 | 显示全部楼层
对了你的程序里面 ,那个判断两个值的误差是否在范围,是什么作用??
回复

使用道具 举报

4

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
339
金钱
339
注册时间
2016-8-12
在线时间
86 小时
发表于 2018-5-7 11:20:11 | 显示全部楼层
大脑 我做咋个不是线性的呢
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-7 23:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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