韦东山ARM裸机和uboot大全(第1期加强版)学习笔记18-第018课_ADC和触摸屏_第003~005节_电阻触摸屏原理和编程

一 电阻触摸屏的原理

  1. 基本原理:ADC对于触摸屏内置的电阻实时进行测量,触点的位置不同,ADC实时测量的电阻也不同。触摸屏和LCD是两个设备,触摸屏是一层覆盖到LCD上面的一层膜。
    在这里插入图片描述
    屏幕被点击的时候会被按压
    ①测量X方向坐标:XP接3.3V,XM接GND;YP,YM不接电源;测量YP电压即可得到X的坐标。
    ②测量Y方向坐标:YP接3.3V,YM接GND;XP,XM不接电源;测量XP电压即可得到Y的坐标。
  2. 触摸屏使用流程:
    ①按下触摸屏,产生触摸中断->
    ②触摸中断程序中:启动ADC(目的:获得XY坐标)->
    ③等待ADC完成,产生ADC中断->
    ④在ADC中断程序中:ADC中断中读取XY坐标->
    ⑤启动定时器->
    ⑥定时器中断发生,判断触摸屏是否仍然被按下?->
    ⑦按下:跳转到②;松开:结束流程
    在这里插入图片描述
    在这里插入图片描述

二 S3C2440 ADC & TOUCH SCREEN芯片手册学习

在这里插入图片描述
触摸屏中断处理流程:
在这里插入图片描述

三 程序设计流程

  1. 初始化ADC/TC接口:
  2. 开始触摸屏没有按下,设置TS处于“等待中断模式”
  3. 设置中断控制寄存器:INTSUBMASK/INTMSK
  4. 按下触摸屏,进入TS中断:①进入自动采集模式;②启动ADC
  5. ADC中断:①读数据;②再次进入“等待中断模式”;③启动定时器
  6. 定时器中断:①若松开触摸,结束;②若仍然按下,继续执行
    程序工作流程图参考如下(未包含定时器中断):
    在这里插入图片描述

四 程序代码实现流程(仅实现触摸屏按下和松开中断)

代码实现:

//总初始化函数
void touchscreen_init(void)
{
    
    
//1. 初始化ADC/TC接口;
	adc_ts_reg_init();
//2.设置中断控制寄存器:INTSUBMASK/INTMSK
	adc_ts_int_init();
//3. 开始触摸屏没有按下,设置TS处于“等待中断模式”
	enter_wait_pen_down_mode();
}
//4. 按下触摸屏,进入TS中断:①进入自动采集模式;②启动ADC
//5. ADC中断:①读数据;②再次进入“等待中断模式”;③启动定时器
//6. 定时器中断:①若松开触摸,结束;②若仍然按下,继续执行
//1 ADC/TC接口初始化函数
void adc_ts_reg_init(void)
{
    
    
	/* [15] : ECFLG,  1 = End of A/D conversion
	 * [14] : PRSCEN, 1 = A/D converter prescaler enable
	 * [13:6]: PRSCVL, adc clk = PCLK / (PRSCVL + 1)
	 * [5:3] : SEL_MUX, 000 = AIN 0
	 * [2]   : STDBM
	 * [0]   : 1 = A/D conversion starts and this bit is cleared after the startup.
	 */
	ADCCON = (1<<14) | (49<<6) | (0<<3);
	ADCDLY = 0xff;	
}

//2 ADC/TS中断初始化函数 
#define ADC_INT_BIT (10)
#define TC_INT_BIT  (9)
void adc_ts_int_init (void)
{
    
    
	/*为了避免误触发,清除中断标志位*/
	SUBSRCPND = (1<<TC_INT_BIT) | (1<<ADC_INT_BIT);
	/* 注册中断处理函数 */
	//中断总开关已经设置过了
	register_irq(31, AdcTsIntHandle);//31:中断号,	AdcTsIntHandle:中断处理函数
	/* 使能中断 */
	//中断子开关
	//ADC中断为INTSUBMSK寄存器bit10,
	//TC中断为INTSUBMSK寄存器bit9
	INTSUBMSK &= ~((1<<ADC_INT_BIT) | (1<<TC_INT_BIT));
}

//3 开始触摸屏没有按下,设置TS处于“等待中断模式”
//SS开关闭合,YM开关闭合,其余开关断开

/* ADCTSC's bits */
#define WAIT_PEN_DOWN    (0<<8)
#define WAIT_PEN_UP      (1<<8)

#define YM_ENABLE        (1<<7)
#define YM_DISABLE       (0<<7)

#define YP_ENABLE        (0<<6)
#define YP_DISABLE       (1<<6)

#define XM_ENABLE        (1<<5)
#define XM_DISABLE       (0<<5)

#define XP_ENABLE        (0<<4)
#define XP_DISABLE       (1<<4)

#define PULLUP_ENABLE    (0<<3)
#define PULLUP_DISABLE   (1<<3)

#define AUTO_PST         (1<<2)

#define WAIT_INT_MODE    (0b11)//等待中断
#define NO_OPR_MODE      (0)
void enter_wait_pen_down_mode(void)
{
    
    
	ADCTSC = WAIT_PEN_DOWN | PULLUP_ENABLE | YM_ENABLE | YP_DISABLE | XP_DISABLE |XM_DISABLE | WAIT_INT_MODE;
}

//4.1 中断服务函数
void AdcTsIntHandle(int irq)
{
    
    
	/* 如果是触摸屏中断 */
	if (SUBSRCPND & (1<<TC_INT_BIT))  
		Isr_Tc();

//	if (SUBSRCPND & (1<<ADC_INT_BIT))  /* ADC中断 */
//		Isr_Adc();

	/*清除中断*/
	SUBSRCPND = (1<<TC_INT_BIT) | (1<<ADC_INT_BIT);
}

//4.1.1 中断服务子函数-触摸屏中断处理函数
void Isr_Tc(void)
{
    
    
	//bit15=1表示up
	if (ADCDAT0 & (1<<15))
	{
    
    
		void enter_wait_pen_down_mode();
		printf("pen up\n\r");
	}
	//bit15=0表示down
	else	
	{
    
    
		/*需要检测触摸笔松开*/
		enter_wait_pen_up_mode();
		printf("pen down\n\r");
	}
}
void enter_wait_pen_up_mode(void)
{
    
    
	ADCTSC = WAIT_PEN_UP | PULLUP_ENABLE | YM_ENABLE | YP_DISABLE | XP_DISABLE | XM_DISABLE | WAIT_INT_MODE;
}

猜你喜欢

转载自blog.csdn.net/xiaoaojianghu09/article/details/104352839