OpenEdv-开源电子网

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

触屏校准 数据有时候准 有时候不准 单步调试 貌似程序东奔西跑的

[复制链接]

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
发表于 2013-9-17 22:38:27 | 显示全部楼层 |阅读模式

采用了外部中断 里面设置了一个标志位 fuck
每次进入外部中断就把中断关闭 然后执行完一次按键判断就把外部中断打开  期间有延时程序 50ms
然后 还去检测 笔中断脚的 具体值 来消抖
 然后单步调试的时候 发现 程序不按照正常的节奏跑 但是却能把五组数据都读出来 显示到液晶屏上 数据 时而准 时而不准 但是总不能执行到

Finished  那一步 

贴上代码  请原子哥 指点 

uint16_t Phy_X,Phy_Y;                        //触笔的物理坐标
uint16_t ADC_X,ADC_Y;                        //触笔的ADC值
float    xoff,yoff,xfac,yfac;                //触笔的校正值及换算比值

extern u8 fuck;
/******************************************************************************************
*函数名:Touch_GetPhyXY()
* 参数:void
* 返回值:uint8_t 返回1表示成功,返回0表示失败
* 功能:读取XY物理位置
*********************************************************************************************/
uint8_t Touch_GetPhyXY(void)
{
 u8  i, j, k, min;
 u16 temp;
 u16 tempXY[2][SAMP_CNT], XY[2];// 采样
 
 for(i=0; i<SAMP_CNT; i++)
 {
  tempXY[0] = ADS_Read_AD(CMD_RDX_t);
  //LCD_ShowNum(70,150,ADC_X,5);      //输出X坐标
  tempXY[1] = ADS_Read_AD(CMD_RDY_t);
  //LCD_ShowNum(150,150,ADC_Y,5);
 }
 // 滤波
 for(k=0; k<2; k++)
 {
  // 降序排列
  for(i=0; i<SAMP_CNT-1; i++)
  {
   min=i;
   for (j=i+1; j<SAMP_CNT; j++)
   {
    if (tempXY[k][min] > tempXY[k][j])
     min=j;
    }
    temp = tempXY[k];
    tempXY[k] = tempXY[k][min];
    tempXY[k][min] = temp;
  }
  // 设定阈值
  if((tempXY[k][SAMP_CNT_DIV2]-tempXY[k][SAMP_CNT_DIV2-1]) > 5)
   return 0;
 // 求中间值的均值
  XY[k] = (tempXY[k][SAMP_CNT_DIV2]+tempXY[k][SAMP_CNT_DIV2-1])>>1;
 }
  if(XY[0]==0 || XY[1]==2047)return 0;   
  ADC_X=XY[0];
  ADC_Y=XY[1];
  // 矫正坐标
  hy_X = (uint16_t)(ADC_X*xfac+xoff);
  hy_Y = (uint16_t)(ADC_Y*yfac+yoff);
  return 1;
}


/******************************************************************************************
*函数名:ADS_Write_Byte(u8 num)
* 参数:u8 num
* 返回值:无
* 功能:向7843写入1byte数据
*********************************************************************************************/ 
void ADS_Write_Byte(u8 num)   

 u8 count=0; 
 
 for(count=0;count<8;count++) 
 {
  if(num&0x80)SET_TDIN();
  else CLR_TDIN();  
  num<<=1;   
  CLR_TCLK();//上升沿有效  
  SET_TCLK();     
 }       
}  


/******************************************************************************************
*函数名:ADS_Read_AD(u8 CMD) 
* 参数:u8 CMD
* 返回值:无
* 功能:从7846/7843/XPT2046/UH7843/UH7846读取adc值
*********************************************************************************************/  
uint16_t ADS_Read_AD(u8 CMD)  
{  
 u8 count=0;   
 u16 Num=0;  
 CLR_TCLK();         //先拉低时钟
    //CLR_TDIN();         //拉低数据线
 CLR_TCS();          //选中ADS7843 
 ADS_Write_Byte(CMD);//发送命令字
 delay_us(6);       //ADS7846的转换时间最长为6us
    //CLR_TCLK();
    delay_us(1);   
 SET_TCLK();         //给1个时钟,清除BUSY       
 CLR_TCLK();  
 for(count=0;count<16;count++) 
 {      
  Num<<=1;       
  CLR_TCLK();       //下降沿有效
        SET_TCLK();
  if(TDOUT_IN())Num++;   
 }   
 Num>>=4;            //只有高12位有效.
 SET_TCS();          //释放ADS7843   
 return(Num);
}


/******************************************************************************************
*函数名:AdjustTouchPanel()
* 参数:void
* 返回值:void
* 功能:触摸屏校准函数
*********************************************************************************************/
void AdjustTouchPanel(void)
{
 uint16_t touchXY[5][2];
 uint8_t cnt=0;
 uint16_t temp1,temp2,temp3;
 
 LCD_Clear(WHITE);                                //清屏
 LCD_SetColors(BLUE,WHITE);                       //设置前景色和背景色
 TP_Drow_Touch_Point(20,20,BLUE);                 //绘制第一个准星
 LCD_ShowString(40,50,"Touch Sight");
 while(1)
  {    
//   if(PEN_State()==RESET)
   if( fuck == 1)   // 如果外部中断响应  fuck 为 1 则说明有按键 执行读取物理坐标的操作
    {
      
     if(Touch_GetPhyXY())    //获取物理坐标成功
      {
       touchXY[cnt][0]=ADC_X;             //存储
       touchXY[cnt][1]=ADC_Y;             //
       LCD_ShowString(40,50,"              ");
                            //printf("%4d  \n\r",ADC_X);//touchXY[%d][0]=
                            //printf("%d",cnt,); touchXY[%d][1]=
                             while(PEN_State()== RESET);           //等待触笔松开
       
       delay_ms(50);                     //消抖
       cnt++;                             //跳转到下个点
       fuck = 0;
       EXTI->IMR |= 0x00000040;     //开启Line6
      }
label:    switch(cnt)
      {
       case 0:
        TP_Drow_Touch_Point(120,160,WHITE);        //清除第5个准星位置  TP_Drow_Touch_Point
        TP_Drow_Touch_Point(20,20,RED);          //绘制第一个准星
        break;
       case 1:
                                LCD_ShowNum(0,30,touchXY[cnt-1][0],4, 16);      //输出X坐标  LCD_ShowNum
                                LCD_ShowNum(70,30,touchXY[cnt-1][1],4, 16);
        TP_Drow_Touch_Point(20,20,WHITE);             //清除第1个准星位置
        TP_Drow_Touch_Point(20,300,BLUE);          //绘制第二zhou个准星
    //    fuck = 0;
    //    EXTI->IMR |= 0x00000040;     //开启Line6
         break;
       case 2:
                                LCD_ShowNum(0,300,touchXY[cnt-1][0],4, 16);      //输出X坐标
                                LCD_ShowNum(70,300,touchXY[cnt-1][1],4, 16);
        TP_Drow_Touch_Point(20,300,WHITE);       //清除第2个准星位置
        TP_Drow_Touch_Point(220,300,GREEN);        //绘制第三个准星 
    //    fuck = 0;
    //    EXTI->IMR |= 0x00000040;     //开启Line6
         break;
       case 3:
                                LCD_ShowNum(120,300,touchXY[cnt-1][0],4, 16);      //输出X坐标
                                LCD_ShowNum(170,300,touchXY[cnt-1][1],4, 16);
        TP_Drow_Touch_Point(220,300,WHITE);         //清除第3个准星位置
        TP_Drow_Touch_Point(220,20,BLACK);          //绘制第四个准星
    //    fuck = 0;
    //    EXTI->IMR |= 0x00000040;     //开启Line6
         break;
       case 4:
                                LCD_ShowNum(120,30,touchXY[cnt-1][0],4, 16);      //输出X坐标
                                LCD_ShowNum(160,30,touchXY[cnt-1][1],4, 16);
        TP_Drow_Touch_Point(220,300,WHITE);          //清除第4个准星位置
        TP_Drow_Touch_Point(120,160,BLUE);        //绘制第五个准星
    //    fuck = 0;
    //    EXTI->IMR |= 0x00000040;     //开启Line6
         break;
       case 5:
                                LCD_ShowNum(90,180,touchXY[cnt-1][0],4, 16);      //输出X坐标
                                LCD_ShowNum(150,180,touchXY[cnt-1][1],4, 16);
        
         temp1=abs(touchXY[3][0]-touchXY[0][0]);     //获取上方两点的X的ADC值的差
                                 temp2=abs(touchXY[2][0]-touchXY[1][0]);       //获得下方两点的X的ADC值的差
         if(abs(temp1-temp2)>ADJUST_DE)     //对比偏差是否大于阀值,若大于则不符合
          {
                                        cnt=0;                                  //归零
                                        goto label;                 //跳转重新开始
          }
          temp3 = temp1 + temp2;      //将上下X的ADC的值的差值相加
          xfac=200.0/(temp3>>1);//右移n位除以2的n次方      //获取x的比值
          temp3=temp3>>2;                    //将上下X的ADC的值的差值相加除以4和中心点的X的ADC值对比

          if(abs(touchXY[4][0]-touchXY[0][0]-temp3)>ADJUST_DE) //对比偏差是否大于阀值,若大于则不符合
          {
                                        cnt=0;                  //归零
                                        goto label;         //跳转重新开始
          }
          temp1=abs(touchXY[1][1]-touchXY[0][1]);     //获取左边两点的Y的ADC值的差
          temp2=abs(touchXY[2][1]-touchXY[3][1]); //获取右边两点的Y的ADC值的差
         if(abs(temp1-temp2)>ADJUST_DE)     //对比偏差是否大于阀值,若大于则不符合
          {
          cnt=0;                    //归零
            goto label;                   //跳转重新开始
          }
          temp3=temp1+temp2;      //将左右Y的ADC差相加
          yfac = 280.0/(temp3>>1);      //获取y的比值
          temp3=temp3>>2;                                   //将左右Y的ADC差的和除以4和中心点的Y的ADC值对比
          if(abs(touchXY[4][1]-touchXY[0][1]-temp3)>ADJUST_DE)   //对比偏差是否大于阀值,若大于则不符合
          {
          cnt=0;                    //归零
            goto label;                   //跳转重新开始
          }
          xoff=(240-xfac*(touchXY[0][0]+touchXY[3][0]))/2;      //获取到X的修正值
          yoff=(320-yfac*(touchXY[0][1]+touchXY[1][1]))/2;  //获取到Y的修正值
          LCD_ShowString(40,180," Finish");//校验完成
          delay_ms(500);             //延时
          return ;        //返回
      }
    }
  }
}

闷鱼闷闷不乐吃焖鱼
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
 楼主| 发表于 2013-9-17 23:02:20 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
那要怎么搞啊
闷鱼闷闷不乐吃焖鱼
回复 支持 反对

使用道具 举报

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
 楼主| 发表于 2013-9-17 23:03:11 | 显示全部楼层


 


闷鱼闷闷不乐吃焖鱼
回复 支持 反对

使用道具 举报

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
 楼主| 发表于 2013-9-17 23:05:12 | 显示全部楼层
if( fuck == 1)   // 如果外部中断响应  fuck 为 1 则说明有按键 执行读取物理坐标的操作
    {
      
     if(Touch_GetPhyXY())    //获取物理坐标成功
      {
       touchXY[cnt][0]=ADC_X;             //存储
       touchXY[cnt][1]=ADC_Y;             //
       LCD_ShowString(40,50,"              ");
                            //printf("%4d  \n\r",ADC_X);//touchXY[%d][0]=

………………………………………………
…………………………………………


比如说单步调试的时候把  他直接就忽略了 那个 fusk==1  和 if(Touch_GetPhyXY())    //获取物理坐标成功

直接跳到下面去执行了  我就是很纠结啊  怎么回事
闷鱼闷闷不乐吃焖鱼
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2013-9-15
在线时间
1 小时
发表于 2013-9-18 01:59:09 | 显示全部楼层
回复【5楼】闷鱼:
---------------------------------
回复【5楼】闷鱼:
---------------------------------
不知道,把if改成while语句来查询fusk==1可以不
永不放弃!!!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-9-18 10:43:24 | 显示全部楼层
回复【5楼】闷鱼:
---------------------------------
仿真的时候查看fuck是不是等于1,是程序运行的问题,还是变量的问题。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
 楼主| 发表于 2013-9-18 12:07:39 | 显示全部楼层
回复【7楼】正点原子:
---------------------------示波器 再有按键的时候 笔中断 是拉低的 (默认:没有触摸为高)然后,程序会进入到 外部中断 然后 fuck 标志位 被置 1
然后单步调试的时候 fuck 在有外部中断的情况下它就是 1 所以能够进去(这是正常的),不正常的情况就是 有时候没有触摸 一直 F10 然后 突然发现 程序居然直接跳过 if(fuck == 1 ) 和 if(Touch_GetPhyXY())    (//获取物理坐标成功 )直接执行到了 switch(cnt)下面的cnt = 1 的情况 ,事实上 cnt 也是 为 0 的 
还有就是 每次 导致了 第一次获取物理坐标的时候 坐标值全部是 0 ,这个也是一个问题 
) 
回复【6楼】WJY0821:
---------------------------------
好 我现在试试
闷鱼闷闷不乐吃焖鱼
回复 支持 反对

使用道具 举报

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
 楼主| 发表于 2013-9-18 12:08:09 | 显示全部楼层
回复【6楼】WJY0821:
---------------------------------
我试试  嘿嘿 搞了几天了 有点淡淡的忧伤
闷鱼闷闷不乐吃焖鱼
回复 支持 反对

使用道具 举报

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
 楼主| 发表于 2013-9-18 12:31:40 | 显示全部楼层
 


图一


现在 程序执行到了 while(fuck == 1) 然后我 继续按下 F10 他直接跳到了 224行  也就是 case1:下面的语句 然后 在 224行卡住 一直不动

然后我 直接 点击 打断 它 按下 keil 单步调试 的 那个红色的有个 × 的按钮  发现它一直在读 笔中断的那个标志位 貌似又在
207 行 那个里面去了  我有点凌乱 
一般我的触摸 触发了外部中断之后 是不需要再去读 笔中断了吧  我这样是为了消抖  但是 另外我在中断采用了 把标志位置 1 之后 就把中断给关闭了  165 行语句
     EXIT->IMR &= 0XFFFFFFBF; 


图二

然后在 图一的 209行 把它开启了 这样会有问题么  求解!!!!   

难道是中断用我这种单步调试的 方式调试是错误的么 
为什么 刚开始 调试 不引发外部中断 他也会 进入到 if(fuck == 1)
下面的语句呢  然后 有突然发现 它在 一直读 笔中断的 状态 
            以下是端口配置


图三

另外 TSC2046 引脚  X+ Y+ X- Y-;

我每次触摸的时候 发现 X+  Y+ 是从一开始的拉高置为低的   而X- 和 Y-
 一直保持为低  这样的状态是对的么    笔中断 在每次触摸液晶的时候 都会由高置低  这样 我的液晶和触摸控制芯片2046 都是没有问题的吧

闷鱼闷闷不乐吃焖鱼
回复 支持 反对

使用道具 举报

23

主题

292

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2013-9-17
在线时间
17 小时
 楼主| 发表于 2013-9-20 03:29:01 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
#define TP_PRES_DOWN 0x80  //触屏被按下   
#define TP_CATH_PRES 0x40  //有按键按下了   

if(tp_dev.sta & TP_PRES_DOWN) //触摸屏被按下
这个tp_dev.sta 是 触摸屏是否触摸的标志  但是我有个疑问 它应该是根据 笔中断的状态来赋值的 那么它与PEN是如何关联的呢
闷鱼闷闷不乐吃焖鱼
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-9-20 09:56:32 | 显示全部楼层
看TP_Scan代码。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-12 23:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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