因为电阻式接触屏便是一种传感器,它运用压力感应进行操控,将矩形区域中接触点(X,Y)的物理方位转化为代表 X坐标和 Y 坐标的电压。这儿先引进两个概念,物理坐标和逻辑坐标。物理坐标指接触屏上点的实践方位,通常以液晶上点的个数来衡量。逻辑坐标指这点被接触时A/D 转化后的坐标值。如图1,咱们假定液晶最左下角为坐标轴原点A ,在液晶就任取一点B (十字线穿插中心),B 在X 方向间隔A 10 个点,在Y 方向间隔A20 个点,则这点的物理坐标为(10,20)。假如咱们接触这一点时得到的X 向A/D 转化值为100,Y 向A/D 转化值为200,则这点的逻辑坐标为(100,200)。
常用的电阻式接触屏纠正办法有两点校准法和三点校准法。本文这儿介绍的是结合了不同的电阻式接触屏纠正法的优化算法:五点校对法。其间首要的原理是运用4点纠正法的份额运算以及三点纠正法的基准点运算。五点校对法优势在于能够愈加准确的核算出X和Y方向的份额缩放系数,一起供给了中心基准点,关于一些线性电阻系数比较差电阻式接触屏有很好的校对功用。
校对相关的变量首要有:
x[5] , y[5] 五点定位的物理坐标
xl[5] , yl[5] 五点定位的逻辑坐标
KX , KY 横纵方向弹性系数
XLC , YLC 中心基点逻辑坐标
XC , YC 中心基点物理坐标(数值选用LCD显现屏的物理长宽分辨率的一半)
接触屏常和点阵式液晶显现(LCD)屏叠加在一起配套运用,构成一个矩形的实践物理平面; 而由用户接触的接触点调集经过 A/D 转化器,得到详细显现坐标的调集,这个调集构成了一个逻辑平面。 因为存在差错,这两个平面并不重合,校准的效果便是要将逻辑平面映射到物理平面上,即得到触点在液晶屏上的方位坐标。 校准算法的中心思想也便是要树立这样一个映射函数现有的校准算法大多是根据线性校准, 即首要假定物理平面和逻辑平面之间的差错是线性差错,由旋转和偏移构成。

x[5] , y[5] 五点定位的物理坐标是已知的,其间4点别离设置在LCD的旮旯,一点设置在LCD正中心,作为基准纠正点。校对要害点和间隔布局如图。校对过程如下:
1. 经过先后点击LCD的4个旮旯的纠正点,获取4个旮旯的逻辑坐标值。
2. 核算 s1’ = xl[2] – xl[1] 、 s3’ = xl[3] – xl[4] 、 s2’ = yl[3] – yl[2] 、 s4’ = yl[4] – yl[1]
核算 s1 = x[2] – x[1] 、 s3 = x[3] – x[4] 、 s2 = y[3] – y[2] 、 s4 = y[4] – y[1],一般取点能够人为的设定s1 = s3 和 s2 = s4,以便利运算。
核算 KX = ( s1’ + s3’ )/2/s1 、KY = ( s2’ + s4’ )/2/s2
3. 点击LCD正中心,获取中心点的逻辑坐标,作为纠正的基准点。
4. 完结以上过程则校对完结。下次点击接触屏的时分获取的逻辑值XL和YL,可根据公式转化成物理值:
X = ( XL – XLC ) / KX + XC
Y = ( YL – YLC ) / KY + YC
换算出来的X , Y便是和LCD像素相对应的物理坐标值,便利对触屏呼应程序做区域判别。
以下是校对程序:
/****************************************************************************
* 名 称:void LCD_Adjustd(void)
* 功 能:校对电阻屏系数
* 进口参数: null
* 出口参数:无
* 说 明:null
* 调用办法:LCD_Adjustd();
****************************************************************************/
u8 LCD_Adjustd(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line7;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //为中断请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//Falling下降沿 Rising上升
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
EXTI_Init(&EXTI_InitStructure);
//显现中止刷屏
TIM_Cmd(TIM3, DISABLE); //使能TIMx外设
LCD_Clear(White );
LCD_printString(110,20, "Adjustd Begin" ,Black);
delay_ms(5000);
// 定第一个点
LCD_Draw_Target(20, 20, Red);
while( GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7));
while( (1-GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7)))
{
x[0] = Read_XY(CMD_RDX);
y[0] = Read_XY(CMD_RDY);
LCD_ShowNum(150,80,x[0],Black);
LCD_ShowNum(150,110,y[0],Black);
delay_ms(200);
LCD_Color_Fill(150,80,200,120, White);
}
// 定第二个点
LCD_Draw_Target(300, 20, Red);
LCD_Draw_Target(20, 20, White);
while( GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7));
while( (1-GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7)))
{
x[1] = Read_XY(CMD_RDX);
y[1] = Read_XY(CMD_RDY);
LCD_ShowNum(150,80,x[1],Black);
LCD_ShowNum(150,110,y[1],Black);
delay_ms(200);
LCD_Color_Fill(150,80,200,120, White);
}
if(abs(y[1]-y[0]) >60)
{
LCD_Clear(White );
LCD_printString(110,20, "Adjustd Fail" ,Black);
delay_ms(5000);
LCD_Clear(White );
return 1;
}
// 定第三个点
LCD_Draw_Target(20, 220, Red);
LCD_Draw_Target(300, 20, White);
while( GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7));
while( (1-GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7)))
{
x[2] = Read_XY(CMD_RDX);
y[2] = Read_XY(CMD_RDY);
LCD_ShowNum(150,80,x[2],Black);
LCD_ShowNum(150,110,y[2],Black);
delay_ms(200);
LCD_Color_Fill(150,80,200,120, White);
}
if(abs(x[2]-x[0]) >80)
{
LCD_Clear(White );
LCD_printString(110,20, "Adjustd Fail" ,Black);
delay_ms(5000);
LCD_Clear(White );
return 1;
}
// 定第四个点
LCD_Draw_Target(300, 220, Red);
LCD_Draw_Target(20, 220, White);
while( GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7));
while( (1-GPIO_ReadInputD
while( (1-GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7)))
{
x[3] = Read_XY(CMD_RDX);
y[3] = Read_XY(CMD_RDY);
LCD_ShowNum(150,80,x[3],Black);
LCD_ShowNum(150,110,y[3],Black);
delay_ms(200);
LCD_Color_Fill(150,80,200,120, White);
}
if((abs(y[2]-y[3]) >60) || (abs(x[1]-x[3]) >80))
{
LCD_Clear(White );
LCD_printString(110,20, "Adjustd Fail" ,Black);
delay_ms(5000);
LCD_Clear(White );
return 1;
}
// 定第五个点
LCD_Draw_Target(160, 120, Red);
LCD_Draw_Target(300, 220, White);
while( GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7));
while( (1-GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_7)))
{
x[4] = Read_XY(CMD_RDX);
y[4] = Read_XY(CMD_RDY);
delay_ms(200);
}
//核算校对系数
// KX = ((abs(y[0]-y[2])/280+abs(y[1]-y[3])/280)/2);
// KY = ((abs(x[0]-x[1])/200+abs(x[2]-x[3])/200)/2);
KX = (((float)(y[0]-y[2])/280+(float)(y[1]-y[3])/280)/2);
KY = (((float)(x[0]-x[1])/200+(float)(x[2]-x[3])/200)/2);
XC = 160;
YC = 120;
XLC = y[4];
YLC = x[4];
// 定点完结
LCD_Clear(White );
LCD_printString(110,20, "Adjustd Done" ,Black);
delay_ms(5000);
LCD_Color_Fill(110,20,200,35, White);
LCD_printString(110,20, "Testing" ,Black);
EXTI_InitStructure.EXTI_Line = EXTI_Line7;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //为中断请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//Falling下降沿 Rising上升
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line7); //铲除线路挂起位
//显现开端刷屏
TIM_Cmd(TIM3, ENABLE); //使能TIMx外设
Add_Button();
return 0;
}