OpenEdv-开源电子网

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

为什么触摸屏一直在那四个点校准呢?我用的是板子带的程序啊??

[复制链接]

3

主题

13

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2012-11-7
在线时间
0 小时
发表于 2012-11-14 18:51:41 | 显示全部楼层 |阅读模式

#include"stm32f10x.h"
#include"ili9320.h"
#include"touch.h"
#include "stdlib.h"
#include "math.h"
#include"usart.h"

#define TDIN_SET GPIO_SetBits(GPIOA,GPIO_Pin_7);
#define TDIN_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_7);

#define TOUT_SET GPIO_SetBits(GPIOA,GPIO_Pin_6);
#define TOUT_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_6);

#define TCLK_SET GPIO_SetBits(GPIOA,GPIO_Pin_5);
#define TCLK_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_5);

#define TCS_SET GPIO_SetBits(GPIOA,GPIO_Pin_8);
#define TCS_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_8);
#define CMD_RDX 0XD0
#define CMD_RDY 0X90
extern Pen_Holder Pen_Point;
unsigned int POINT_COLOR = 0x0000,BACK_COLOR = 0xFFFF;   
/************************************************************************************
  GPIO口的配置
*************************************************************************************/
void TOUCH_GPIO_Config()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB , ENABLE);

/* 配置管脚: SCK--PA5,  and DINT--PA7 2046 CS ---------PA8 ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIOA->ODR|=(1<<5)|(1<<7)|(1<<8);
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIOA->ODR|=(1<<5)|(1<<7)|(1<<8);
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 2046 INT_busy --PB10  DOUT--PB6-----PB9----按键*/
GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIOA->ODR|=1<<6;
GPIO_Init(GPIOA, &GPIO_InitStructure);

 

GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
  
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//调用函数使能外设的时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;  
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //定义模式;    
GPIO_Init(GPIOB, &GPIO_InitStructure);

}
extern void EXIT_Config(void)
{
   
  EXTI_InitTypeDef EXTI_InitStructure; //申明结构体
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
  EXTI_ClearITPendingBit(EXTI_Line1);
  EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_Line=EXTI_Line1;
  EXTI_InitStructure.EXTI_LineCmd=ENABLE;
  EXTI_Init(&EXTI_InitStructure);
}
extern void NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);  //选择第二组
  NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;            //选择中断通道3
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占式中断优先级设置为1
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //响应式中断优先级设置为1
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断                                   //使能中断
  NVIC_Init(&NVIC_InitStructure);


}
extern void EXTI1_IRQHandler(void)
{

  if(EXTI_GetITStatus(EXTI_IMR_MR1) != RESET)
 {
  en_Point.Key_Sta=Key_Down;//按键按下          
     /* Clear the Key Button EXTI line pending bit */
     EXTI_ClearITPendingBit(EXTI_IMR_MR1);
 }

}
extern void Pen_Int_Set(u8 en)
{
   if(en)EXTI->IMR|=1<<1;   //开启line9上的中断    
   else EXTI->IMR&=~(1<<1); //关闭line9上的中断
}
extern u8 Read_TP_Once()
{
 u8 t=0;    
 en_Int_Set(0);//关闭中断
 en_Point.Key_Sta=Key_Up;
 Read_ADS7843TWO(&en_Point.X,&en_Point.Y);
  
 while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0&&t<=250)
 {
  t++;
  delayms(10);
 };
 en_Int_Set(1);//开启中断  
 if(t>=250)return 0;//按下2.5s 认为无效
 return 1;  
}
extern void ADS7843SPI_start()
{
 TCLK_CLR;
 TCS_SET;
 TDIN_SET;
 TCLK_SET;
 TCS_CLR;
}

/*---------------------------------------------------------------------------------
SPI软件模拟写一个字节
输入:data
无返回值
-----------------------------------------------------------------------------------*/
void ADS7843_Write_Byte(uchar data)
{
  uchar count=0;
  TCLK_CLR;
  TCS_CLR;
  for(count=0;count<8;count++)
  {
    if(data&0x80==1)
 TDIN_SET;
    if(data&0x80==0)
 TDIN_CLR;
 data=data<<1;
 TCLK_CLR;
 TCLK_SET; //上升沿ADS7846读总线的数据
  }
}
/*---------------------------------------------------------------------------------
SPI先发送命令字,
然后再读出AD转换的结果
输入:命令控制字
return:转换的结果
-----------------------------------------------------------------------------------*/
unsigned int ADS7843_ReadAD(unsigned char cmd)

   unsigned char count=0;
   unsigned int  number=0;
  // ADS7843SPI_start();
   TCLK_CLR; //先拉低时钟   
   TDIN_CLR; //拉低数据线
   TCS_CLR;  //选中触摸屏IC

   ADS7843_Write_Byte(cmd);//发送控制命令字
   TCLK_CLR;
   delay_us(6);
   TCLK_SET;
   TCLK_CLR;
  
   for(count=0;count<16;count++)
 {
  number<<=1;
     TCLK_CLR;
  delay_us(1);   
     TCLK_SET; //下降沿有效
 
  if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6))number++;
 } //读出number
   number>>=4;       //取高12位
   TCS_SET;     //释放ADS7843
   return number;
 
}
#define READ_TIMES 15//读取次数
#define LOST_VAL 5//丢弃的次数
/*---------------------------------------------------------------------------------
输入:cmd
输出:读15次舍弃10次的平均值
------------------------------------------------------------------------------------*/
unsigned int ADS7843_ReadAvgAD(unsigned char cmd)
{
   unsigned int i,j;
   unsigned int AD_buffer[READ_TIMES];
   unsigned int t,sum,AVG;

   for(i=0;i<READ_TIMES;i++)
   {
     AD_buffer=ADS7843_ReadAD(cmd);
   }
   
   for(j=0;j<READ_TIMES;j++)
   {
     for(i=0;i<READ_TIMES-j;i++)
  {
    if(AD_buffer>AD_buffer[i+1])
       {
    t=AD_buffer;
    AD_buffer=AD_buffer[i+1];
    AD_buffer[i+1]=t;
    }
   
  }
   }

   sum=0;
   for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++)  //剩余的数据相加
 {
    sum+=AD_buffer;
 }
   AVG=sum/(READ_TIMES-2*LOST_VAL);   //求取平均值
   return AVG;

}
/*-----------------------------------------------------------------------------------
  分别测出一个触摸点的x,y
  并存入指针
  return:读取标志位,是否读取正确
--------------------------------------------------------------------------------------*/

unsigned char Read_ADS7843(unsigned int *x,unsigned int *y)
{
   int xtemp,ytemp;
   xtemp=ADS7843_ReadAvgAD(CMD_RDX);
   ytemp=ADS7843_ReadAvgAD(CMD_RDY);

   if(xtemp<100||ytemp<100||xtemp>3800||ytemp>3800) return 0; //读取失败,触摸屏比TFT屏要大,一般小于100的
   //是在TFT屏外,这样就没有意义
       *x=xtemp;
    *y=ytemp;
    printf("\n\r X=%d,Y=%d\n\r",xtemp,ytemp);
    return 1;   //读取成功
   
}
/*---------------------------------------------------------------------------------
   取两次坐标看两次的误差是否在(—+50)一定范围之内
   return:标志位
------------------------------------------------------------------------------------*/
#define  ERR_RANGE 50
unsigned char Read_ADS7843TWO(unsigned int *x,unsigned int *y)
{
 unsigned int x1,y1;
 unsigned int x2,y2;
 unsigned char flag;

 flag=Read_ADS7843(&x1,&y1);
 if(flag==0) return 0;
 flag=Read_ADS7843(&x2,&y2);
 if(flag==0) return 0;

 if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE)) //前后两次采样xy的误差范围
 &&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE)))
 {
    *x=(x1+x2)/2;   //把两次采集到的数据求平均值存到*x,*y中
    *y=(y1+y2)/2;  
    return 1;
 }
 else
 {
    return 0;
 }

}
/*----------------------------------------------------------------------------------
   因为触摸屏的坐标和TFT坐标是不一样的
   所以先要确定一个关系
   触摸屏的检验程序
   确定四个点的坐标
-------------------------------------------------------------------------------------*/
void Touch_Adjust(void)
{
 uint16_t pos_temp[4][2];//坐标缓存值
 u8  cnt=0; 
 u16 d1,d2;
 float fac=0;
 u32 tem1,tem2;   
 cnt=0;    
 OINT_COLOR=Blue;
 BACK_COLOR =White;
 CLR_Screen(White);//清屏  
 OINT_COLOR=Red;//红色
 CLR_Screen(White);//清屏
 Drow_Touch_Point(40,40);//画点1
 en_Point.Key_Sta=Key_Up;//消除触发信号
 while(1)
 {
   if(Pen_Point.Key_Sta==Key_Down)//按键按下了
  {
   if(Read_TP_Once())//得到单次按键值
   {            
    pos_temp[cnt][0]=Pen_Point.X;
    pos_temp[cnt][1]=Pen_Point.Y;  
    cnt++;
   }
   LCDShow_uCharNumber(100,100,pos_temp[0][0],Black,White);  
//      LCD_DispNum(pos_temp[0][0],80,80,0,Black,White);
//   LCD_DispNum(pos_temp[0][1],60,60,0,Black,White);
   delayms(1500);
//   return;//校正完成 
   switch(cnt)
   {     
    case 1:
        CLR_Screen(White);//清屏
     Drow_Touch_Point(160,40);//画点2
     break;
    case 2:
     CLR_Screen(White);//清屏
     Drow_Touch_Point(40,280);//画点3
     break;
    case 3:
     CLR_Screen(White);//清屏
     Drow_Touch_Point(160,280);//画点4
     break;
    case 4: 

//        LCD_DispNum(pos_temp[0][0],80,80,0,Black,White);
//     LCD_DispNum(pos_temp[0][1],70,70,0,Black,White);
    
     delayms(1500);      
                    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.95||fac>1.05||d1==0||d2==0)//不合格
     {
      cnt=0;
      CLR_Screen(White);//清屏
      Drow_Touch_Point(40,40);
      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.95||fac>1.05)//不合格
     {
      cnt=0;
         CLR_Screen(White);//清屏
      Drow_Touch_Point(40,40);
      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.95||fac>1.05)//不合格
     {
      cnt=0;
      CLR_Screen(White);//清屏
      Drow_Touch_Point(40,40);
      continue;
     }//正确了
     //计算结果
     en_Point.xfac=(float)160/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac  
     Pen_Point.xoff=(240-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff
       
     Pen_Point.yfac=(float)240/(pos_temp[2][1]-pos_temp[0][1]);//得到yfac
     Pen_Point.yoff=(320-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff 
     POINT_COLOR=Blue;
     CLR_Screen(White);//清屏
     LCD_PutString(35,110,"Touch Screen Adjust OK!",Black,White);//校正完成
     delayms(1000);
     CLR_Screen(White);//清屏  
        return;//校正完成    
           //退出校验循环程序
 
   }
   }
  }
 }

/**********************************************************************************
   这是一个画笔函数
***********************************************************************************/
extern void Drow_Touch_Point(unsigned int x,unsigned int y)
{
 Line(x-12,y,x+13,y,Black);//横线
 Line(x,y-12,x,y+13,Black);//竖线
 Put_pixel(x+1,y+1,Black);
 Put_pixel(x-1,y+1,Black);
 Put_pixel(x+1,y-1,Black);
 Put_pixel(x-1,y-1,Black);
 LCD_DispCircle(x,y,6,Black);//画中心圈
 Write_Cmd_Data(0x0000,0x0022);    
}
/**********************************************************************************
   这是一个画笔函数一个大点
***********************************************************************************/
void Drow_Big_Point(unsigned int x,unsigned int y)
{    
 Put_pixel(x,y,Black);//中心点
 Put_pixel(x+1,y,Black);
 Put_pixel(x,y+1,Black);
 Put_pixel(x+1,y+1,Black);      
}
unsigned int key_scan(void)
{
  u8 Read_A12;
  Read_A12=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11);
  if(Read_A12==0)
  {
     delayms(10);
   led(on);
    return 1;
  }  
   return 0;      
 
}
extern u8 key_scan1()

  u8 Read_A11;
  Read_A11=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12);
  if(Read_A11==0)
  {
      delayms(10);
  
   return 1;
  }
   return 0;      

 }

 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2012-11-14
在线时间
0 小时
发表于 2012-11-14 19:54:43 | 显示全部楼层
好好学习,天天上上!!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-11-14 20:08:43 | 显示全部楼层
回复【楼主位】风雨120:
---------------------------------
fac是多少?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

13

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2012-11-7
在线时间
0 小时
 楼主| 发表于 2012-11-15 11:00:42 | 显示全部楼层
fac也一直是0 
回复 支持 反对

使用道具 举报

3

主题

13

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2012-11-7
在线时间
0 小时
 楼主| 发表于 2012-11-15 13:30:58 | 显示全部楼层
无语啊,一直进入校准
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-11-15 13:42:05 | 显示全部楼层
触摸屏挂了
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2014-6-29
在线时间
4 小时
发表于 2014-10-15 08:46:59 | 显示全部楼层
请问LZ那个160是什么意思啊

比例因子和偏移量为什么是这样算的了。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-30 06:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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