(本节笔记的实验代码,在这里:https://github.com/elvinsys/arm_tq2440/tree/master/1_uboot/1-17.touchscreen)
一、 原理解析
1. 分类:电阻式、电容式、红外线技术、表面声波技术、矢量压力传感技术;现代主要用到电阻式和电容式两种触摸屏。
2. 电阻屏工作原理:
当手指触屏是,两个相互绝园的导电层在触点链接,顶层电压加到底层,致使底层电压发生变化,控制器检测到电压变化,自动完成电压的A/D转换,从而算出触点坐标。
电容屏工作原理:
给工作面同上一个低电压,用户触屏时,手指头吸收一个电流,电流从触屏四角流出,计算电流比例从而得出触点坐标。相对于电阻屏,电容屏的有点事感应灵敏,支持多点触控。
二、 电阻屏驱动程序设计
大致步骤为:
1. 初始化
1.1 设置AD转换时钟
1.2 中断屏蔽设置
1.3 进入等待中断模式(按下)
2. TC中断处理(按下)
2.1 启动XY坐标自动转化
2.2 等待转化完成,获取坐标
2.3 消除中断
2.4 进入等待TC中断模式(弹起)
2.5 消除弹起中断
2.6 打印X、Y坐标
2.7 进入等待中断模式(按下)
(在dev中touch ts.c,记得修改dev/Makefile)
1. 初始化函数——void ts.init();
1.1 设置AD转换时钟(参考2440芯片手册第16章 ADC & Touch Screen Interface)
ADCCON R/W 0x5800 0000
PRSCEN [14] 1 = ENABLE 预分频使能
PRSCVL [13:6] (PCLK = 10MHz, ADC < 2MHz)
设置AD = 1MHz = PCLK / (PRSCVL +1) 而PCLK = 50MHz, 因此,PRSCVL = 49
STDBM [2] 0 = Normal Operation mode
1.2 设置中断屏蔽位
INT_ADC分为 INT_ADC_S 和 INT_TC两种子中断(参考2440芯片手册第14章 Interrupt Controller)
INT_S :AD转换完成后,出发一个中断
TC :触摸板被触碰,触发一个中断
本次实验采用屏蔽ADC_S中断,用轮询方式检查ADC是否完成了转换,并使能TC。
INTMASK R/W 0x4a00 0008
INT_ADC [31] 0 = AVAILABLE 取消屏蔽
INTSUBMSK R/W 0x4a00 001c
INT_ADC_S [10] 1 = MASH
INT_TC [9] 0 = AVAILABLE
1.3 进入等待中断模式(按下)
ADCTSC R/W 0x5800 0004
XY_PST [1:0] 11:Wating for interrupt Mode
UD_SEN [8] 0 = 等待按下 1 = 等待弹起 (参考2440芯片手册16-3 Touch Screen Interface Mode 4 Wating for Interrupt Mode)
ADCTSC = 0xd3; /* XP_PU,XP_DIS,XM_DIS,YP_DIS,YM_EU,0xd3 = 0 1101 0011 */
2. TC中断处理函数——void tc_handler();
2.1 启动X,Y坐标自动转换
ADCCON R/W 0x5800 0000
ENABLE_START [0] 1 = A/D conversion starts
ADCTSC R/W 0x58000004
AUTO_PST [2] 1 = AUTO 转换xy的position
2.2 等待转化完成,获取坐标
ADCCON R/W 0x5800 0000
ECFLG [15] 0 = ADC in process
//该位置1,则说明转化完成 1 = ADC end
ADCDAT0 R 0x5800 000c
XPDATA [9:0] Data value: 0~3F //存放X坐标
ADCDAT1 R 0x5800 0010
YPDATA [9:0] Data value: 0~3F //存放Y坐标
2.3 消除按下后产生的中断
SUBSRCPND R/W 0x4a00 0018
INT_TC [9] 1 = Requested
SPCPND R/W 0x4a00 0000
INT_ADC [31] 1 = Requested
INTPND R/W 0x4a00 0010
INT_ADC [31] 1 = Requested
2.4 进入TC等待弹起
ADCTSC = 0xd3
UD_SEN [8] 1 = 等待弹起
检查 SUBSRCPND [9] INT_TC是否为1
2.5 清除弹起的中断
SUBSRCPND R/W 0x4a00 0018
INT_TC [9] 1 = Requested
SPCPND R/W 0x4a00 0000
INT_ADC [31] 1 = Requested
INTPND R/W 0x4a00 0010
INT_ADC [31] 1 = Requested
2.6 打印出X,Y坐标printf("\n x is %d, y is %d \n \r", xdata , y data);
2.7 再次进入按下等待状态
ADCTSC = 0Xd3;
3. 在main.c中加入ts_init()
在interrupt.c 中 的 void handle_init()中加入
case 31:
tc_handler();
break;