七、lcd触摸屏控制
触摸屏就是当接触了屏幕上的图形按钮时,屏幕上的触觉反馈系统可根据预先编程的程式驱动各种连结装置,可用以取代机械式的按钮面板。2440连接的是电阻式触摸屏,利用压力感应进行控制,电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层透明氧化金属(透明的导电电阻)导电层,上面再盖有一层外表面硬化处理、光滑防擦的塑料层、它的内表面也涂有一层涂层、在他们之间有许多细小的(小于1/1000英寸)的透明隔离点把两层导电层隔开绝缘。当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,在X和Y两个方向上产生信号,然后送触摸屏控制器。控制器侦测到这一接触并计算出(X,Y)的位置,再根据模拟鼠标的方式运作。这就是电阻技术触摸屏的最基本的原理。所以电阻触摸屏可用较硬物体操作。其工作原理示意图为:
这里要说明,触摸屏与lcd是两个不同的模块,lcd是输出设备,用来显示,触摸屏是输入设备主要应用的AD转换。
在本章的第一段就有说明,触控器通过检测触点就可以检测出XY的坐标值,那么他是怎么检测的呢,在说明触摸屏检测原理之前,先说一下大家多很熟悉的东西------滑动变阻器,其实物图和原理图分别如下:
左边为滑动变阻器的实物图,右边是滑动变阻器的原理图,其基本原理都应该理解,以左边的原理图来分析,对电阻来说,当滑动点在的不同位置的时候,那么在本电路的有效电阻()的大小就会发生变化,进而导致电压表测得的电压发生变化,假如用数学公式来表示:
电压V=/(+) 同样的道理,假如知道公式V=/(+)中的电压值V的大小,由于的大小是固定不变的,所以就可以得到,得到的值后就可以知道触点在的位置(线性关系)。
触摸屏就是使用的这个原理,先看一下触摸屏的原理图:
上面这个图讲解的是通过触摸屏获得X轴的坐标,此时X+连接的电源正极,X-连接的是电源负极(接地),Y+连接的电压表(测量Y+到地的电压),Y-为高阻态,那么此时在X+到X-就会形成一个通路,当上下的两个电阻面没有接触(即没有按下触摸屏)的时候,Y+是测不到电压的;当触摸屏被按下的时候,其等效电路:
,此时Y+就可以测得电压,而且触点在X+到X-的不同位置,在Y+测得的电压是不同,因此这里只需要获得电压值,就可以得到对应的X轴上的坐标。当Y需要测量Y轴的坐标的时候,Y+连接的电源正极,Y-连接的是电源负极(接地),X+连接的电压表(测量X+到地的电压),X-为高阻态,测量方式Y类似。
原理就这么简单,下面介绍一下2440有关adc及其触摸屏相关的功能。
在2.5MHz A/D 转换器时钟下,2440的数模转换最大转换率为500ksps(ksps,全称kilo Samples per Second ,即采样千次每秒,是转化速率的单位),支持8通道10位转换的模拟信号的输入。对于触摸屏,可直接读取xy的坐标值。其连接示意图如下:
对于触摸屏来讲,提供了四个引脚的输入,分别为连接触摸屏的X正负极(XP,XM)和 连接触摸屏的Y正负极(YP ,YM),当该四个引脚作为触摸屏输入的时候,XM或者YM接地就可以,当不连接触摸屏的时候,XM、YM可作为普通的ADC引脚。在图中右下角,对于触摸屏会出现两个中断:INT_ADC表示ADC转换器已经转换完毕产生的中断信号,INT_TC表示触摸屏被按下的时候产生的中断信号。
对于触摸屏控制器,连接方式及其输出引脚的分析比较简单,对于触摸屏接口,其有四种模式:
⑴普通转换模式
单转换模式比较适用于一般目的的adc转换(不使用触摸屏的情况下使用),该模式可以通过设置寄存器ADCCON来进行初始化,并且可以通过读写寄存器ADCDAT0来获得ADC转换的数据。
⑵分离X/Y坐标轴转换模式
刚才前面在介绍触摸屏确定X、Y坐标轴位置的时候有介绍过,在该模式下X、Y的坐标值是分两次得到的:在ADCTSC寄存器的值为0x69时,进行的是X坐标轴的转换,转换成功后触发INT_ADC中断,X轴的转换结果存放在ADCDAT0寄存器中;在ADCTSC寄存器的值为0x9a时,进行的是Y坐标轴的转换,转换成功后触发INT_ADC中断,Y轴的转换结果存放在ADCDAT1寄存器中。
⑶自动(顺序)X、Y坐标轴转换模式
在分离X/Y坐标轴转换模式的时候,X、Y是分次转换的,当ADCTSC寄存器的值为0x0c时,为自动(顺序)转换,也就说控制器将自动一次得到X、Y的坐标值,转换成功后触发INT_ADC中断,X轴的转换结果存放在ADCDAT0寄存器中,轴的转换结果存放在ADCDAT1寄存器中。
当ADCTSC寄存器的值为0xd3时,为等待中断模式,在该模式下,当屏幕被按下时,会产生INT_TC中断信号,当检测到INT_TC模式的时候必须清除等待中断模式进入其他模式。
模式介绍完毕,接下来将会介绍有关的寄存器,首先要看的是ADC控制寄存器,ADCCON
下面详细说明各位的作用:
ENABLE_START:ADC转换使能位,假如READ_ START(ADCCON【1】)没有使能时,该位是无效的,该位为0,表示无作用,该位为1表示启动ADC转换,但是当硬件启动ADC转换时,该位被清除。
READ_ START :读转换后的数据时是否启动下次转换,为0表示当读取玩本次转换数据后不启动下次ADC转换;为1表示在读取数据时启动下一次adc转换。
STDBM :待机模式选择,该位为0表示进入正常操作模式;为1表示进入待机模式。
注意:当从待机模式中变换到正常工作模式时, ADC 的预分频器必须在之后的 3 个 ADC 时钟前使能
STDBM :ADC通道选择位:
000 = AIN 0 001 = AIN 1 010 = AIN 2 011 = AIN 3
100 = YM 101 = YP 110 = XM 111 = XP
这里需要注意的是:当触摸屏引脚( YM、 YP、 XM 和 XP) 为禁止时, 这些端口可以被用于 ADC 的模拟输入端口 ( AIN4、 AIN5、AIN6 和 AIN7)。
PRSCVL:AD转换分频系数值,大小分为为0~255;这里,ADC 频率应该设置为低于 PCLK 的 1/5例如 PCLK=10MHz,则 ADC 频率<2MHz。
ADC转换频率=PCLK/( PRSCVL +1 )
PRSCEN :AD转换分频使能位,当该位设置为1表示使能AD转换分频。
ECFLG :AD转换结束标记位(只读),该位为0表示正在进行AD转换,该位为1表示本次AD转换结束。
有关ADC控制寄存器已经介绍完毕,由于2440支持触摸屏控制,因此内部还存在ADC触摸屏控制寄存器ADCTSC:
下面详细说明一下ADC 触摸屏控制寄存器ADCTSC:
XY_PST :手动测量X、Y的坐标设置位
00 = 无操作模式 01 = X 方向测量
10 = Y 方向测量 11 = 等待中断模式
注意:在处于等待中断模式的时候,XP_SEN应该设置1(XP输出禁止)且PULL_UP应该设置为0(使能XP的上拉电阻)
AUTO_PST :自动(顺序)X、Y坐标转换控制位,该位为0表示为普通转换模式,改位为1表示自动(顺序)X、Y坐标轴转换模式。
注意:当且仅当在自动(顺序)X、Y坐标轴转换模式该位设置为。
PULL_UP :XP引脚上拉电阻使能位,该位为0表示使能XP的上拉电阻。在等待中断模式下,上拉电阻要有效,在触发中断后,上拉电阻要无效
XP_SEN :XP开关使能位,该位设置为1表示XP输出驱动禁止;该位设置为0表示XP输出驱动使能
XM_SEN :XM开关使能位,该位设置为0表示XM输出驱动禁止;该位设置为1表示XM输出驱动使能。
YP_SEN :YP开关使能位,该位设置为1表示YP输出驱动禁止;该位设置为0表示YP输出驱动使能。
YM_SEN :YM开关使能位,该位设置为0表示YM输出驱动禁止;该位设置为1表示YM输出驱动使能。
UD_SEN :检测笔尖起落状态位,该位为0表示当触笔按下时产生中断信号;该位为1表示当触笔抬起时产生中断信号
有关ADCTSC寄存器介绍已经介绍完毕,只是要注意的是,在睡眠模式期间应该分离 XP、 YP 与 GND 源以避免漏电电流。因为 XP、 YP 将在睡眠模式中保持为 ‘H’状态。
为了更加详细的说明触摸屏坐标时XP、XM、YP、YM接连情况,数据手册中给出一个参考表格:
这个表格是说明当要测量X坐标的时候:XP连接参考电压,XM接地,YP、YM分别是高阻态,ADC选中YP通道(即对YP进行AD测量);当要测量Y坐标的时候:YP连接参考电压,YM接地,XP、XM分别是高阻态,ADC选中XP通道(即对XP进行AD测量);
在2440内部,对于四中中断接口模式,普通转换模式、分离X/Y坐标轴转换模式、自动(顺序)X、Y坐标轴转换模式的采样延时时间(本次采样到下次采样的时间间隔)或者在等待中断模式中,当有触摸屏被按到是,多次发出INT_TC信号的每次间隔时间都可以通过ADCDLY寄存器来设置:
这里要注意的是,ADC 启动或间隔延时寄存器ADCDLY不能设置为0,默认值为0xff。在等待中断模式下,其工作时钟源频率为3.6864MHz。其余模式下工作频率为PCLK。
之前又提到,当需要读取AD转换结果时需要访问ADCDTA0和ADCDTA1寄存器,下面详细的介绍这两个寄存器:
XPDATA :触点在X坐标转换后的数值,或者在不同模式下,ADC对应引脚转换的数值大小范围为0~0x3ff
XY_PST :手动测量X或Y的坐标值:
00 = 无操作模式 01 = X 方向测量
1 0 = Y 方向测量 11 = 等待中断模式
AUTO_PST :自动(顺序)X、Y坐标轴转换模式设定位,该位设置为1表示开启自动(顺序)X、Y坐标轴转换模式;该位为0表示设置正常模式。
UPDOWN :在中断等待模式时,该位为0表示触摸屏被按下;该位为1表示触笔抬起状态。
对于ADCDAT1其寄存器作用与ADCDAT0雷同,只不过ADCDAT1【9:0】记录的是触点在Y坐标轴转换后的数值,不在赘述。
最后一个要说的是ADC触摸屏起落中断检测寄存器ADCUPDN,该寄存器记录的是触笔起落状态:
TSC_UP:触笔抬起中断标记位,该位为0表示没有发生触笔抬起;该位为1表示有触笔抬起
TSC_DN:触笔按下中断标记位,该位为0表示没有发生触笔按下;该位为1表示有触笔按下
到这里有关触屏的接扫介绍完毕,下面总结如下:
对于对触摸屏的设置难点是要来回变换中断接口模式(等待接收模式和自动测量XY坐标模式之间的切换),下面以代码说明是如何获得触摸屏坐标的,其步骤如下:
1、设置等待模式下的延时时间(此时频率为3.6864M) 给ADCDLY寄存器赋值
2、设置ADC转换的时钟频率 通过寄存器ADCCON来赋值
3、设置中断接口模式为等待中断模式 rADCTSC = 0xd3
4、清除中断挂起标志位 涉及到的寄存器有SUBSRCPND SRCPND INTPND
5、使能ADC及其触摸屏有关的中断 涉及到底寄存器有INTSUBMSK INTMSK
代码操作为下:
void touch_init() /*触摸屏初始化*/
{
unsigned intpreScaler = 50000000/2500000 - 1; //PCLK=50M 设置AD分频系数,最大频率为2.5MHz
//1、
设置等待模式下的延时时间(此时频率为3.6864M)给ADCDLY寄存器赋值
rADCDLY=36864; //等待中断模式延迟 (1/3.6864M)*36864=0.01s=10ms
//2、设置ADC转换的时钟频率通过寄存器ADCCON来赋值
rADCCON =(1<<14)|(preScaler<<6); //设置分频系数,并且设定分频有效
// 3、
设置中断接口模式为等待中断模式 rADCTSC =0xd3
rADCTSC=0xd3; //设置触摸屏为等待中断模式,等待触摸笔被按下(触笔按下触发中断)
// 4、
清除中断挂起标志位涉及到的寄存器有SUBSRCPNDSRCPND INTPND
rSUBSRCPND |=(1<<9); //清除子中断INT_TC标志位
rSRCPND |= (1<<31); //清除adc中断INT_ADC标志位
rINTPND |= (1<<31); //清除adc中断INT_ADC标志位
// 5、
使能ADC及其触摸屏有关的中断涉及到底寄存器有INTSUBMSK INTMSK
rINTSUBMSK &=~(1<<9); //使能INT_TC中断
rINTMSK &=~(1<<31);//使能INT_ADC中断
pISR_ADC =(unsigned int )touch_isr; //将中断执行函数如入地址赋给INT_TC中断
}
对于中断服务函数,主要涉及到坐标数据的读取、中断服务接口模式的判断及其模式的转换。
1、进入中断服务函数判断是触笔按下引起的中断还是触笔抬起引起的中断
2、设置XP的上拉电阻无效,切换到自动(顺序)得到X、Y坐标中断接口模式
3、在自动测量XY坐标模式下,重新设置延时间隔ADCDLY,注意初始频率为PCLK
4、设置寄存器ADCCON[0](此时保证ADCCON[0]=0) 使之开始转换ADC。
5、通过判断ADCCON【0】 ADCCON【15】 SRCPND【31】是否已经转化结束。
6、读取ADCDAT0 和ADCDAT1的低10位获取坐标值
7、清除中断挂起标志位涉及到的寄存器有SUBSRCPND SRCPND INTPND
8、转换模式为等待中断模式(ADCTSC=0xd3),并设置设置触笔抬起触发中断ADCTSC[8]=1
9、检测是否触笔是否抬起,并等待触笔抬起(rSUBSRCPND【9】=?1)
10、 重新设置延时间隔ADCDLY,在等待中断模式,注意初始频率为3.6864M
11、 设置触摸屏为等待中断模式,并设置下次触摸笔按下产生中断
12、 为了确保可以再次清除中断挂起标志位涉及到的寄存器有SUBSRCPNDSRCPND INTPND
中断服务函数代码实例为:
{
int xdata=0;
int ydata=0;
//1、进入中断服务函数判断是触笔按下引起的中断还是触笔抬起引起的中断
/*检测子中断源,判断是否是触摸屏(INT_TC)中断,且触摸笔按下*/
//正常情况下这里是因为触笔按下触发的中断
if(rSUBSRCPND &(1<<9)) //检查是否完成了中断位ADC
{
if(!(rADCDAT0&0x8000)) //当触笔抬起时,rADCDAT0【15?=1;
{
send_c(‘d‘);
send_c(‘o‘);
send_c(‘w‘);
send_c(‘n‘);
send_c(‘ ‘);
}
else
{
send_c(‘u‘);
send_c(‘p‘);
send_c(‘‘);
}
}
// 2、
设置XP的上拉电阻无效,切换到自动(顺序)得到X、Y坐标中断接口模式
rADCTSC|= (1<<3)|(1<<2); //XP上拉无效,自动(顺序)得到X、Y坐标
//3、
在自动测量XY坐标模式下,重新设置延时间隔ADCDLY,注意初始频率为PCLK
rADCDLY=40000; //正常转换模式延时(1/50M)*40000=0.8ms
//4、
设置寄存器ADCCON[0](此时保证ADCCON[0]=0)
使之开始转换ADC。
rADCCON|= 0x1; // 设置AD开始转换
当硬件启动ADC转换时,该位被清0
//5、
通过判断ADCCON【0】 ADCCON【15】
SRCPND【31】是否已经转化结束。
while(rADCCON & 0x1); //检查AD转换是否已经开始
while(!(rADCCON & (1<<15))); //等待AD转换结束
while(!(rSRCPND &(1<<31))); //检查AD中断标志位是否产生中断请求
//6、读取ADCDAT0
和ADCDAT1的低10位获取坐标值
xdata=(rADCDAT0&0x3ff);//取出低10位
/*获取X,Y坐标*/
ydata=(rADCDAT1&0x3ff);//取出低10位5、
通过判断ADCCON【0】 ADCCON【15】
SRCPND【31】是否已经转化结束。
//7、
清除中断挂起标志位涉及到的寄存器有SUBSRCPNDSRCPND INTPND
rSUBSRCPND |=(1<<9); //清中断
rSRCPND |=(1<<31);
rINTPND |=(1<<31);
//8、转换模式为等待中断模式(ADCTSC=0xd3),并设置设置触笔抬起触发中断ADCTSC[8]=1
/*设置触摸屏为等待中断模式,等待触摸笔抬起*/
rADCTSC =0xd3; //设置为等待中断模式 Wfait,XP_PU,XP_Dis,XM_Dis,YP_Dis,YM_En
rADCTSC=rADCTSC|(1<<8); //设置触笔抬起触发中断
//检查光标提起中断信号
//9、检测是否触笔是否抬起,并等待触笔抬起(rSUBSRCPND【9】=?1)
while(1) //检查抬笔状态
{
if(rSUBSRCPND & (1<<9))
//抬笔时再次触发中断
{
send_c(‘u‘);
send_c(‘p‘);
send_c(‘ ‘);
break;
}
}
//串口发送读取的数据
//Uart_Printf("count=%3d , XP=%4d, YP=%4d\n", count++, xdata,ydata);
send_c(‘x‘);send_c(‘:‘);
send_c(xdata/1000%10+48);
send_c(xdata/100%10+48);
send_c(xdata/10%10+48);
send_c(xdata%10+48);
send_c(‘y‘);send_c(‘:‘);
;
send_c(ydata/1000%10+48);
send_c(ydata/100%10+48);
send_c(ydata/10%10+48);
send_c(ydata%10+48);
send_c(0x0d);//发送换行符
send_c(0x0a);
// 10、
重新设置延时间隔ADCDLY,在等待中断模式,注意初始频率为3.6864M
rADCDLY=36864; //等待中断模式延迟(1/3.6864M)*36864=0.01s=10ms
// 11、
设置触摸屏为等待中断模式,并设置下次触摸笔按下产生中断
rADCTSC=0xd3; //设置触摸屏为等待中断模式,等待下次触摸笔按下
// 12、
为了确保可以再次清除中断挂起标志位涉及到的寄存器有SUBSRCPNDSRCPND INTPND
rSUBSRCPND |=(1<<9); //清中断
rSRCPND |=(1<<31);
rINTPND |=(1<<31);
}