打印

如何将触摸屏的校正参数写到外部FLASH中保存起来

[复制链接]
378|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kaloulin|  楼主 | 2019-11-27 14:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有些网友说触摸屏每次都要校正,很烦,那我们可以在校正之后,把得到的校正参数保存到EEPROM或者外部的FLASH中,
这里将给大家讲讲如何把校正的参数存放到我们开发板里面的FLASH(W25X16)中。

我把原先的那几个校正参数定义在了结构里面了,也增加了一个触摸屏校正标志
/* 触摸屏校正系数 */
//long double aa1=0,bb1=0,cc1=0,aa2=0,bb2=0,cc2=0;
/* 触摸屏校正系数结构体 */
long double cal_p[6]={0};
/* 触摸屏校正标志位 */
uint8_t cal_flag = 0xcc;

1、修改main函数,红色部分是重点

/**
  * @brief  主函数
  * @param  无  
  * @retval 无
  */
int main(void)
{  
  uint8_t k;
  
  /* 系统定时器 1us 定时初始化 */
  SysTick_Init();

  LED_GPIO_Config();
  
  LCD_Init();  
  /* GRAM扫描方向为左下脚->右上角 */
  Lcd_GramScan(2);
  LCD_Clear(0, 0, 320, 240, BACKGROUND);
  
  USART1_Config();
  
  SPI_FLASH_Init();
  //SPI_FLASH_SectorErase(0);
  
  /* 触摸屏IO和中断初始化 */
  Touch_Init();
/*-------------------------------------------------------------------------------------------------------*/  
  #if 1
  SPI_FLASH_BufferRead(&cal_flag, 0, 1);
  if( cal_flag == 0x55 )
  {
    SPI_FLASH_BufferRead((void*)cal_p, 1, sizeof(cal_p));
    SPI_FLASH_CS_HIGH();
    for( k=0; k<6; k++ )
          printf("\r\n rx = %LF \r\n",cal_p[k]);
  }
  else
  {
    /* 等待触摸屏校正完毕 */
    while(Touch_Calibrate() !=0);
  }
  #elif 0
  /* 等待触摸屏校正完毕 */
  while(Touch_Calibrate() !=0);
  #endif
/*------------------------------------------------------------------------------------------------------*/  
  //Touch_Init();
  /* 触摸取色板初始化 */
  Palette_Init();
  
  while( 1 )
  {
    if(touch_flag == 1)      /*如果触笔按下了*/
    {
      /*获取点的坐标*/
      if(Get_touch_point(&display, Read_2046_2(), &touch_para ) !=DISABLE)      
      {         
        Palette_draw_point(display.x,display.y);
        LED1_TOGGLE;      
      }
    }   
  }
}
2、修改Touch_Calibrate() 这个函数
123
int Touch_Calibrate(void)
{
    uint8_t i,k;
    u16 test_x=0, test_y=0;
    u16 gap_x=0, gap_y=0;
    Coordinate * Ptr;   
   
    for(i=0; i<4; i++)
    {        
        LCD_Clear(0, 0, 320, 240, BACKGROUND);        
        LCD_DispStr(110, 110, (uint8_t *)"Touch Calibrate......", RED);         
        LCD_DisNum(160, 90, i+1, RED);
      
        /* 适当的延时很有必要 */        
        Delay_ms(500);     
        DrawCross(DisplaySample.x,DisplaySample.y);  //显示校正用的“十”字
        do
        {
            Ptr=Read_2046_2();  //读取TSC2046数据到变量ptr            
        }
        while( Ptr == (void*)0 );     //当ptr为空时表示没有触点被按下
        ScreenSample.x= Ptr->x;    //把读取的原始数据存放到全局变量ScreenSample结构体
        ScreenSample.y= Ptr->y;
    }
  /* 用原始参数计算出 原始参数与坐标的转换系数。 */
    Cal_touch_para( &DisplaySample[0],&ScreenSample[0],&touch_para ) ;      
   
  /*取一个点计算X值*/
    test_x = ( (touch_para.An * ScreenSample[3].x) +
               (touch_para.Bn * ScreenSample[3].y) +
                touch_para.Cn
             ) / touch_para.Divider ;   
   
  /*取一个点计算Y值*/
    test_y = ( (touch_para.Dn * ScreenSample[3].x) +
               (touch_para.En * ScreenSample[3].y) +
               touch_para.Fn
             ) / touch_para.Divider ;
   
    /* 实际坐标与计算坐标的差 */
    gap_x = (test_x > DisplaySample[3].x)?(test_x - DisplaySample[3].x)DisplaySample[3].x - test_x);
    gap_x = (test_y > DisplaySample[3].y)?(test_y - DisplaySample[3].y)DisplaySample[3].y - test_y);
   
    //LCD_Rectangle(0,0,320,240,CAL_BACKGROUND_COLOR);
    LCD_Clear(0, 0, 320, 240, BACKGROUND);
   
    /* 可以通过修改这两个值的大小来调整精度 */
    if((gap_x>10)||(gap_y>10))
    {
      LCD_DispStr(100, 100, (uint8_t *)"Calibrate fail", RED);
      LCD_DispStr(100, 120, (uint8_t *)"try again", RED);     
      Delay_ms(2000);
      return 1;
    }   
   
    /* 校正系数为全局变量 */
//    aa1 = (touch_para.An*1.0)/touch_para.Divider;
//    bb1 = (touch_para.Bn*1.0)/touch_para.Divider;
//    cc1 = (touch_para.Cn*1.0)/touch_para.Divider;
//   
//    aa2 = (touch_para.Dn*1.0)/touch_para.Divider;
//    bb2 = (touch_para.En*1.0)/touch_para.Divider;
//    cc2 = (touch_para.Fn*1.0)/touch_para.Divider;
    cal_p[0] = (touch_para.An*1.0)/touch_para.Divider;  // aa1
    cal_p[1] = (touch_para.Bn*1.0)/touch_para.Divider;  // bb1
    cal_p[2] = (touch_para.Cn*1.0)/touch_para.Divider;  // cc1
   
    cal_p[3] = (touch_para.Dn*1.0)/touch_para.Divider;  // aa2
    cal_p[4] = (touch_para.En*1.0)/touch_para.Divider;  // bb2
    cal_p[5] = (touch_para.Fn*1.0)/touch_para.Divider;  // cc2     

    {
      cal_flag = 0x55;
      SPI_FLASH_SectorErase(0);
      SPI_FLASH_BufferWrite(&cal_flag, 0, 1);     
      SPI_FLASH_BufferWrite((void*)cal_p, 1, sizeof(cal_p));
      for( k=0; k<6; k++ )
        printf("\r\n tx = %LF \r\n",cal_p[k]);
    }
   
    LCD_DispStr(100, 100, (uint8_t *)"Calibrate Succed", RED);  
    Delay_ms(1000);
    return 0;   
}
3、修改Get_touch_point()这个函数
FunctionalState Get_touch_point(Coordinate * displayPtr,
                                Coordinate * screenPtr,
                                Parameter * para )
{
  FunctionalState retTHRESHOLD =ENABLE ;
  if(screenPtr==0)
  {
    /*如果获取的触点信息有误,则返回DISABLE*/
    retTHRESHOLD = DISABLE;   
  }
  else
  {   
    //if( para->Divider != 0 )  /* 每次都要校正时 */
    if( para->Divider != 1 )    /* 校正系数写到FLASH时 */
    {        
      //displayPtr->x = ( (aa1 * screenPtr->x) + (bb1 * screenPtr->y) + cc1);        
      //displayPtr->y = ((aa2 * screenPtr->x) + (bb2 * screenPtr->y) + cc2 );
      displayPtr->x = ( (cal_p[0] * screenPtr->x) + (cal_p[1] * screenPtr->y) + cal_p[2]);        
      displayPtr->y = ((cal_p[3] * screenPtr->x) + (cal_p[4] * screenPtr->y) + cal_p[5] );
    }
    else
    {
      retTHRESHOLD = DISABLE;
    }
  }
  return(retTHRESHOLD);
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

439

主题

448

帖子

0

粉丝