您的位置 首页 被动

s3c2440的触摸屏使用与校对

触摸屏是当今最流行的一种人机交互接口,它被广泛地应用于手机等消费类电子产品中,目前这种技术有向PC机方向发展的趋势。基于原理的不同,…

触摸屏是当今最盛行的一种人机交互接口,它被广泛地运用于手机等消费类电子产品中,现在这种技能有向PC机方向开展的趋势。根据原理的不同,触摸屏能够分为电阻式、电容式、外表声波式等。电阻式是运用较广的一种触摸屏,它的原理是经过丈量横向和纵向的电阻值来取得触点的坐标。

s3c2440集成了4线制电阻式的触摸屏接口,触点坐标的检测是经过A/D转化来完结的。s3c2440一共有4种触摸屏接口形式,其间,主动(接连)XY坐标转化形式和等候中止形式运用地比较常见。等候中止形式是在触笔落下时产生一个中止,在这种形式下,A/D触摸屏操控寄存器ADCTSC的值应为0xD3,在体系呼应中止后,XY坐标的丈量形式有必要为无操作形式,即寄存器ADCTSC的低两位有必要清零。主动(接连)XY坐标转化形式是体系顺次转化触点的X轴坐标和Y轴坐标,其间X轴坐标值写入寄存器ADCDAT0的低10位中,Y轴坐标写入寄存器ADCDAT1的低10位中,在这种形式下,体系同样会产生中止信号。在一般情况下,为完结触摸屏功用,先是设置为等候中止形式,在产生中止后,再设置为主动(接连)XY坐标转化形式,顺次读取触点的坐标值。在完结触摸屏功用的进程中,除了上面介绍的几个寄存器外,还会用到以下寄存器。寄存器ADCTSC的第8位能够完结是触笔落下中止仍是触笔抬起中止,假如写过根据视窗运用程序的人对这一点会很熟悉,它就如同单击鼠标操作相同,一次单击操作包含两个动作:按下和开释,这两个动作能够完结不同的指令。寄存器ADCTSC的第3位能够挑选上拉电阻的使能,在等候中止形式下,上拉电阻要有用,在触发中止后,上拉电阻要无效。寄存器ADCTSC的第2位用于挑选主动(接连)XY坐标转化形式。触笔抬起/落下中止状况寄存器ADCUPDN的低2位能够判别触笔在何种状况下引起的中止。A/D延时寄存器ADCDLY能够设置开端中止到真实开端A/D转化这段时刻的延时长度,它的时钟源频率为3.68MHz。

在开端完结触摸屏功用之前,还需求处理一个问题,那就是触摸屏的校对。触摸屏和LCD是两种不同的物理器材。关于一个分辨率为320×240的LCD,它的宽度为320个像素,高度为240个像素。而触摸屏处理的数据是点的物理坐标,该坐标是经过触摸屏操控器并重得到的。要想完结触摸屏上的物理坐标与LCD上的像素点坐标一一对应上,两者之间就需求必定的转化,即校对。并且电阻式触摸屏咱们本身的原因参数会产生变化,因而需求经常性的校对。比较常见的校对办法是三点校对法,它的原理是:

设LCD上每个点PD的坐标为[XD,YD],触摸屏上每个点PT的坐标为[XT,YT]。要完结触摸屏上的坐标转化为LCD上的坐标,需求下列公式进行转化:
XD=A×XT+B×YT+C
YD=D×XT+E×YT+F
咱们其间一共有六个参数(A,B,C,D,E,F),因而只需求三个取样点就能够求得这六个参数。这六个参数一旦确认下来,只需给出恣意触摸屏上的坐标点PT,代入这个公式,就能够得到它所对应的LCD上像素点的坐标PD。详细的求解进程就不细讲,只给出终究的成果。已知LCD上的三个取样点为:PD0,PD1,PD2,它们所对应的触摸屏上的三个点为:PT0,PT1,PT2。A,B,C,D,E,F这六个参数终究的成果都是一个分式,并且都有一个一起的分母,为:
K=(XT0-XT2)×(YT1-YT2)-(XT1-XT2)×(YT0-YT2)
那么这六个参数别离为:
A=[(XD0-XD2)×(YT1-YT2)-(XD1-XD2)×(YT0-YT2)] / K
B=[(XT0-XT2)×(XD1-XD2)-(XD0-XD2)×(XT1-XT2)] / K
C=[YT0×(XT2×XD1-XT1×XD2)+YT1×(XT0×XD2-XT2×XD0)+YT2×(XT1×XD0-XT0×XD1)] / K
D=[(YD0-YD2)×(YT1-YT2)-(YD1-YD2)×(YT0-YT2)] / K
E=[(XT0-XT2)×(YD1-YD2)-(YD0-YD2)×(XT1-XT2)] / K
F=[YT0×(XT2×YD1-XT1×YD2)+YT1×(XT0×YD2-XT2×YD0)+YT2×(XT1×YD0-XT0×YD1)] / K

下面的程序是完结触摸屏功用的简略实例——以触点为中心,制作出一个赤色的边长为10个像素的正方形。触点的坐标是用下面办法得到的:当触笔落下时,进入中止,然后读取触点处的坐标,直到触笔的抬起,才退出该次中止。咱们触摸屏需求校对,因而在运用之前需求进行校对处理。但并不是每次运用都要校对,只需坐标没有产生漂移,就不需求再次校对。所以在进行一次校对后,只需把那几个参数保存起来,下次需求时直接运用前次保存下来的参数即可。在这儿,咱们运用EEPROM来保存这几个参数,即A,B,C,D,E,F,K别离保存在以0x20,0x30,0x40,0x50,0x60,0x70,0x80为首地址内存的接连4个字节空间内,别的内存地址0x1F保存一个标识信息,当为0x6A时,一共这几个参数已核算并保存好了,只需从上述内存地址中读取参数就行,而当为其他值时,就需求进行校对。校对时,需求三个取样点,在这儿咱们选取LCD上的(32,24),(160,216),(288,120)为这三个取样点,咱们在这三个取样点上画一个十字(如下图所示),只需求顺次点击这三个点,即可完结触摸屏的校对。

…………
volatile U32 LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];
unsigned char iic_buffer[8];
unsigned char devAddr=0xa0;
int A,B,C,D,E,F,K;

volatile int xdata, ydata;

int flagIIC;//IIC标志
int flagTS;//触摸屏标志
…………

//触摸屏中止
void __irq ADCTs(void)
{
rADCTSC = (1<<3)|(1<<2);//上拉电阻无效,主动接连XY坐标转化形式舱位
rADCDLY = 40000;//延时

rADCCON|=0x1;//开端A/D转化

while(rADCCON & 0x1)
;//查看A/D转化是否开端
while(!(rADCCON & 0x8000))
;//等候A/D转化的完毕

while(!(rSRCPND & ((U32)0x1<<31)))
;//判别A/D中止的悬挂位

xdata=(rADCDAT0&0x3ff);//读取X轴坐标
ydata=(rADCDAT1&0x3ff);//读取Y轴坐标

flagTS = 1;//置标志

rSUBSRCPND|=0x1<<9;
rSRCPND = 0x1<<31;
rINTPND = 0x1<<31;
rINTSUBMSK=~(0x1<<9);
rINTMSK=~(0x1<<31);//清A/D中止,舱位A/D中止屏蔽 rADCTSC =0xd3;//再次设置等候中止形式,这一次是判别触笔的抬起
rADCTSC=rADCTSC|(1<<8);//设置触笔抬起中止 while(1)//等候触笔的抬起
{
if(rSUBSRCPND & (0x1<<9))//查看A/D触摸屏中止悬挂
{
break;//假如触笔抬起,则跳出该循环
}
}

rADCDLY=50000;
rSUBSRCPND|=0x1<<9;
rINTSUBMSK=~(0x1<<9);
rSRCPND = 0x1<<31;
rINTPND = 0x1<<31;//再次清A/D中止,舱位A/D中止屏蔽
rADCTSC =0xd3;//设置等候中止形式,为下一次触笔的落下做准备
}

//制作“十”字型
void drawCross(U32 x,U32 y,U32 color)
{
int i;
for(i=x-10;iPutPixel(i,y, color);
for(i=y-10;iPutPixel(x,i, color);
}

//触摸屏校对
void TSCal(void)
{
int i=0;
int xt[3],yt[3];
Brush_Background(0,0,LCD_WIDTH,LCD_HEIGHT,0xFFFFFF);
drawCross(32,24,0xFF0000);
Draw_ASCII(36,28,0xFF0000,one);
drawCross(160,216,0xFF0000);
Draw_ASCII(164,220,0xFF0000,two);
drawCross(288,120,0xFF0000);
Draw_ASCII(292,124,0xFF0000,three);

//顺次读取三个采样点的坐标值
for(i=0;i<3;i++)
{
while(flagTS==0)
delay(500);
xt[i]=xdata;
yt[i]=ydata;
flagTS=0;
}

//核算参数
K=(xt[0]-xt[2])*(yt[1]-yt[2])-(xt[1]-xt[2])*(yt[0]-yt[2]);
A=(32-288)*(yt[1]-yt[2])-(160-288)*(yt[0]-yt[2]);
B=(xt[0]-xt[2])*(160-288)-(32-288)*(xt[1]-xt[2]);
C=yt[0]*(xt[2]*160-xt[1]*288)+yt[1]*(xt[0]*288-xt[2]*32)+yt[2]*(xt[1]*32-xt[0]*160);
D=(24-120)*(yt[1]-yt[2])-(216-120)*(yt[0]-yt[2]);
E=(xt[0]-xt[2])*(216-120)-(24-120)*(xt[1]-xt[2]);
F=yt[0]*(xt[2]*216-xt[1]*120)+yt[1]*(xt[0]*120-xt[2]*24)+yt[2]*(xt[1]*24-xt[0]*216);
}

//把一个32位整型转化为4个8位字节型,并写入EEPROM中
void wrTStoIIC(int coef,unsigned char address)
{
iic_buffer[0]=(unsigned char)((coef&0xFF000000)>>24);
iic_buffer[1]=(unsigned char)((coef&0x00FF0000)>>16);
iic_buffer[2]=(unsigned char)((coef&0x0000FF00)>>8);
iic_buffer[3]=(unsigned char)(coef&0x000000FF);
wr24c02a(address,iic_buffer,4);
}

//读取EEPROM中的4个8位字节,并把它们组合成一个32位的整型。
int rdTStoIIC(unsigned char address)
{
int temp;
rd24c02a(address,iic_buffer,4);
temp=(iic_buffer[0]<<24)|(iic_buffer[1]<<16)|(iic_buffer[2]<<8)|(iic_buffer[3]);
return temp;
}

void Main(void)
{

LCD_Init();
rLCDCON1|=1;

rADCDLY=50000;//设置延时
rADCCON=(1<<14)+(9<<6);//设置A/D预分频 rADCTSC=0xd3;//设置触摸屏为等候中止形式。 pISR_ADC = (U32)ADCTs; ………… flagTS = 0;
flagIIC = 1;

//读取EEPROM中的标志地址内容,用于判别触摸屏校对的参数是否已核算并保存好
rd24c02a(0x1F,iic_buffer,1);

if(iic_buffer[0]!=0x6A)//假如触摸屏的校对参数没有核算并保存,从头校对
{
TSCal();
rINTMSK=~((0x1<<31)|(0x1<<27));//舱位IIC中止屏蔽
iic_buffer[0]=0x6A;
wr24c02a(0x1F,iic_buffer,1);//置“触摸屏校对参数核算并坚持好”的标志信息
delay(3000);//等候一段时刻,必定要有,不然EEPROM不能正确读写
wrTStoIIC(A,0x20);
delay(3000);
wrTStoIIC(B,0x30);
delay(3000);
wrTStoIIC(C,0x40);
delay(3000);
wrTStoIIC(D,0x50);
delay(3000);
wrTStoIIC(E,0x60);
delay(3000);
wrTStoIIC(F,0x70);
delay(3000);
wrTStoIIC(K,0x80);

}
else//假如触摸屏校对参数已准备好,则直接读取
{
A=rdTStoIIC(0x20);
delay(3000);
B=rdTStoIIC(0x30);
delay(3000);
C=rdTStoIIC(0x40);
delay(3000);
D=rdTStoIIC(0x50);
delay(3000);
E=rdTStoIIC(0x60);
delay(3000);
F=rdTStoIIC(0x70);
delay(3000);
K=rdTStoI%&&&&&%(0x80);
}

Brush_Background(0,0,LCD_WIDTH,LCD_HEIGHT,0xFFFFFF);

while(1)
{
if(flagTS)
{
flagTS=0;
xLcd = (A*xdata+B*ydata+C)/K;//核算X轴坐标
yLcd = (D*xdata+E*ydata+F)/K;//核算Y轴坐标
Brush_Background(xLcd-5,yLcd-5,xLcd+5,yLcd+5,0xFF0000);//制作正方形
}
delay(1000000);
}
}

本文介绍的程序要略显杂乱一些,这儿对触摸屏校对和中止再做一总结:
1、一般地,在第一次运用触摸屏时,需求校对一次,今后能够不再校对,除非产生了显着的漂移。咱们是把校对参数存储在EEPROM中,下次再运用时,只需读取该组数据即可。EEPROM中的0x1F地址用于存储校对参数标识信息,在现已校对过的情况下,该位内容为0x6A,这样在下次开机运用触摸屏时,只需读取该位内容,就可知道触摸屏是否已校对,没有校对则需求进行校对,现已校对过了则无需再重复校对了。
2、先设置等候中止形式,以等候触摸屏中止的产生,当中止产生并进入中止今后,再转化为主动接连XY坐标转化形式,可正确读取触点的坐标值。在中止程序中,当触笔落下时进入中止,当触笔抬起时退出中止,程序只记载触笔落下时触点的坐标值。

该段程序的演示图如下:

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/beidong/265514.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部