18.ARM裸板实现电阻触摸屏控制实例(一)

目录

1.电阻触摸屏的原理

2.如何计算触摸屏的XY坐标

3.s3c2440的触摸屏接口

3.1.ADC的原理框图

3.2.触摸屏接口模式

3.3.编程要点

3.4.触摸屏主要寄存器描述

4.ADC中断(触摸屏)和中断控制器

5.编程控制触摸屏

实验1:触摸屏按下或松开检测

步骤:

① 创建宏定义

②编写初始化ADC寄存器函数:

③ADC和触摸屏中断使能:

④ADC中断或触摸屏中断处理

⑤处理触摸屏中断

⑥初始化函数

⑦结果演示

 源代码:




 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系统,编译烧录。

⑦结果演示


 

源代码:https://download.csdn.net/download/qq_36243942/11112931


发布了91 篇原创文章 · 获赞 247 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qq_36243942/article/details/89245779