目录
1.电阻触摸屏的原理
四线电阻式触摸屏的结构如图1,在玻璃或丙烯酸基板上覆盖有两层透平,均匀导电的ITO层,分别做为X电极和Y电极,它们之间由均匀排列的透明格 点分开绝缘。其中下层的ITO与玻璃基板附着,上层的ITO附着在PET薄膜上。X电极和Y电极的正负端由“导电条”(图中黑色条形部分)分别从两端引 出,且X电极和Y电极导电条的位置相互垂直。引出端X-,X+,Y-,Y+一共四条线,这就是四线电阻式触摸屏名称的由来。当有物体接触触摸屏表面并施以 一定的压力时,上层的ITO导电层发生形变与下层ITO发生接触,该结构可以等效为相应的电路,如下图:
转自:http://www.elecfans.com/kongzhijishu/renjijiemian/596589.html
备注:LCD显示屏幕和触摸屏是分开的,触摸薄膜只是粘贴在LCD显示屏上面(尺寸相同)。
2.如何计算触摸屏的XY坐标
在连接如何计算之前,先了解一个电阻的分压原理:
例如现在有一个电阻R,这个电阻加上一个3.3V的电压
触摸屏的结构大致如下:
如何测量触电左边
测量x的坐标(实质测的是电压):
计算X坐标,在X+电极施加驱动电压Vdrive, X-电极接地,Y+做为引出端测量得到接触点的电压,由于ITO层均匀导电,触点电压与Vdrive电压之比等于触点X坐标与屏宽度之比。
测量Y坐标(实质是电压值):
1. 计算Y坐标,在Y+电极施加驱动电压Vdrive, Y-电极接地,X+做为引出端测量得到接触点的电压,由于ITO层均匀导电,触点电压与Vdrive电压之比等于触点Y坐标与屏高度之比。
ADC测量流程的分析:
①:ADC等待中断模式:
②测量X坐标和Y坐标
备注:所以如果想去获取触摸屏的话,只需要按照特定的控制顺序控制开关,然后读取ADC数据进行分析就可以了,在这里使用的S3C2440这款芯片。它的ADC就提供了这些接口的控制。
触摸屏使用基本流程:
1.按下触摸屏,产生触摸屏中断
2.在触摸中断中启动ADC转换器,获得触电X和Y方向的坐标
3.ADC完成转换,产生一个中断
4.在ADC中断中读取XY电压
5.启动定时器
6.定时器中断发生,判断当前是否按下,如果是则循环 1 - 5 步骤
7.松开,结束测量流程
3.s3c2440的触摸屏接口
3.1.ADC的原理框图:
3.2.触摸屏接口模式:
3.3.编程要点:
3.4.触摸屏主要寄存器描述:
- ADCTSC寄存器
这个寄存器主要是用来控制上面图示的s1-s5开关的。
- ADCDAT0
- ADCDAT1
- ADCUPDN
4.ADC中断(触摸屏)和中断控制器
中断控制器的框图:
下面是有关于ADC和触摸屏中断,各个寄存器的详细信息:
- INT_ADC:中断源
- SUBSRCPEND:用于判断是产生ADC中断还是触摸屏中断
bit10 = 1 表示ADC中断
bit9 = 1表示触摸屏中断
- INTSUBMASK:用于屏蔽或启动来自上一层的中断源
bit10 = 1 表示屏蔽ADC中断
bit9 = 1表示屏蔽触摸屏中断
- SRCPEND寄存器:判断是否有中断产生
- INTMOD:选择中断模式
- INTMASK寄存器:设置是否屏蔽某一个中断
- PRIORITY:中断优先级
- INTPEND:显示正在执行的中断
5.编程控制触摸屏
步骤:
1. 初始化ADC/触摸屏接口(设置ADC寄存器,采样时钟等)
2.设置触摸屏为处于等待中断模式,按下便会产生中断
3.设置中断:INTSUBMAST使能中断ADC和触摸屏中断(设置为不屏蔽,默认为屏蔽),INTMASK设置使能INT_ADC中断
4.按下触摸屏,进去触摸屏中断: ①开启自动采集XY坐标模式 ②启动ADC
5.转换完成,产生一个ADC中断, ①读取ADCDAT寄存器,读取XY数据 ②从第1步循环 ③ 启动定时器,动态检测触摸屏状态
6.定时器中断 : ① 检测触摸屏未按下,结束 ② 继续从第步开始循环
实验1:触摸屏按下或松开检测
步骤:
新建两个文件:touchscreen.c 和 touchscreen.h
① 创建宏定义
- 在touchscreen.h 中
备注:第一个包含SUBSRCPEND的中断位,ADC和触摸屏中断,第二个是ADCTSC寄存器的位,待会用到,ADCTSC的
寄存器描述如下:
他的名称也是和如下这张图对应的
②编写初始化ADC寄存器函数:
- 在touchscreen.c中:
如下:
/*设置触摸屏接口:寄存器
初始化相应寄存器
*/
void Adc_Ts_Reg_Init(void)
{
/*使能预分频,设置分频后的采样频率为1M*/
ADCCON = (1<<14)| (49<<6) |(0<<3);
ADCDLY = 0xff;
}
解释如下:
设置寄存器:
ACDCON寄存器描述:
其中PRSCVL分频系数的设置:
可以这样设置这个寄存器:
ADCDLY寄存器:
设置为默认值
③ADC和触摸屏中断使能:
代码如下:
//*设置中断源:ADC和触摸屏中断源初始化*/
void Adc_Ts_INT_Init()
{
/*步骤1:通过写相应的位清除中断,设置SUBSRCPND的bit10和bit9为1,
初始化先清除中断,以免干扰*/
SUBSRCPND = (1<<TS_INT_BIT) | (1<<ADC_INT_BIT);
/*步骤2:设置INTSUBMASK寄存器,不屏蔽ADC和TS中断*/
INTSUBMSK &= ~((1<<ADC_INT_BIT) | (1 <<TS_INT_BIT ));
/*步骤3:设置INTMSK不屏蔽,INT_ADC中断
含义:注册中断函数
1.中断号是 INTMASK的第31位,也就是INT_ADC中断,设置为 Service available
2.如果产生了INT_ADC中断就执行函数Adc_OR_Ts_IntHandler
*/
register_irq(31,Adc_OR_Ts_IntHandler);
}
备注:从上面ADC中断和中断控制器便可了解,这个函数的含义。目的即使初始化中断控制器,使我们能接收到ADC或触摸屏的IRQ中断并处理。
④ADC中断或触摸屏中断处理
当发生了ADC中断或者IRQ中断,便会进入Adc_OR_Ts_IntHandler函数,在这个函数中要判断到底产生的是ADC中断还是触摸屏中断,在这里我们只关心触摸屏中断
/*总中断:判断:SUBSRCPEND寄存器
bit10 = 1 表示ADC中断
bit9 = 1 表示触摸屏中断
方程参数:IRQ_Num(中断号)
*/
void Adc_OR_Ts_IntHandler(int IRQ_Num)
{
/*分辨中断源:
因为ADC中断和触摸屏中断在中断源中是属于同一个中断源
需要通过下一级,SUBSRCPND来区分是触摸屏中断还是ADC中断
*/
if(SUBSRCPND & (1<<TS_INT_BIT)) /*触摸屏中断*/
{
/*调用触摸屏中断服务函数*/
TS_Handler();
}
/*清除中断,bit9 -> 触摸屏中断, bit10-> ADC中断*/
SUBSRCPND = (1<<TS_INT_BIT) | (1<<ADC_INT_BIT);
/*中总中断处理函数中设置了清除中断的程序
即为IRQ_Handler 中,有这样的语句
SRCPND = (1<<bit);
INTPND = (1<<bit);
这样一来,SUBSRCPND、SRCPND、INTPND的中断标志位就全部清除了,可以
等待下一次中断的到来。
*/
}
如果发生的是触摸屏中断,则调用触摸屏中断处理函数TS_Handler。
注意:在进入中断函数退出之后一定要清楚中断标志位!
⑤处理触摸屏中断
在前面说过,在初始化的时候需要把ADC引脚上拉,等待中断的产生,如下:
其实S3C2440的ADC触摸屏控制器还可以检测屏幕松开,也就是说,按下或者松开都是可以产生一个触摸屏中断的,不过需要我们设置它。
通过寄存器可以知道ADCTSC有如下的含义,发现Bit8如果设置为1,表示关心松开中断,设置为0关心按下中断。
因此当我们初始化的时候可以可以这样做,时触摸屏处于等待按下模式,即设置:PULL_UP(s5)闭合,YM(s4)闭合,UD_SEN位设置为0。
代码如下:其中位的含义已给出
/*设置为触摸屏按下中断*/
void enter_wait_pen_down_mode(void)
{
/*通过修改ADCTSC的第8位,修改期待产生的中断*/
//设置ADCTSC的 bit8为0,说明期待的是按下中断,当检测按下时产生触摸屏中断
//注意,按下和松开中断进入的是同一个中断函数
ADCTSC = WAIT_PEN_DOWN | PULL_UP_SWITCH_ENABLE | YM_SWITCH_ENABLE | YP_SWITCH_DISABLE | XM_SWITCH_DISABLE | XP_SWITCH_DISABLE | WAIT_INT_MODE;
}
那当然还有一种就是触摸屏松开中断,实质只改变了 UD_SEN 位为1
代码如下:
/*设置为触摸笔松开中断*/
void enter_wait_pen_up_mode(void)
{
/*文档说明:
While waiting for Touch screen Interrupt,
XP_SEN bit should be set to ‘1’(XP Output disable) and
PULL_UP bit should be set to ‘0’(XP Pull-up enable).
此处设置PULL_UP 为使能
XP_SEM 设置为 禁止(disable)
YM_SEM 设置为 使能(enable)
*/
/*通过修改ADCTSC的第8位,修改期待产生的中断*/
//设置ADCTSC的 bit8为1,说明期待的是松开中断,当检测松开时产生触摸屏中断
ADCTSC = WAIT_PEN_UP | PULL_UP_SWITCH_ENABLE | YM_SWITCH_ENABLE | YP_SWITCH_DISABLE | XM_SWITCH_DISABLE | XP_SWITCH_DISABLE | WAIT_INT_MODE;
}
通过上面就可以去处理触摸屏中断函数了。
通过ADCDAT0的bit15可以知道当前屏幕的状态(按下或者松开)
因此可以把它作为按下或者松开的一句,如果在TS_Handler中通过检测ADCDAT0的bit15,发现屏幕是按下的,串口打印输入:”ts down“,然后把触摸屏中断模式,设置为松开中断,当松开触摸屏时又会产生一个中断,进入TS_Handler函数,通过检测ADCDAT0的bit15,发现屏幕是松开的,打印输出:”ts up“,然后把触摸屏中断模式,设置为按下中断。
代码如下:
/*进入触摸屏中断服务函数*/
/*当产生触摸屏按下中断或触摸屏松开中断执行此函数*/
void TS_Handler()
{
/*通过判断ADCDAT0寄存器的第15位就可以知道触摸屏是松开还是按下
UPDOWN[15] = 1 说明触摸笔处于松开状态,产生的中断是松开中断*/
if (ADCDAT0 & (1<<15))
{
//打印触摸笔松开
printf("\n\rts up\n\r");
//把中断模式切换成等待触摸屏按下中断
enter_wait_pen_down_mode();
}
else //否则,触摸笔产生按下中断
{
printf("\n\rts down\n\r");
/* 把触摸屏中断模式切换为松开中断 */
enter_wait_pen_up_mode();
}
}
这个代码就基本写完,接下来写一个初始化函数。
⑥初始化函数
初始化函数要做的就是,1.初始化ADC设置 2. 初始化中断设置 3.进入等待中断模式。
代码如下:
/*触摸屏初始化*/
void TS_init(void)
{
/*设置触摸屏接口:寄存器
初始化相应寄存器
*/
Adc_Ts_Reg_Init();
/*设置中断源:ADC和触摸屏中断源初始化
使能相应的中断。
*/
Adc_Ts_INT_Init();
/*进入等待中断模式*/
enter_wait_pen_down_mode();
}
最后在主函数中调用这个函数。
上传到Linux系统,编译烧录。