矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 5135|回复: 29

求助51单片机触摸屏坐标和液晶屏坐标如何对应!

[复制链接]
     
发表于 2020-8-29 16:20:18 | 显示全部楼层 |阅读模式
本帖最后由 分立元件 于 2020-8-29 16:29 编辑

弄了好久了不知道哪里错了,触摸屏在液晶屏上的定位不准,求教高手指点一下!
1e72fb32424e5e3ad953fe0575569ca.jpg

498f31394d70257ef9811ec56a10e5e.jpg

触摸屏.jpg

触摸屏2046.gif

#include<reg51.h>
#include<absacc.h>
#include<intrins.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int

//液晶屏引脚
sbit cs        =P1^0;//片选
sbit reset     =P1^1;//复位
sbit rs        =P1^2;//地址/数据切换
sbit sda       =P1^3;// SDI  MOSI
sbit scl       =P1^4;//时钟
//SDO引脚可以不连接

//触摸屏引脚
sbit  clk=P0^4;
sbit  cs1=P0^3;
sbit  din=P0^2;
sbit  out=P0^1;
sbit  a=P0^0;

uchar bdata bitdata;
sbit bit7=bitdata^7;
sbit bit6=bitdata^6;
sbit bit5=bitdata^5;
sbit bit4=bitdata^4;
sbit bit3=bitdata^3;
sbit bit2=bitdata^2;
sbit bit1=bitdata^1;
sbit bit0=bitdata^0;

uint shuju;
void delay(uint time)
{
uint i,j;
  for(i=0;i<time;i++)
   for(j=0;j<2500;j++);
}

void  write_command(uchar c)
{
        cs=0;

        rs=0;
        bitdata=c;

        sda=bit7;scl=0;scl=1;
        sda=bit6;scl=0;scl=1;
        sda=bit5;scl=0;scl=1;
        sda=bit4;scl=0;scl=1;
        sda=bit3;scl=0;scl=1;
        sda=bit2;scl=0;scl=1;
        sda=bit1;scl=0;scl=1;
        sda=bit0;scl=0;scl=1;
        cs=1;      
}

void  write_data(uchar d)
{
        cs=0;
        rs=1;
        bitdata=d;
        sda=bit7;scl=0;scl=1;
        sda=bit6;scl=0;scl=1;
        sda=bit5;scl=0;scl=1;
        sda=bit4;scl=0;scl=1;
        sda=bit3;scl=0;scl=1;
        sda=bit2;scl=0;scl=1;
        sda=bit1;scl=0;scl=1;
        sda=bit0;scl=0;scl=1;
        cs=1;
}

void wr_com16(unsigned char i,unsigned char j)   
{         
        cs=0;

        rs=1;
        bitdata=i;

        sda=bit7;scl=0;scl=1;
        sda=bit6;scl=0;scl=1;
        sda=bit5;scl=0;scl=1;
        sda=bit4;scl=0;scl=1;
        sda=bit3;scl=0;scl=1;
        sda=bit2;scl=0;scl=1;
        sda=bit1;scl=0;scl=1;
        sda=bit0;scl=0;scl=1;
        cs=1;  
        cs=0;


        rs=1;
        bitdata=j;

        sda=bit7;scl=0;scl=1;
        sda=bit6;scl=0;scl=1;
        sda=bit5;scl=0;scl=1;
        sda=bit4;scl=0;scl=1;
        sda=bit3;scl=0;scl=1;
        sda=bit2;scl=0;scl=1;
        sda=bit1;scl=0;scl=1;
        sda=bit0;scl=0;scl=1;
        cs=1;

}
//////////////////////////////////////////////////////////////////////////////////////////////

void lcd_initial()
{

        reset=0;
        delay(100);
        reset=1;
        delay(100);
       
        write_command(0x11);  
        write_data(0x00);

        write_command(0xCF);  
        write_data(0X00);
        write_data(0XC1);
        write_data(0X30);

        write_command(0xED);  
        write_data(0X64);
        write_data(0X03);
        write_data(0X12);
        write_data(0X81);

        write_command(0xE8);  
        write_data(0X85);
        write_data(0X11);
        write_data(0X78);

        write_command(0xF6);  
        write_data(0X01);
        write_data(0X30);
        write_data(0X00);

        write_command(0xCB);  
        write_data(0X39);
        write_data(0X2C);
        write_data(0X00);
        write_data(0X34);
        write_data(0X05);

        write_command(0xF7);  
        write_data(0X20);

        write_command(0xEA);  
        write_data(0X00);
        write_data(0X00);

        write_command(0xC0);  
        write_data(0X20);

        write_command(0xC1);  
        write_data(0X11);

        write_command(0xC5);  
        write_data(0X31);
        write_data(0X3C);

        write_command(0xC7);  
        write_data(0XA9);

        write_command(0x3A);  
        write_data(0X55);
       
    write_command(0x36);  
        write_data(0x48);//竖屏参数

        write_command(0xB1);  
        write_data(0X00);
        write_data(0X18);

        write_command(0xB4);  
        write_data(0X00);
        write_data(0X00);

        write_command(0xF2);  
        write_data(0X00);

        write_command(0x26);  
        write_data(0X01);

        write_command(0xE0);  
        write_data(0X0F);
        write_data(0X17);
        write_data(0X14);
        write_data(0X09);
        write_data(0X0C);
        write_data(0X06);
        write_data(0X43);
        write_data(0X75);
        write_data(0X36);
        write_data(0X08);
        write_data(0X13);
        write_data(0X05);
        write_data(0X10);
        write_data(0X0B);
        write_data(0X08);


        write_command(0xE1);  
        write_data(0X00);
        write_data(0X1F);
        write_data(0X23);
        write_data(0X03);
        write_data(0X0E);
        write_data(0X04);
        write_data(0X39);
        write_data(0X25);
        write_data(0X4D);
        write_data(0X06);
        write_data(0X0D);
        write_data(0X0B);
        write_data(0X33);
        write_data(0X37);
        write_data(0X0F);
    write_command(0x29);  

}
void addset(unsigned int x,unsigned int y)
{
                write_command(0x2a);
                wr_com16(0,x);
                write_command(0x2b);
                wr_com16(0,y);
                write_command(0x2c);
}

void dsp_single_colour(DH,DL)
{
       

           unsigned int i;

        for (i=0;i<3;i++)  
        {
         
    wr_com16(DH,DL);
       
       
         }

}

//触摸屏程序
void write(uchar DAT)                //写XY坐标

{

uchar i;

clk=0;

for(i=0;i<8;i++)

{
  
din=DAT>>7;

DAT<<=1;

clk=1;


clk=0;

}

}


uint read()                                        //读XY坐标数据

{

uint date;

uchar i;

clk=0;

for(i=0;i<12;i++)

{
  
date<<=1;



clk=1;

clk=0;
  
date|=out;


}

return date;

}

uint ad_read(uchar cmd)                 

{



char i;

clk=0;

cs1=0;

write(cmd);

for(i=6;i>0;i--);

clk=1;

//_nop_();

//_nop_();

clk=0;

//_nop_();

//_nop_();

shuju=read();

cs1=1;

return  shuju;

}

main()
{           float aa,bb,x,y;
                lcd_initial();        //液晶屏初始化

                while(1)       
                  {
                       
                    if(a==0)   //有触摸低电平
                        {
                      delay(20);//延时消抖                          
                          if(a==0)        //再次判断是否低电平
                          {
                          delay(1);
                         ad_read(0xd0);          //读坐标指令        x
                         aa=shuju;                   //x坐标数据给aa
                         ad_read(0x90);          //坐标指令        y
                         bb=shuju;                  //y坐标数据给bb

                         x=aa/(4095/240);        //触摸屏和液晶屏坐标转换
                         y=bb/(4095/320);


                         addset(x,y);                                          //液晶屏坐标

                     dsp_single_colour(0xf8,0x00);         //显示红色定位点
               
                         
                 }
                                                   
               
            }
        }
}
     
发表于 2020-8-29 16:35:33 | 显示全部楼层
也许触摸屏的质量不行,
多年前,我花700元买过杂牌8寸WIN8小平板,触屏不准,校准几遍都不行,但能对付用,边角就难了。我以为触摸屏都这样呢;
后来又花3700买个某大牌WIN10,12寸平板,触屏真是分毫不差,也不用校准;边角跟中间无差别地准;那以后我确信品牌的价值了。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-8-29 16:43:15 来自手机 | 显示全部楼层
壹法拉 发表于 2020-8-29 16:35
也许触摸屏的质量不行,
多年前,我花700元买过杂牌8寸WIN8小平板,触屏不准,校准几遍都不行,但能对付用 ...

有这个可能额!但是也怕程序有错,或者计算有错!
回复 支持 反对

使用道具 举报

     
发表于 2020-8-30 19:38:26 | 显示全部楼层
我感觉你uint read()里面的date没有初始化0;是不是这的原因?
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-8-30 19:39:39 来自手机 | 显示全部楼层
peiguoqing 发表于 2020-8-30 19:38
我感觉你uint read()里面的date没有初始化0;是不是这的原因?

触摸屏不需要初始化的吧
回复 支持 反对

使用道具 举报

     
发表于 2020-8-30 19:42:02 | 显示全部楼层
分立元件 发表于 2020-8-30 19:39
触摸屏不需要初始化的吧

uint read()                                        //读XY坐标数据

{

uint date;//--------------这里,能确定内存分配=0吗?    改成uint date=0;试试
uchar i;
clk=0;
for(i=0;i<12;i++)
{
date<<=1;
clk=1;
clk=0;
date|=out;
}
return date;

}
回复 支持 反对

使用道具 举报

     
发表于 2020-8-30 20:08:41 | 显示全部楼层
我昨天才修复了个手写板,这个手写板就是一张7寸的电阻触摸屏,老年人不会键盘打字,用手写挺方便的。
我修的这个手写板是触摸屏使用时间太长表层的那层膜划破了。
从你发的照片上可以看出来用的是电阻屏,电阻屏正常使用前是需要校准的,因为不同厂家不同尺寸的电阻不一样,
还有就是时间久了或者温度变化了,都可能导致电阻变化,所以得经常校准。
如果你用的是电容屏,就没有这样的校准要求。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-8-30 20:09:26 来自手机 | 显示全部楼层
peiguoqing 发表于 2020-8-30 19:42
uint read()                                        //读XY坐标数据

{

谢谢你了,我试试看!
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-8-30 20:10:24 来自手机 | 显示全部楼层
xiaocake1 发表于 2020-8-30 20:08
我昨天才修复了个手写板,这个手写板就是一张7寸的电阻触摸屏,老年人不会键盘打字,用手写挺方便的。
我 ...

就是电阻屏,用的液晶带触摸屏模块的
回复 支持 反对

使用道具 举报

     
发表于 2020-8-30 20:14:45 | 显示全部楼层
分立元件 发表于 2020-8-30 20:10
就是电阻屏,用的液晶带触摸屏模块的

那建议你增加校准程序,在屏幕边角设置两个点(对角)作为校准点。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-8-30 21:04:50 来自手机 | 显示全部楼层
xiaocake1 发表于 2020-8-30 20:14
那建议你增加校准程序,在屏幕边角设置两个点(对角)作为校准点。

不是那个,是我现在用51单片机驱动程序,对应像素不对,点一下,屏幕出现点是随机的,不是偏差一点点
回复 支持 反对

使用道具 举报

     
发表于 2020-8-30 22:50:43 | 显示全部楼层
没玩过高级货
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-8-30 23:08:55 来自手机 | 显示全部楼层
iffi123 发表于 2020-8-30 22:50
没玩过高级货

不是啥高级货,现在很便宜啦,30多一个
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-8-30 23:32:53 | 显示全部楼层
peiguoqing 发表于 2020-8-30 19:42
uint read()                                        //读XY坐标数据

{

现在试了一下,还是一样的!!!
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-8-30 23:39:11 | 显示全部楼层
找到一个STM32的程序

#include "touch.h"
#include "lcd.h"
#include "delay.h"
#include "stdlib.h"
#include "math.h"
#include "24cxx.h"
#include "gui.h"            
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//测试硬件:单片机STM32F103RBT6,正点原子MiniSTM32开发板,主频72MHZ
//QDtech-TFT液晶驱动 for STM32 IO模拟
//xiao冯@ShenZhen QDtech co.,LTD
//公司网站:www.qdtft.com
//淘宝网站:http://qdtech.taobao.com
//我司提供技术支持,任何技术问题欢迎随时交流学习
//固话(传真) :+86 0755-23594567
//手机:15989313508(冯工)
//邮箱:goodtft@126.com
//SkypeDtech2008
//技术支持QQ:3002773612
//技术交流QQ群:324828016
//创建日期:2013/5/13
//版本:V2.0
//版权所有,盗版必究。
//Copyright(C) 深圳市全动电子技术有限公司 2013-2019
//All rights reserved
/****************************************************************************************************

//====================================电源接线==========================================//
//VCC        ---接 5V或3.3V电源
//GND        ---接 地

//===============================液晶屏控制线接线======================================//
//CS               ---接PB11        //液晶屏片选信号
//RESET             ---接PB12        //液晶屏复位信号
//DC/RS             ---接PB10        //寄存器/数据选择信号
//SDI(MOSI)         ---接PB15        //SPI总线写数据
//SCK               ---接PB13        //SPI总线时钟信号
//LED               ---接PB9         //背光控制信号(高电平点亮)如果不需要控制可接VCC常亮
//SDO(MISO)  ---接PB14 //SPI读信号如无需读取可不接

//===============================触摸屏接线========================================//
//不使用触摸或者模块本身不带触摸,则可不连接  
//T_CLK             ---接PC0         //触摸SPI总线时钟
//T_CS             ---接PC13 //触摸IC片选
//T_DIN             ---接PC3        //触摸SPI总线输入
//T_DO             ---接PC2        //触摸SPI总线输出
//T_IRQ             ---接PC1        //触摸屏中断信号

*************************************************************************************************/

_m_tp_dev tp_dev=
{
        TP_Init,
        TP_Scan,
        TP_Adjust,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,                                  
        0,
        0,                                  
};                                       
//默认为touchtype=0的数据.
u8 CMD_RDX=0XD0;
u8 CMD_RDY=0X90;
                                                                               
//SPI写数据
//向触摸屏IC写入1byte数据   
//num:要写入的数据
void TP_Write_Byte(u8 num)   
{  
        u8 count=0;   
        for(count=0;count<8;count++)  
        {           
                if(num&0x80)TDIN=1;  
                else TDIN=0;   
                num<<=1;   
                TCLK=0;          
                TCLK=1;                //上升沿有效                
        }                                             
}                  
//SPI读数据
//从触摸屏IC读取adc值
//CMD:指令
//返回值:读到的数据          
u16 TP_Read_AD(u8 CMD)          
{          
        u8 count=0;           
        u16 Num=0;
        TCLK=0;                //先拉低时钟          
        TDIN=0;         //拉低数据线
        TCS=0;                 //选中触摸屏IC
        TP_Write_Byte(CMD);//发送命令字
        delay_us(6);//ADS7846的转换时间最长为6us
        TCLK=0;                          
        delay_us(1);              
        TCLK=1;                //给1个时钟,清除BUSY                        
        TCLK=0;                          
        for(count=0;count<16;count++)//读出16位数据,只有高12位有效
        {                                   
                Num<<=1;          
                TCLK=0;        //下降沿有效                        
                TCLK=1;
                if(DOUT)Num++;                  
        }         
        Num>>=4;           //只有高12位有效.
        TCS=1;                //释放片选         
        return(Num);   
}
//读取一个坐标值(x或者y)
//连续读取READ_TIMES次数据,对这些数据升序排列,
//然后去掉最低和最高LOST_VAL个数,取平均值
//xy:指令(CMD_RDX/CMD_RDY)
//返回值:读到的数据
#define READ_TIMES 5         //读取次数
#define LOST_VAL 1                  //丢弃值
u16 TP_Read_XOY(u8 xy)
{
        u16 i, j;
        u16 buf[READ_TIMES];
        u16 sum=0;
        u16 temp;
        for(i=0;i<READ_TIMES;i++)buf=TP_Read_AD(xy);                                     
        for(i=0;i<READ_TIMES-1; i++)//排序
        {
                for(j=i+1;j<READ_TIMES;j++)
                {
                        if(buf>buf[j])//升序排列
                        {
                                temp=buf;
                                buf=buf[j];
                                buf[j]=temp;
                        }
                }
        }          
        sum=0;
        for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++)sum+=buf;
        temp=sum/(READ_TIMES-2*LOST_VAL);
        return temp;   
}
//读取x,y坐标
//最小值不能少于100.
//x,y:读取到的坐标值
//返回值:0,失败;1,成功。
u8 TP_Read_XY(u16 *x,u16 *y)
{
        u16 xtemp,ytemp;                                                    
        xtemp=TP_Read_XOY(CMD_RDX);
        ytemp=TP_Read_XOY(CMD_RDY);                                                                                                            
        //if(xtemp<100||ytemp<100)return 0;//读数失败
        *x=xtemp;
        *y=ytemp;
        return 1;//读数成功
}
//连续2次读取触摸屏IC,且这两次的偏差不能超过
//ERR_RANGE,满足条件,则认为读数正确,否则读数错误.          
//该函数能大大提高准确度
//x,y:读取到的坐标值
//返回值:0,失败;1,成功。
#define ERR_RANGE 50 //误差范围
u8 TP_Read_XY2(u16 *x,u16 *y)
{
        u16 x1,y1;
        u16 x2,y2;
        u8 flag;   
    flag=TP_Read_XY(&x1,&y1);   
    if(flag==0)return(0);
    flag=TP_Read_XY(&x2,&y2);          
    if(flag==0)return(0);   
    if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE))//前后两次采样在+-50内
    &&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE)))
    {
        *x=(x1+x2)/2;
        *y=(y1+y2)/2;
        return 1;
    }else return 0;          
}  
//////////////////////////////////////////////////////////////////////////////////                  
//与LCD部分有关的函数  
//画一个触摸点
//用来校准用的
//x,y:坐标
//color:颜色
void TP_Drow_Touch_Point(u16 x,u16 y,u16 color)
{
        POINT_COLOR=color;
        LCD_DrawLine(x-12,y,x+13,y);//横线
        LCD_DrawLine(x,y-12,x,y+13);//竖线
        LCD_DrawPoint(x+1,y+1);
        LCD_DrawPoint(x-1,y+1);
        LCD_DrawPoint(x+1,y-1);
        LCD_DrawPoint(x-1,y-1);
        gui_circle(x,y,POINT_COLOR,6,0);//画中心圈
}          
//画一个大点(2*2的点)                  
//x,y:坐标
//color:颜色
void TP_Draw_Big_Point(u16 x,u16 y,u16 color)
{            
        POINT_COLOR=color;
        LCD_DrawPoint(x,y);//中心点
        LCD_DrawPoint(x+1,y);
        LCD_DrawPoint(x,y+1);
        LCD_DrawPoint(x+1,y+1);                          
}                                                  
//////////////////////////////////////////////////////////////////////////////////                  
//触摸按键扫描
//tp:0,屏幕坐标;1,物理坐标(校准等特殊场合用)
//返回值:当前触屏状态.
//0,触屏无触摸;1,触屏有触摸
u8 TP_Scan(u8 tp)
{                          
        if(PEN==0)//有按键按下
        {
                if(tp)TP_Read_XY2(&tp_dev.x,&tp_dev.y);//读取物理坐标
                else if(TP_Read_XY2(&tp_dev.x,&tp_dev.y))//读取屏幕坐标
                {
                         tp_dev.x=tp_dev.xfac*tp_dev.x+tp_dev.xoff;//将结果转换为屏幕坐标
                        tp_dev.y=tp_dev.yfac*tp_dev.y+tp_dev.yoff;  
                 }
                if((tp_dev.sta&TP_PRES_DOWN)==0)//之前没有被按下
                {                 
                        tp_dev.sta=TP_PRES_DOWN|TP_CATH_PRES;//按键按下  
                        tp_dev.x0=tp_dev.x;//记录第一次按下时的坐标
                        tp_dev.y0=tp_dev.y;                                      
                }                          
        }else
        {
                if(tp_dev.sta&TP_PRES_DOWN)//之前是被按下的
                {
                        tp_dev.sta&=~(1<<7);//标记按键松开       
                }else//之前就没有被按下
                {
                        tp_dev.x0=0;
                        tp_dev.y0=0;
                        tp_dev.x=0xffff;
                        tp_dev.y=0xffff;
                }            
        }
        return tp_dev.sta&TP_PRES_DOWN;//返回当前的触屏状态
}          
//////////////////////////////////////////////////////////////////////////         
//保存在EEPROM里面的地址区间基址,占用13个字节(RANGE:SAVE_ADDR_BASE~SAVE_ADDR_BASE+12)
#define SAVE_ADDR_BASE 40
//保存校准参数                                                                                    
void TP_Save_Adjdata(void)
{
        s32 temp;                         
        //保存校正结果!                                                                             
        temp=tp_dev.xfac*100000000;//保存x校正因素      
    AT24CXX_WriteLenByte(SAVE_ADDR_BASE,temp,4);   
        temp=tp_dev.yfac*100000000;//保存y校正因素   
    AT24CXX_WriteLenByte(SAVE_ADDR_BASE+4,temp,4);
        //保存x偏移量
    AT24CXX_WriteLenByte(SAVE_ADDR_BASE+8,tp_dev.xoff,2);                    
        //保存y偏移量
        AT24CXX_WriteLenByte(SAVE_ADDR_BASE+10,tp_dev.yoff,2);       
        //保存触屏类型
        AT24CXX_WriteOneByte(SAVE_ADDR_BASE+12,tp_dev.touchtype);       
        temp=0X0A;//标记校准过了
        AT24CXX_WriteOneByte(SAVE_ADDR_BASE+13,temp);
}
//得到保存在EEPROM里面的校准值
//返回值:1,成功获取数据
//        0,获取失败,要重新校准
u8 TP_Get_Adjdata(void)
{                                          
        s32 tempfac;
        tempfac=AT24CXX_ReadOneByte(SAVE_ADDR_BASE+13);//读取标记字,看是否校准过!                  
        if(tempfac==0X0A)//触摸屏已经校准过了                          
        {                                                                                                     
                tempfac=AT24CXX_ReadLenByte(SAVE_ADDR_BASE,4);                  
                tp_dev.xfac=(float)tempfac/100000000;//得到x校准参数
                tempfac=AT24CXX_ReadLenByte(SAVE_ADDR_BASE+4,4);                                  
                tp_dev.yfac=(float)tempfac/100000000;//得到y校准参数
            //得到x偏移量
                tp_dev.xoff=AT24CXX_ReadLenByte(SAVE_ADDR_BASE+8,2);                                     
            //得到y偏移量
                tp_dev.yoff=AT24CXX_ReadLenByte(SAVE_ADDR_BASE+10,2);                                           
                tp_dev.touchtype=AT24CXX_ReadOneByte(SAVE_ADDR_BASE+12);//读取触屏类型标记
                if(tp_dev.touchtype)//X,Y方向与屏幕相反
                {
                        CMD_RDX=0X90;
                        CMD_RDY=0XD0;         
                }else                                   //X,Y方向与屏幕相同
                {
                        CMD_RDX=0XD0;
                        CMD_RDY=0X90;         
                }                 
                return 1;         
        }
        return 0;
}         
//提示字符串
const u8* TP_REMIND_MSG_TBL="lease use the stylus click the cross on the screen.The cross will always move until the screen adjustment is completed.";
                                          
//提示校准结果(各个参数)
void TP_Adj_Info_Show(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2,u16 x3,u16 y3,u16 fac)
{          
        POINT_COLOR=RED;
        LCD_ShowString(40,160,16,"x1:",1);
        LCD_ShowString(40+80,160,16,"y1:",1);
        LCD_ShowString(40,180,16,"x2:",1);
        LCD_ShowString(40+80,180, 16,"y2:",1);
        LCD_ShowString(40,200, 16,"x3:",1);
        LCD_ShowString(40+80,200, 16,"y3:",1);
        LCD_ShowString(40,220, 16,"x4:",1);
        LCD_ShowString(40+80,220, 16,"y4:",1);  
        LCD_ShowString(40,240, 16,"fac is:",1);     
        LCD_ShowNum(40+24,160,x0,4,16);                //显示数值
        LCD_ShowNum(40+24+80,160,y0,4,16);        //显示数值
        LCD_ShowNum(40+24,180,x1,4,16);                //显示数值
        LCD_ShowNum(40+24+80,180,y1,4,16);        //显示数值
        LCD_ShowNum(40+24,200,x2,4,16);                //显示数值
        LCD_ShowNum(40+24+80,200,y2,4,16);        //显示数值
        LCD_ShowNum(40+24,220,x3,4,16);                //显示数值
        LCD_ShowNum(40+24+80,220,y3,4,16);        //显示数值
        LCD_ShowNum(40+56,lcddev.width,fac,3,16);         //显示数值,该数值必须在95~105范围之内.

}
                 
//触摸屏校准代码
//得到四个校准参数
void TP_Adjust(void)
{                                                                 
        u16 pos_temp[4][2];//坐标缓存值
        u8  cnt=0;       
        u16 d1,d2;
        u32 tem1,tem2;
        float fac;        
        u16 outtime=0;
        cnt=0;                               
        POINT_COLOR=BLUE;
        BACK_COLOR =WHITE;
        LCD_Clear(WHITE);//清屏   
        POINT_COLOR=RED;//红色
        LCD_Clear(WHITE);//清屏           
        POINT_COLOR=BLACK;
        LCD_ShowString(10,40,16,"lease use the stylus click the",1);//显示提示信息
        LCD_ShowString(10,56,16,"cross on the screen.The cross will",1);//显示提示信息
        LCD_ShowString(10,72,16,"always move until the screen ",1);//显示提示信息
        LCD_ShowString(10,88,16,"adjustment is completed.",1);//显示提示信息

        TP_Drow_Touch_Point(20,20,RED);//画点1
        tp_dev.sta=0;//消除触发信号
        tp_dev.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误         
        while(1)//如果连续10秒钟没有按下,则自动退出
        {
                tp_dev.scan(1);//扫描物理坐标
                if((tp_dev.sta&0xc0)==TP_CATH_PRES)//按键按下了一次(此时按键松开了.)
                {       
                        outtime=0;               
                        tp_dev.sta&=~(1<<6);//标记按键已经被处理过了.
                                                                             
                        pos_temp[cnt][0]=tp_dev.x;
                        pos_temp[cnt][1]=tp_dev.y;
                        cnt++;          
                        switch(cnt)
                        {                          
                                case 1:                                                 
                                        TP_Drow_Touch_Point(20,20,WHITE);                                //清除点1
                                        TP_Drow_Touch_Point(lcddev.width-20,20,RED);        //画点2
                                        break;
                                case 2:
                                        TP_Drow_Touch_Point(lcddev.width-20,20,WHITE);        //清除点2
                                        TP_Drow_Touch_Point(20,lcddev.height-20,RED);        //画点3
                                        break;
                                case 3:
                                        TP_Drow_Touch_Point(20,lcddev.height-20,WHITE);                        //清除点3
                                        TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,RED);        //画点4
                                        break;
                                case 4:         //全部四个点已经得到
                                //对边相等
                                        tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2
                                        tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2
                                        tem1*=tem1;
                                        tem2*=tem2;
                                        d1=sqrt(tem1+tem2);//得到1,2的距离
                                       
                                        tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4
                                        tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4
                                        tem1*=tem1;
                                        tem2*=tem2;
                                        d2=sqrt(tem1+tem2);//得到3,4的距离
                                        fac=(float)d1/d2;
                                        if(fac<0.8||fac>1.05||d1==0||d2==0)//不合格
                                        {
                                                cnt=0;
                                            TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE);        //清除点4
                                                    TP_Drow_Touch_Point(20,20,RED);                                                                //画点1
                                                TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据   
                                                continue;
                                        }
                                        tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3
                                        tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3
                                        tem1*=tem1;
                                        tem2*=tem2;
                                        d1=sqrt(tem1+tem2);//得到1,3的距离
                                       
                                        tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4
                                        tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4
                                        tem1*=tem1;
                                        tem2*=tem2;
                                        d2=sqrt(tem1+tem2);//得到2,4的距离
                                        fac=(float)d1/d2;
                                        if(fac<0.8||fac>1.05)//不合格
                                        {
                                                cnt=0;
                                            TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE);        //清除点4
                                                    TP_Drow_Touch_Point(20,20,RED);                                                                //画点1
                                                TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据   
                                                continue;
                                        }//正确了
                                                                  
                                        //对角线相等
                                        tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3
                                        tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3
                                        tem1*=tem1;
                                        tem2*=tem2;
                                        d1=sqrt(tem1+tem2);//得到1,4的距离
       
                                        tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4
                                        tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4
                                        tem1*=tem1;
                                        tem2*=tem2;
                                        d2=sqrt(tem1+tem2);//得到2,3的距离
                                        fac=(float)d1/d2;
                                        if(fac<0.8||fac>1.05)//不合格
                                        {
                                                cnt=0;
                                            TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE);        //清除点4
                                                    TP_Drow_Touch_Point(20,20,RED);                                                                //画点1
                                                TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据   
                                                continue;
                                        }//正确了
                                        //计算结果
                                        tp_dev.xfac=(float)(lcddev.width-40)/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac                 
                                        tp_dev.xoff=(lcddev.width-tp_dev.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff
                                                  
                                        tp_dev.yfac=(float)(lcddev.height-40)/(pos_temp[2][1]-pos_temp[0][1]);//得到yfac
                                        tp_dev.yoff=(lcddev.height-tp_dev.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff  
                                        if(abs(tp_dev.xfac)>2||abs(tp_dev.yfac)>2)//触屏和预设的相反了.
                                        {
                                                cnt=0;
                                            TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE);        //清除点4
                                                    TP_Drow_Touch_Point(20,20,RED);                                                                //画点1
                                                LCD_ShowString(40,26, 16,"TP Need readjust!",1);
                                                tp_dev.touchtype=!tp_dev.touchtype;//修改触屏类型.
                                                if(tp_dev.touchtype)//X,Y方向与屏幕相反
                                                {
                                                        CMD_RDX=0X90;
                                                        CMD_RDY=0XD0;         
                                                }else                                   //X,Y方向与屏幕相同
                                                {
                                                        CMD_RDX=0XD0;
                                                        CMD_RDY=0X90;         
                                                }                            
                                                continue;
                                        }               
                                        POINT_COLOR=BLUE;
                                        LCD_Clear(WHITE);//清屏
                                        LCD_ShowString(35,110, 16,"Touch Screen Adjust OK!",1);//校正完成
                                        delay_ms(1000);
                                        TP_Save_Adjdata();  
                                        LCD_Clear(WHITE);//清屏   
                                        return;//校正完成                                 
                        }
                }
                delay_ms(10);
                outtime++;
                if(outtime>1000)
                {
                        TP_Get_Adjdata();
                        break;
                 }
        }
}                  
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-29 07:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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