其坐标识别原理如下图:
当手指触摸屏幕时,两个相互绝缘的导电层在触摸点处连接,顶层的5伏电压就会加到底层触摸点处,底层该点的电压会发生改变,控制器检测到该点的变化后,将该点的电压进行A/D转换,得到的值与5伏相比,再乘以该轴总长度即可得触摸点靠地那一端的坐标:X=L*V(I)/5
也就是说我们要得到触点坐标的话,只需要将触点的电压进行A/D转换再用公式计算一下便可。那么触摸屏驱动的重点应该是在什么时候,对什么地点的电压进行A/D转换。S3C2440中的A/D转换器便有这种功能:
如图所示为S3C2440中ADC与触摸屏的接口框架图。
我们从上面的结构图和数 据手册可以知道,该ADC模块总共有8个通道可以进行模拟信号的输入,分别是AIN0、AIN1、AIN2、AIN3、YM、YP、XM、XP。那么 ADC是怎么实现模拟信号到数字信号的转换呢?首先模拟信号从任一通道输入,然后设定寄存器中预分频器的值来确定AD转换器频率,最后ADC将模拟信号转 换为数字信号保存到ADC数据寄存器0中(ADCDAT0),然后ADCDAT0中的数据可以通过中断或查询的方式来访问。
从下面的程序中可以看到这些信号是如何别控制的:
中断模式用到的寄存器:
设置触摸屏接口为等待中断模式:
寄存器ADCTSC的第2位用于选择自动(连续)XY坐标转换模式
寄存器ADCTSC的第3位可以选择上拉电阻的使能,在等待中断模式下,上拉电阻要有效
- rADCTSC=0xd3;
//[0:7]Wfait,XP_PU(在等待中断模式下,上拉电阻要有效),XP_Dis,XM_Dis,YP_Dis,YM_En
A/D延时寄存器ADCDLY可以设置开始中断到真正开始A/D转换这段时间的延时长度,它的时钟源频率为3.68MHz。
- rADCDLY=50000;
//Normal conversion mode delay about (1/3.6864M)*50000=13.56ms
当然还要开中断,注意INT_TC为子中断:
- rINTMSK=~BIT_ADC;
//ADC Touch Screen Mask bit clear,enable ADCint - rINTSUBMSK=~(BIT_SUB_TC);//enable
sub ADCint
如果INT_TC发生,选择XY转换模式,启动A/D转换:
- rADCTSC=(1<<3)|(1<<2);
//Pull-up disable,(在触发中断后,上拉电阻要无效) Seq. X,Y postion measure. - saveAdcdly=rADCDLY;
//save ADCDLY(启动延时) - rADCDLY=40000;
//Normal conversion mode delay about (1/50M)*40000=0.8ms -
- rADCCON|=0x1;
//start ADC
- 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检查AD转换是否完成:
- while(!(rSRCPND
& (BIT_ADC))); //check if ADC is finished with interrupt bit
- xdata=(rADCDAT0&0x3ff);
- ydata=(rADCDAT1&0x3ff);//读取转换结果,x轴坐标值放入rADCDAT0,y轴坐标值放入ADCDAT1
设置触摸屏为等待中断模式
- rADCTSC
=0xd3; //Waiting for interrupt//[0:7]Wfait,XP_PU,XP_Dis,XM_Dis,YP_Dis,YM_En
等待触笔抬起后,恢复现场,结束中断函数。
- rADCTSC=rADCTSC|(1<<8);
// Detect tylus up sinterrupt 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~! ");//触笔抬起! -
break; //if Stylus is up(1) state -
} -
} [page]
- #define
REQCNT 30 - #define
ADCPRS 9 //YH 0627 - #define
LOOP 1 -
- void
__irq AdcTsAuto(void); -
- int
count=0; - volatile
int xdata, ydata; -
- void
Test_Touchpanel(void) - {
-
-
rADCDLY=50000; //Normal conversion mode delay about (1/3.6864M)*50000=13.56ms -
rADCCON=(1<<14)+(ADCPRS<<6); //ADCPRS En, ADCPRS Value -
-
Uart_Printf("ADC touch screen test "); -
-
rADCTSC=0xd3; //[0:7]Wfait,XP_PU(在等待中断模式下,上拉电阻要有效),XP_Dis,XM_Dis,YP_Dis,YM_En -
-
pISR_ADC = (int)AdcTsAuto; -
rINTMSK=~BIT_ADC; //ADC Touch Screen Mask bit clear,enable ADCint -
rINTSUBMSK=~(BIT_SUB_TC);//enable sub ADCint -
-
Uart_Printf(" Type any key to exit!!! "); -
Uart_Printf(" Stylus Down, please...... "); -
Uart_Getch(); -
-
rINTSUBMSK|=BIT_SUB_TC;//get a key then mask sub ADCint ;exit -
rINTMSK|=BIT_ADC;//mask ADCint -
Uart_Printf("Touch Screen Test is Finished!!! "); -
- }
-
-
- void
__irq AdcTsAuto(void) - {
-
int i; -
U32 saveAdcdly; -
-
if(rADCDAT0&0x8000) -
{ -
//Uart_Printf(" Stylus Up!! "); -
rADCTSC&=0xff; // Set stylus down interrupt bit -
} -
//else -
//Uart_Printf(" Stylus Down!! "); -
-
rADCTSC=(1<<3)|(1<<2); //Pull-up disable,(在触发中断后,上拉电阻要无效) Seq. X,Y postion measure. -
saveAdcdly=rADCDLY; //save ADCDLY(启动延时) -
rADCDLY=40000; //Normal conversion mode delay about (1/50M)*40000=0.8ms -
-
rADCCON|=0x1; //start ADC -
-
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~!! -
//conversion over -
while(!(rSRCPND & (BIT_ADC))); //check if ADC is finished with interrupt bit,等待中断清零? -
-
xdata=(rADCDAT0&0x3ff); -
ydata=(rADCDAT1&0x3ff);//读取转换结果,x轴坐标值放入rADCDAT0,y轴坐标值放入ADCDAT1 -
-
//YH 0627, To check Stylus Up Interrupt. -
rSUBSRCPND|=BIT_SUB_TC; -
ClearPending(BIT_ADC);//清楚中断标志位 -
rINTSUBMSK=~(BIT_SUB_TC);//使能中断? -
rINTMSK=~(BIT_ADC); -
-
rADCTSC =0xd3; //Waiting for interrupt//[0:7]Wfait,XP_PU,XP_Dis,XM_Dis,YP_Dis,YM_En -
rADCTSC=rADCTSC|(1<<8); // Detect tylus up sinterrupt 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~! ");//触笔抬起! -
break; //if Stylus is up(1) state -
} -
} -
-
Uart_Printf("count=d XP=d, YP=d ", count++, xdata, ydata); //X-position Conversion data -
-
rADCDLY=saveAdcdly; //恢复ADCDLY原值 -
rADCTSC=rADCTSC&~(1<<8); // Detect stylus Down interrupt signal.检查触笔落下中断(下一次检测) -
rSUBSRCPND|=BIT_SUB_TC; -
rINTSUBMSK=~(BIT_SUB_TC); // Unmask sub interrupt (TC)//使能中断 -
ClearPending(BIT_ADC); - }
效果图:
上一篇:S3C2440裸奔触摸屏
下一篇:运行时域和加载时域(运行地址和加载地址)
推荐阅读最新更新时间:2024-03-16 14:31