野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 26395|回复: 6

关于如何把触摸屏的校准参数存到静态内存里

[复制链接]
发表于 2013-10-29 23:52:01 | 显示全部楼层 |阅读模式
http://www.firebbs.cn/forum.php?mod=viewthread&tid=711
首先附上调试过程开的帖子,感谢那么多热心网友回复,在此谢过。
在我的实验中,M3板上的EEPROM是无法实现这个功能的,在f103发出start信号后,硬件无法将SB置1,至今不知为何,以下是存入到flash的源代码。
一、首先是数据的获取和转换
触摸屏校准后产生的6个参数都是long double型的,而EEPROM和FLASH都是8位数据这样的存储,所以必须把几个参数进行转换再存入flash中。
数据的获取:
    aa1 = (touch_para.An*1.0)/touch_para.Divider;
        lcd_save[0] = aa1;
    bb1 = (touch_para.Bn*1.0)/touch_para.Divider;
        lcd_save[1] = bb1;
    cc1 = (touch_para.Cn*1.0)/touch_para.Divider;
        lcd_save[2] = cc1;

    aa2 = (touch_para.Dn*1.0)/touch_para.Divider;
        lcd_save[3] = aa2;
    bb2 = (touch_para.En*1.0)/touch_para.Divider;
        lcd_save[4] = bb2;
    cc2 = (touch_para.Fn*1.0)/touch_para.Divider;
        lcd_save[5] = cc2;

然后是数据的转换,这里我用了比较麻烦的算法,好像可以简单一点的。
extern long double lcd_save[6];  //我是在mian.c里面进行操作的,所以要把touch.c里的缓冲数组取过来。
u8 *save;
u8 buff ,Rx_Buffer[48];
u8 *buf = buff;
        save = (u8 *)lcd_save;
        for (  ; *save != '\0' ; save++ , buf++ )
                *buf = *save ;
        *buf = '\0' ;

二、数据的存储
SPI_FLASH_Init(); //这里记得初始化,我最开始忘记了结果错了很久。
/* Erase SPI FLASH Sector to write on 擦除内存 */
SPI_FLASH_SectorErase(FLASH_SectorToErase);                  
               
/* 将发送缓冲区的数据写到flash中 */
SPI_FLASH_BufferWrite(buff, FLASH_WriteAddress, sizeof (lcd_save));//sizeof(lcd_save)=48,这里也可以直接写48

三、数据的读取和转换
以下源代码我写在mian函数的开始部位,在这里把spi初始化用在了flash上,这部分完了之后就接上了野火的源代码了。
long double lcd_take[6];u8 Rx_Buffer[48];
long double *take ;
long double *rxbuf = lcd_take ;
        uint8_t i;
        SPI_FLASH_Init();
        SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, 48);

        take = (long double *)Rx_Buffer ;                                       
        for (i = 0  ;i < 6 ; take ++ , rxbuf ++ , i ++ )
                *rxbuf = *take ;
        *rxbuf = '\0' ;       

    SysTick_Init();                     /*systick 初始化*/
    LCD_Init();                                                        /*LCD初始化*/
    Touch_init();                                                /*触摸初始化*/

。。。。
四、校准参数的替换。
这一步就要把校准函数的内容删掉啦,然后写上下面这些就行。
int Touchl_Calibrate(void)
{        aa1 = lcd_take[0];
        bb1 = lcd_take[1];
        cc1 = lcd_take[2];
       
        aa2 = lcd_take[3];
        bb2 = lcd_take[4];
        cc2 = lcd_take[5];
          
        LCD_Str_6x12_O(100, 100,"Calibrate Success", 0);
    delay_ms(1000);

    return 0;   

}

这里有一点值得注意,画板初始化后使用的画点函数中有这一部分
FunctionalState Get_touch_point(Coordinate * displayPtr,                                Coordinate * screenPtr,
                                Parameter * para )
{
    FunctionalState retTHRESHOLD =ENABLE ;

    if(screenPtr==0)
    {
        /*如果获取的触点信息有误,则返回DISABLE*/
                                retTHRESHOLD = DISABLE;                       
    }
    else
        if( para->Divider != 0 )      //这里的para.Divider在野火历程中是通过四个点的校准得到的,而其实这里只要                                       //不为零就行,所以,大胆的将里面的para->Divider != 0改为1吧。
        {

最后,诚心感谢这个社区的人的帮助。
回复

使用道具 举报

发表于 2013-10-31 09:15:26 | 显示全部楼层
改成存放在stm32内部flash就更好了
回复 支持 反对

使用道具 举报

发表于 2013-11-2 17:28:49 | 显示全部楼层
把你程序发上来看看,好像你说的这样不行。

你那个数据转换那里不用这么麻烦,只需要把第一个传进去的参数转换成空指针就可以了。
SPI_FLASH_BufferWrite((void*)buff, FLASH_WriteAddress, sizeof (lcd_save));
SPI_FLASH_BufferRead((void*)buff, FLASH_WriteAddress, sizeof (lcd_save));
回复 支持 反对

使用道具 举报

发表于 2013-11-2 17:31:10 | 显示全部楼层
我实测出来的校正系数是下面的几个

/* 触摸屏校正系数 */
#if 1
long double aa1=0,bb1=0,cc1=0,aa2=0,bb2=0,cc2=0;
#elif 0
long double aa1=0.088370,\
            bb1=-0.000468,\
            cc1=-24.042172,\
            aa2=0.0001891,\
            bb2=0.062395,\
            cc2=-10.223455;
#endif
回复 支持 反对

使用道具 举报

发表于 2013-11-2 17:31:59 | 显示全部楼层
硬件的I2C我这边也测试了不行,估计需要用软件的模拟才可以。
回复 支持 反对

使用道具 举报

发表于 2013-11-2 17:44:54 | 显示全部楼层
使用条件编译(代码中红色部分),把原来的校正的代码屏蔽掉,把实测出的校正参数写到该函数中,
导致的结果是进不了中断,画不了。

int Touch_Calibrate(void)
{
    #if 1
    uint8_t i;
    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;
   
    #elif 0
    aa1=0.088370;
    bb1=-0.000468;
    cc1=-24.042172;
    aa2=0.0001891;
    bb2=0.062395;
    cc2=-10.223455;

    LCD_DispStr(100, 100, (uint8_t *)"Calibrate Succed", RED);  
    Delay_ms(1000);
    #endif
   
    return 0;   
}
回复 支持 反对

使用道具 举报

发表于 2013-11-2 18:07:35 | 显示全部楼层
我了个大艹,忽略了这里
    //if( para->Divider != 0 )     /* 每次都校正时 */
     if( para->Divider != 1 )      /* 校正系数保存到FLASH时 */
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-1 09:21 , Processed in 0.061350 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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