S3C2440触摸屏驱动详解
2440的触摸屏转换接口搭载在ADC接口之上,使用上比ADC接口多了一些花样,首先,触摸屏接口有几种转换模式
1. 普通转换模式
单转换模式是最合适的通用ADC转换。此模式可以通过设置ADCCON(ADC控制寄存器)初始化并且通过读写ADCDAT0(ADC数据寄存器0)就能够完成
2. 分离的X/Y方向转换模式
触摸屏控制器可以工作在两个转换模式之一。方向转换模式如下方法操作。X方向模式写X方向转换数据到ADCDAT0,故触摸屏接口产生中断源给中断控制器。Y方向模式写Y方向转换数据到ADCDAT1,故触摸屏接口产生中断源给中断控制器。
3. 自动(顺序)X/Y方向转换模式
自动(顺序)X/Y方向转换模式操作如下。触摸屏控制器顺序变换触摸X方向和Y方向。在自动方向转变模式中触摸控制器在写入X测量数值到ADCDAT0和写入Y测量数值到ADCDAT1后,触摸屏接口产生中断源给中断控制器。
4. 等待中断模式
当笔尖落下时触摸屏控制器产生中断(INT_TC)信号。等待中断模式设置值为rADCTSC=0xd3; // XP_PU,XP_Dis,XM_Dis,YP_Dis,YM_En触摸屏控制器产生中断信号(INT_TC)后,必须清除等待中断模式。(XY_PST设置到无操作模式)
使用触摸屏ADC需要设置以下几个寄存器
设置转换引脚的模式,以及转换模式
中断转换时间
另外还需要注意一点
具体查看代码
#ifndef __TOUCH_H #define __TOUCH_H #include "def.h" #include "2440addr.h" #include "uart0.h" extern u16 xPoint; extern u16 yPoint; extern u8 touchState; void TouchInit(void); void TouchMode1GetValue(void); //extern volatile int xdata,ydata; //extern volatile U8 penDownFlag; //落笔标志 //extern volatile int A,B,C,D,E,F,K; //void TouchInit(void); //#define ADCPRS 26 //AD转换器预分频值 #endif
#include "touch.h" u16 xPoint = 0; u16 yPoint = 0; u8 touchState = 0; void __irq AdcTsAuto(void) { u8 i = 0,j=0; u16 xtemp[10] = {0}; u16 ytemp[10] = {0}; xPoint = 0; yPoint = 0; rSRCPND |= BIT_ADC; rINTPND |= BIT_ADC; rSUBSRCPND|= BIT_SUB_TC; //清除中断标志 rINTMSK |= BIT_ADC; //关闭中断 rADCTSC &= ~(3<<0);//清除等待中断模式,上拉不禁止 rADCTSC |= (1<<3)|(1<<2); //XP上拉禁止,自动顺序X,Y测量 for(i = 0; i < 10; i++)//循环获取十次数据 { rADCCON |=0x1; //使能AD转换 while(rADCCON & 0x1); //判断使能ADC转换后被清零 while(!(rADCCON &0x8000)); //等待转换结束 xtemp[i] = (rADCDAT0&0x3ff); ytemp[i] = (rADCDAT1&0x3ff); } //两组值进行冒泡排序 for(i = 0; i < 10; i++) { for(j = 0; j < i; j++) { if(xtemp[j]> xtemp[j+1]) { xtemp[j] = xtemp[j]+xtemp[j+1]; xtemp[j+1] = xtemp[j]-xtemp[j+1]; xtemp[j] = xtemp[j]-xtemp[j+1]; } if(ytemp[j]> ytemp[j+1]) { ytemp[j] = ytemp[j]+ytemp[j+1]; ytemp[j+1] = ytemp[j]-ytemp[j+1]; ytemp[j] = ytemp[j]-ytemp[j+1]; } } } for(i = 2; i < 8; i++)//去掉两个最大值两个最小值 { xPoint+= xtemp[i]; yPoint+= ytemp[i]; } xPoint/=(8-2); yPoint/=(8-2); touchState = 1; printf("xPoint %d yPoint %d \r\n",xPoint,yPoint); rSRCPND |= BIT_ADC; rINTPND |= BIT_ADC; rSUBSRCPND|= BIT_SUB_TC; //清除中断标志 rADCTSC = 0xd3; //等待中断模式,正常AD转换,XP上拉使能,XP,XM,YP输出禁止,YM输出使能 rINTMSK &=~BIT_ADC;//打开中断 } //触摸屏中断初始化 void TouchInit(void) { rADCDLY = 40000; //正常转换模式下延时 rADCCON = (1<<14)|(69<<6); //使能AD转换预分频器 70分频 rADCTSC = 0xd3; //等待中断模式,正常AD转换,XP上拉使能,XP,XM,YP输出禁止,YM输出使能 rSRCPND |= BIT_ADC; rINTPND |= BIT_ADC; rSUBSRCPND|= BIT_SUB_TC; //清除中断标志 rINTMOD &=~BIT_ADC; rINTMSK &=~BIT_ADC; rINTSUBMSK &=~(BIT_SUB_TC); //使能触摸中断 rINTSUBMSK |= BIT_SUB_ADC; //关闭ADC中断 pISR_ADC =(unsigned)AdcTsAuto; //中断服务程序入口 }