对于触摸屏首先说说他们的工作原理:
1 电阻屏
当手指触摸屏幕时,两个相互绝缘的导电层在触摸点处连接,顶层的5伏电压就会加到底层触摸点处,底层该点的电压会发生改变。控制器检测到该点的
变化后,将该点的电压进行A/D转换,得到的值与5伏相比,再乘以该轴总长度即可得触摸点靠地那一端的坐标。
2 电容屏:
给工作面通上一个很低的电压,当用户触摸屏幕时, 手指头吸收走一个很小的电流, 这个电流分从触摸屏四个角上的电极中流出, 并且理论上流经这四个电极的电流与手指到四角的距离成比例, 控制器通过对这四个电流比例的精密计算, 得出触摸点的位置。
接下来一电阻屏为例做一个裸机驱动程序:
此程序可分三部分: 触摸屏初始化,中断处理和进入中断;
一: 触摸屏初始化:ts_init()
对于触摸屏的驱动设计其实就是ADC和中断;所以初始化的因为就是ADC和中
1 配置ADCCON;主要是使能ADC及计算AD转换时钟 公式:AD=pclk/(PRSCVL+1) 其中 AD自己定义,一般不能大于2MHZ,pclk 是时钟频率,PRSCVL 需要配置的;我的配置是:ADCCON = (0<<16)|(1<<14)|(49<<6)|(0<<2)|(0<<1)|(0<<0);//
2 开启使能中断,有两个 1 开启ADC中断,2 开启触摸屏下/上中断 寄存器分别是 VIC1IRQSTATUS = (1<<31);/// ADCUPDN = (1 << 0);///
3 一切准备就绪 开始等待中断 //注;在此驱动中只要是需要等待中断的就要使用语句 ADCTSC = 0xd3; 来进入等待中断模式;
二:中断处理:irq_adc()
1 对于触摸屏两种获取x y 坐标点的方法 一是手动获取,二是自动获取 我再次用的是自定获取x y坐标,并开启ADC ; 寄存器设置是: ADCTSC = (1<<2); ADCCON |= (1<<0);
2 既然用了自动转换,又已经开启了ADC,现在要做的就是等待ADC完成,判断方法是:while (!(ADCCON & (1<<15)));
3 当转换完成之后,它会自动的将x y坐标的值分别放在ADCDAT0[9:0]和ADCDAT1[9:0],如果我们想用的话就要在这两个寄存器中取值;
4 到这里中断处理已经完成了,所以我们要清除中断,以便于下次中断,有两个需要清除 1 清除ADC中断,2 清除按下中断 寄存器设置是: ADCCLRINT = 0; ADCCLRINTPNDNUP = (1 << 0);
5 按下去之后还没有弹起,所以要等待弹起中断; 寄存器设置时: ADCTSC = 0xd3; ADCTSC |= (1<<8);
6 当弹起中断产生之后,在这一阶段的中断圆满结束,但还要做的就是清除弹起中断 寄存器设置是:
ADCCLRINTPNDNUP = (1 << 0);
VIC0ADDRESS = 0; //
VIC1ADDRESS = 0; //
ADCCLRINT = 0;
ADCUPDN = 0x0;
7 接下来就是等待进入下次中断; ADCTSC = 0xd3;
三: 进入中断;
对于进入中断有两种方法,一是 在ts.c 中直接写一个函数来将中断处理的函数地址给了相应寄存器,但好像有问题 他只能进一次中断 代码是:
void ts_irq_init()
{
VIC1VECTADDR30 = irq_adc;
VIC1INTENABLE |=(1<<30);//|(1<<31);//使能INT_ADC ,INT_PENDNUP
VIC1INTSELECT = VIC1INTSELECT&(~(1<<30));//
}
二是在我以前写得中断程序interrupt.c中将其添加进去,没错误 代码如下:
ts_irq()
{
//保存环境
__asm__(
"sub lr,lr,#4\n"
"stmfd sp!, {r0-r12,lr}\n"
:
:
);
irq_adc();
__asm__(
"ldmfd sp!,{r0-r12,pc}^\n"
:
:
);
}
VIC1VECTADDR30 = ts_irq; //保存触摸屏处理地址
VIC1INTENABLE |=(1<<30);//|(1<<31);//使能INT_ADC ,INT_PENDNUP
具体代码如下: