有些网友说触摸屏每次都要校正,很烦,那我们可以在校正之后,把得到的校正参数保存到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(&quot;\r\n rx = %LF \r\n&quot;,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 *)&quot;Touch Calibrate......&quot;, 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 *)&quot;Calibrate fail&quot;, RED);
LCD_DispStr(100, 120, (uint8_t *)&quot;try again&quot;, 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(&quot;\r\n tx = %LF \r\n&quot;,cal_p[k]);
}
LCD_DispStr(100, 100, (uint8_t *)&quot;Calibrate Succed&quot;, 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);
} |