2440触摸屏的设置
扫描二维码
随时随地手机看文章
一、触摸屏原理:
可以参考相关资料,本人参考的是阿南的<<>入门与实践>>中有关触摸屏的内容。
二、2440触摸屏的设置
1、ADCON: ADC控制寄存器
#define ADCPRS 24
rADCCON=(1<<14)+(ADCPRS<<6);
使能读启动操作。
AD转换器的预分频值为24,注意:
AD转换频率=PCLK/(分频值+1),且AD的最高频率为2.5M,这里PCLK=50M,所以AD的转换频率为2M.
2、ADCTSC ADC触摸屏控制寄存器
rADCTSC=0xd3;
当笔尖落下时触摸屏控制器产生中断(INT_TC)信号。
YM输出驱动器使能
YP输出驱动器禁止
XM输出驱动器禁止
XP输出驱动器禁止
等待中断模式
注意:自动x,y方向测量是指当测完x跟y后产生ADC中断。
3、ADCDLY ADC启动或初始化延时寄存器
rADCDLY=50000;
设置一个适当的便可
4、设置中断服务函数
pISR_ADC = (int)AdcTsAuto;//设置中断函数地址
rINTMSK=~BIT_ADC;//ADC Touch Screen Mask bit clear
rINTSUBMSK=~(BIT_SUB_TC); //触摸屏中断
三、触摸屏检测及校正
1、触摸屏的检测思路类似于按键检测,以下为检测一个点的思路:
(1)、设置等待中断,按下有效
(2)、按下进入中断后读取x,y数据
(3)、读取完成后设置成弹起中断,等待一个动作结束
(4)、结束后进入下一次准备。
程序如下:
void __irq AdcTsAuto(void)
{
//解摸屏按下,产生中断
U32 saveAdcdly;
if(rADCDAT0&0x8000)
rADCTSC&=0xff;// Set stylus down interrupt bit
//关闭XP上拉,启动自动顺序x/y转换
rADCTSC=(1<<3)|(1<<2);//Pull-up disable, Seq. X,Y postion measure.
//设置延时时间
saveAdcdly=rADCDLY;
rADCDLY=40000;
//开始AD转换
rADCCON|=0x1;//start ADC
//AD转换启动后开始位会被清0
while(rADCCON & 0x1);//check if Enable_start is low
//等待转换结束
while(!(rADCCON & 0x8000));//check if EC(End of Conversion) flag is high, This line is necessary~!!
//查询INT_ADC中断,直到查到结束中断标志
while(!(rSRCPND & (BIT_ADC)));//check if ADC is finished with interrupt bit
//产生中断标志说明x,y已经转换结束,读取数据。
xdata=(rADCDAT0&0x3ff);
ydata=(rADCDAT1&0x3ff);
//按下标志
touchedflag=TRUE;
//check Stylus Up Interrupt.
//清中断,并且重开中断,再次设置等待中断,这一次设置等待弹起中断。
rSUBSRCPND|=BIT_SUB_TC;
ClearPending(BIT_ADC);
rINTSUBMSK=~(BIT_SUB_TC);
rINTMSK=~(BIT_ADC);
rADCTSC =0xd3;//Waiting for interrupt
rADCTSC=rADCTSC|(1<<8); // Detect stylus up interrupt signal.
//查询等待弹起中断标志,直到查到弹起。
while(1)//to check Pen-up state
{
if(rSUBSRCPND & (BIT_SUB_TC))//check if ADC is finished with interrupt bit
{
//Uart_Printf("Stylus Up Interrupt~!n");
break;//if Stylus is up(1) state
}
}
//此时,一个触摸屏动作检测已经完成,输出坐标信息。
Uart_Printf("count=%03dXP=%d, YP=%dn", count++, xdata, ydata);//X-position Conversion data
//再次设置成按下中断,等待下一次动作
rADCDLY=saveAdcdly;
rADCTSC=rADCTSC&~(1<<8); // Detect stylus Down interrupt signal.
rSUBSRCPND|=BIT_SUB_TC;
rINTSUBMSK=~(BIT_SUB_TC);// Unmask sub interrupt (TC)
ClearPending(BIT_ADC);
}
2、触摸屏的校正
触摸屏校正的目的是为了把触摸屏上的坐标跟LCD上坐标一一对应起来。
如上图,假设LCD与触摸屏的点是一一对应的,LCD上四个角的点为人为设置的点(实际只需要上左上跟右下两个点就可以了,还有两个点是用来做平均的),触摸屏上四个角的点为LCD上四个点对应转换来的数值。(ax,ay)为正常工作时点击的点,(x,y)为(ax,ay)对应的坐标。
那么LCD与触摸屏的关系为:
x=x0+(x1-x0)*(ax-ax0)/(ax1-ax0)
y=y0+(y1-y0)*(ay-ay0)/(ay1-ay0)
具体步骤:
以320*240的屏举例:
(1)、设置四个LCD点(30,30)、(30,210)、(290,210)、(290,30)
(2)、在屏幕上依次画出这四个点(以四个点为中心点的十字形),并且依次点击这四个点,分别记下四个点转换出来的数值。(ax0,ay0),(ax0,ax1),(ax1,ay1),(ax1,ay0)
(3)、由x=x0+(x1-x0)*(ax-ax0)/(ax1-ax0),可以把(x1-x0)/(ax1-ax0)转换成常量系数Kx,那么
x=x0+(ax-ax0)*Kx,Kx=(x1-x0)/(ax1-ax0),这样只需记下x0,ax0,Kx三个值便可。
同样的:
y=y0+(y1-y0)*(ay-ay0)/(ay1-ay0), y=y0+(ay-ay0)*Ky, Ky=(y1-y0)/(ay1-ay0),只需记下y0,ay0,Ky便可.
(4)、校正完成,正常工作时当点击触摸屏时产生(ax,ay),则
x=x0+(ax-ax0)*Kx
y=y0+(ay-ay0)*Ky
便可以很容易求出实际坐标。
校正程序如下:
//触摸屏校正
//x=x0+(x1-x0)*(ax-ax0)/(ax1-ax0)
//x=x0+(ax-ax0)*Kx
//Kx=(x1-x0)/(ax1-ax0)
//x0,ax0,Kx
//同理
//y=y0+(y1-y0)*(ay-ay0)/(ay1-ay0)
//y=y0+(ay-ay0)*Ky
//Ky=(y1-y0)/(ay1-ay0)
//y0,ay0,Ky
volatile U32 touchedflag=FALSE;
//必要的参数
typedef struct cali
{
intx0;
intax0;
floatKx;
inty0;
intay0;
floatKy;
}TCpara;
typedef struct Point
{
int x;
int y;
}POINT;
//LCD四个校正点
POINT LCDPoint[4]=
{
30,30,//左上
30,210,//左下
290,210,//右下
290,30//右上
};
TCpara TCcal;
void touchsrc_calibration()
{
U32 i;
//int x=30,y=30;
//int LCDx1=30,LCDy1=30,LCDx2=30,LCDy2=150,LCDx3=290,LCDy3=210;
//TCx3=0,TCy3=0,TCx4=0,TCy4=0;
//float A,B,C,D,E,F,K;
//float K
Lcd_ClearScr(0);
for(i=0;i<4;i++)
{
//分别画出四个点Glib_Line(LCDPoint[i].x-10,LCDPoint[i].y,LCDPoint[i].x+10,LCDPoint[i].y,(U32)(255<<11));
Glib_Line(LCDPoint[i].x,LCDPoint[i].y-10,LCDPoint[i].x,LCDPoint