S3C6410裸机电阻屏驱动

时间:2022-11-09 18:22:36

使用的是RVDS4.0编译的

大家主要是看看如何配置模式的

我之前一直使用自动X,Y采样,但是读取的都不准,最后采样分离的,才可以,需要注意的是使能ADC读开始后需要先读转换结果寄存器,但是此时读取的是上一次的转换结果,如果是连续读取需要等待转换完成,否则转换结果不准.

 

adc.c

/*************************************************************************************************************
* 文件名:ADC.c
* 功能:S3C6410 ADC底层驱动函数
* 作者:cp1300@139.com
* 创建时间:2012年3月12日21:05
* 最后修改时间:2012年3月12日
* 详细:触摸屏驱动以及相关ADC驱动
* 问题:一直以来存在一个误区,一直以为使用了启动开始读操作,每次读DAT寄存器后就可以读取到转换后的数据,最终发现使用这个后读到的是上一次的数据,
* 还是需要等到转换完成,否则连续转换的时候数据会非常乱.
* 现在使用的是手动控制转换开始
*************************************************************************************************************/
#include "system.h"
#include "ADC.h"




//ADC的控制寄存器 ADCCON
#define ADCCON_RESSEL_12BIT(1 << 16)//12bit模式
#define ADCCON_ECFLG (0 << 15)//A/D转换结束标志只读;
#define ADCCON_PRSCEN(1 << 14)//A/D转换器预分频器使能
#define ADCCON_PRSCVL(32<< 6)//预分频值,1-255,分频值+1,至少为PCLK的1/5,此时PCLK = 66MHZ,在2.5MHZ时钟下转换最快
#define ADCCON_SEL_MUX(0<< 3)//默认选择通道0
#define ADCCON_STDBM(0<< 2)//正常模式
#define ADCCON_READ_START(0<< 1)//关闭启动开始读操作
#define ADCCON_ENABLE_START(0 << 0)//如果READ_START 启用,这个值是无效的。


//ADCDLY
#define ADCDLY_DELAY500//自动采样延时时间,



/*************************************************************************************************************************
*函数 :void SetADC_Channel(u8 ch)
*功能 :设置ADC输入通道
*参数 :ch:通道号,0-7
*返回 :无
*依赖 : 底层宏定义
*作者 :cp1300@139.com
*时间 :20120513
*最后修改时间:20120513
*说明 :ADC输入通道选择
*************************************************************************************************************************/
void SetADC_Channel(u8 ch)
{
ADC->CON &= ~(7 << 3);//清除通道
ADC->CON |= ch & (0x07);//设置通道号
}



/*************************************************************************************************************************
*函数 :void ADC_Init(void)
*功能 :ADC初始始化
*参数 :无
*返回 :无
*依赖 : 底层宏定义
*作者 :cp1300@139.com
*时间 :20120312
*最后修改时间:20120313
*说明 :ADC初始始化
*************************************************************************************************************************/
void ADC_Init(void)
{
//ADC的控制寄存器配置;12BIT模式
ADC->CON = ADCCON_RESSEL_12BIT + ADCCON_ECFLG + ADCCON_PRSCEN + ADCCON_PRSCVL + ADCCON_SEL_MUX + ADCCON_STDBM + ADCCON_READ_START + ADCCON_ENABLE_START;
ADC->DLY = ADCDLY_DELAY;//设置自动间隔采样时间
}


/*************************************************************************************************************************
*函数 :void ADC_SetMode(u8 Mode)
*功能 :设置ADC模式
*参数 :无
*返回 :无
*依赖 : 底层宏定义
*作者 :cp1300@139.com
*时间 :20120313
*最后修改时间:20120313
*说明 :设置ADC模式
*************************************************************************************************************************/
void ADC_SetMode(u8 Mode)
{
ADC->TSC &= (1 << 8);//清除原先设置
ADC->CON &= ~BIT2;//退出待机模式
XP_UP_DISABLE();//XP上拉禁止
Normal_ADC_Mode();//普通ADC模式
switch(Mode)
{
case COMMON_AD_MODER://普通ADC模式
Normal_ADC_Mode();break;
case ASUNDER_X_MODER://分离的X扫描模式
{
ADCTSC_XP_VDD();
ADCTSC_XM_GND();
ADCTSC_YP_HZ();
ADCTSC_YM_HZ();
X_PosMode();
}break;//XP=外部电源,XM=GND,YP=AIN5,YM=高阻
case ASUNDER_Y_MODER://分离的Y扫描模式
{
ADCTSC_XP_HZ();
ADCTSC_XM_HZ();
ADCTSC_YP_VDD();
ADCTSC_YM_GND();
Y_PosMode();
}break;//XP=AIN7,XM=高阻,YP=外部电源,YM=GND
case AUTO_XY_MODER://自动XY扫描模式
{
AUTO_XYPosition();
}break;
case INT_AD_MODER://等待中断模式
{
ADCTSC_XP_HZ();
ADCTSC_XM_HZ();
ADCTSC_YP_HZ();
ADCTSC_YM_GND();
XP_UP_ENABLE();//XP上拉使能
INT_WaitingMode();
}break;//XP上拉,XM=高阻,YP=AIN5,YM=GND
case STANDBY_AD_MODER://掉电模式
StandbyMode();break;
default:break;
}
}



/*************************************************************************************************************************
*函数 :u16 ADC_ReadX(void)
*功能 :读取X坐标
*参数 :无
*返回 :X坐标原始坐标值
*依赖 : 底层宏定义
*作者 :cp1300@139.com
*时间 :20121006
*最后修改时间:20121006
*说明 :读取的是ADC转换寄存器0
* 需要先设置ADC模式
*************************************************************************************************************************/
u16 ADC_ReadX(void)
{
ADC_Start();//开始一次ADC转换
ADC_Wait();//等待转换完成
return ADC_ReadData0();
}


/*************************************************************************************************************************
*函数 :u16 ADC_ReadY(void)
*功能 :读取Y坐标
*参数 :无
*返回 :Y坐标原始坐标值
*依赖 : 底层宏定义
*作者 :cp1300@139.com
*时间 :20121006
*最后修改时间:20121006
*说明 :读取的是ADC转换寄存器1
* 需要先设置ADC模式
*************************************************************************************************************************/
u16 ADC_ReadY(void)
{
ADC_Start();//开始一次ADC转换
ADC_Wait();//等待转换完成
return ADC_ReadData1();
}


/*************************************************************************************************************************
*函数 :u8 Get_TouchState(void)
*功能 :获取触摸状态
*参数 :无
*返回 :1:笔抬起;0:笔按下
*依赖 : 底层宏定义
*作者 :cp1300@139.com
*时间 :20120315
*最后修改时间:20120315
*说明 :通过读取ADCDAT1的BIT15来确定状态
*************************************************************************************************************************/
u8 Get_TouchState(void)
{
return((ADC->DAT1 & BIT15) ? TOUCH_UP : TOUCH_DOWN);
}







//触摸屏中断服务函数
void __irq Isr_Touch(void)
{
TOUCH_ClearInt();//清除触摸屏中断标志
VICInterruptEnd();//中断结束
}




adc.h

/*************************************************************************************************************
* 文件名:ADC.h
* 功能:S3C6410 触摸屏ADC底层驱动函数
* 作者:陈鹏
* 创建时间:2012年3月12日21:05
* 最后修改时间:2012年3月12日
* 详细:触摸屏驱动以及相关ADC驱动
*************************************************************************************************************/

#ifndef_ADC_H_
#define _ADC_H_

//按键状态
#define TOUCH_DOWN 0
#define TOUCH_UP 1
#define TOUCH_Posedge 0x01//笔抬起事件
#define TOUCH_Negedge 0x02//笔按下事件

//ADC采样模式
#define COMMON_AD_MODER0//普通的AD转换模式
#define ASUNDER_X_MODER1//分离的X采样模式
#define ASUNDER_Y_MODER2//分离的Y采样模式
#define AUTO_XY_MODER3//自动的X,Y采样模式//不知道为何不准,只能用分离的X,Y扫描模式
#define INT_AD_MODER4//等待中断的采样模式
#define STANDBY_AD_MODER5//掉电模式


//ADC通道选择
#define ADC_CH_AIN00
#define ADC_CH_AIN11
#define ADC_CH_AIN22
#define ADC_CH_AIN33
#define ADC_CH_YM4
#define ADC_CH_YP5
#define ADC_CH_XM6
#define ADC_CH_XP7


//读取转换寄存器0
#define ADC_ReadData0()(ADC->DAT0&0xfff)
#define ADC_ReadData1()(ADC->DAT1&0xfff)

//相关函数
void ADC_Init(void);//初始化ADC
void SetADC_Channel(u8 ch);//ADC通道选择
void ADC_SetMode(u8 Mode);//ADC工作模式设置
u8 Get_TouchState(void);//获取触摸笔状态
u16 ADC_ReadX(void);//读取X坐标
u16 ADC_ReadY(void);//读取Y坐标



//使能笔抬起中断
__inline void ADCTSC_UD_SEN (u8 EN)
{
ADC->TSC &= ~BIT8;//笔向下中断
if(EN == ENABLE)
ADC->TSC |= BIT8;
}



//YM接GMD无效,接HZ
__inline void ADCTSC_YM_HZ(void)
{
ADC->TSC &= ~BIT7;
}

//YM接GMD有效,接GND
__inline void ADCTSC_YM_GND(void)
{
ADC->TSC |= BIT7;
}


//YP接VDD无效,接HZ
__inline void ADCTSC_YP_HZ(void)
{
ADC->TSC |= BIT6;
}

//YP接VDD有效,接VDDA
__inline void ADCTSC_YP_VDD(void)
{
ADC->TSC &= ~BIT6;
}


//XM接GMD无效,接HZ
__inline void ADCTSC_XM_HZ(void)
{
ADC->TSC &= ~BIT5;
}

//XM接GMD有效,接GND
__inline void ADCTSC_XM_GND(void)
{
ADC->TSC |= BIT5;
}


//XP接VDD无效,接HZ
__inline void ADCTSC_XP_HZ(void)
{
ADC->TSC |= BIT4;
}

//XP接VDD有效,接VDDA
__inline void ADCTSC_XP_VDD(void)
{
ADC->TSC &= ~BIT4;
}


//正常ADC转换模式
__inline void Normal_ADC_Mode(void)
{
ADC->TSC &= ~BIT2;//正常的ADC转换
}

//待机模式
__inline void StandbyMode(void)
{
ADC->CON |= BIT2;
}


//自动X,Y转换
__inline void AUTO_XYPosition(void)
{
ADC->TSC &= ~(BIT0+BIT1);
ADC->TSC |= BIT2;//自动X,Y转换
}

//X,Y手动测量模式,没有运行模式
__inline void NO_OpeMode(void)
{
ADC->TSC &= ~(BIT0+BIT1);
}

//X,Y手动测量模式,X坐标转换模式
__inline void X_PosMode(void)
{
NO_OpeMode();//清除设置
ADC->TSC |= 1;
}

//X,Y手动测量模式,Y坐标转换模式
__inline void Y_PosMode(void)
{
NO_OpeMode();//清除设置
ADC->TSC |= 2;
}

//X,Y手动测量模式,等待中断模式
__inline void INT_WaitingMode(void)
{
NO_OpeMode();//清除设置
ADC->TSC |= 3;
}


//XP上拉启动
__inline void XP_UP_ENABLE(void)
{
ADC->TSC &= ~BIT3;
}


//XP上拉禁止
__inline void XP_UP_DISABLE(void)
{
ADC->TSC |= BIT3;
}


//清除ADC唤醒中断
__inline void ADC_ClearInt(void)
{
ADC->CLRINT = 0xffffffff;//写入任何值清除中断标志
}


//清除触摸屏中断中断
__inline void TOUCH_ClearInt(void)
{
ADC->UPDN = 0;//清除ADC的触摸屏UP-DOWN寄存器
ADC->CLRINTPNDNUP = 0xffffffff;//写入任何值清除中断标志
}


//开始一次ADC转换
__inline void ADC_Start(void)
{
ADC->CON |= BIT0;//开始ADC转换
}


//等待ADC转换完成
__inline void ADC_Wait(void)
{
while(!(ADC->CON & BIT15));
}


#endif

touch.c

/*************************************************************************************************************
* 文件名:Touch.c
* 功能:S3C6410 电阻触摸屏驱动
* 作者:cp1300@139.com
* 创建时间:2012年10月6日17:31
* 最后修改时间:2012年10月6日
* 详细:需要底层的ADC支持
*************************************************************************************************************/
#include "system.h"
#include "adc.h"
#include "touch.h"


Pen_Holder Pen_Point;//定义笔实体



//开启触摸屏校准,需要其它支持
#define _TOUCH_ADJUST 1

#if _TOUCH_ADJUST
void TOUCH_Adjust(void);//触摸屏校准
#endif //_TOUCH_ADJUST

/*************************************************************************************************************************
*函数 :void TOUCH_Init(FunctionalState EnableInt)
*功能 :触摸屏初始始化
*参数 :EnableInt:笔中断使能
*返回 :无
*依赖 : 底层宏定义
*作者 :cp1300@139.com
*时间 :20120313
*最后修改时间:20121006
*说明 :触摸屏初始始化
*************************************************************************************************************************/
void TOUCH_Init(FunctionalState EnableInt)
{
ADC_Init();//初始化ADC
TOUCH_ClearInt();//清除触摸屏中断标志
ADC_ClearInt();//清除ADC中断
ADC_SetMode(INT_AD_MODER);//等待中断模式
ADCTSC_UD_SEN(DISABLE);//设置为按下中断
if(EnableInt == ENABLE)//开启笔中断
{
//Set_IsrAddr(INT_PENDNUP,(u32)Isr_Touch);//设置中断矢量入口
//Set_IntEnable(INT_PENDNUP,ENABLE);//开启触摸屏按下
}
#if _TOUCH_ADJUST
TOUCH_Adjust();//触摸屏校准
#endif //_TOUCH_ADJUST
}




/*************************************************************************************************************************
* 函数:u16 ADS_Read_XY(u16(*ADC_ReadXY)(void))
* 功能:使用冒泡法读取一次坐标
* 参数:ADC_ReadXY:X或Y坐标读取函数
* 返回:转换结果
* 依赖:ADC
* 作者:cp1300@139.com
* 时间:20121006
* 最后修改时间 : 20121006
* 说明: 连续读取READ_TIMES次数据,对这些数据升序排列,
然后去掉最低和最高LOST_VAL个数,取平均值
*************************************************************************************************************************/
#define READ_TIMES 15 //读取次数
#define LOST_VAL 5 //丢弃值
u16 ADS_Read_XY(u16(*ADC_ReadXY)(void))
{
u16 i, j;
u16 buff[READ_TIMES];
u16 sum=0;
u16 temp;

for(i = 0;i < READ_TIMES;i ++)
{
buff[i] = ADC_ReadXY();
}
for(i = 0;i < READ_TIMES - 1;i ++)//排序
{
for(j = i + 1;j < READ_TIMES;j ++)
{
if(buff[i] > buff[j])//升序排列
{
temp = buff[i];
buff[i] = buff[j];
buff[j] = temp;
}
}
}
sum = 0;
for(i = LOST_VAL;i < READ_TIMES - LOST_VAL;i ++)
sum += buff[i];
temp = sum / (READ_TIMES - 2 * LOST_VAL);

return temp;
}


/*************************************************************************************************************************
* 函数:u8 Read_ADS(u16 *x,u16 *y)
* 功能:带滤波的读取X,Y坐标
* 参数:X,Y坐标值缓冲区指针
* 返回:1:转换结果有效;0:转换结果无效
* 依赖:XPT2046底层函数
* 作者:cp1300@139.com
* 时间:20120914
* 最后修改时间 : 20120914
* 说明: 带滤波的坐标读取
最小值不能少于MINI_ADC_DATA.
*************************************************************************************************************************/
#define MINI_ADC_DATA100
u8 Read_ADS(u16 *x,u16 *y)
{
u16 xtemp, ytemp;

ADC_SetMode(ASUNDER_X_MODER);//设置ADC为分离的X采样模式
xtemp = ADS_Read_XY(ADC_ReadX);//读取X坐标
ADC_SetMode(ASUNDER_Y_MODER);//设置ADC为分离的Y采样模式
ytemp = ADS_Read_XY(ADC_ReadY);//读取Y坐标
ADC_SetMode(INT_AD_MODER);//设置ADC为等待中断模式
if(xtemp < MINI_ADC_DATA || ytemp < MINI_ADC_DATA)
return 0;//读数失败
*x = xtemp;
*y = ytemp;

return 1;//读数成功
}


/*************************************************************************************************************************
* 函数:u8 Read_ADS2(u16 *x,u16 *y)
* 功能:连续读取2次有效的AD值
* 参数:X,Y坐标值缓冲区指针
* 返回:1:转换结果有效;0:转换结果无效
* 依赖:u8 Read_ADS(u16 *x,u16 *y)
* 作者:cp1300@139.com
* 时间:20120914
* 最后修改时间 : 20120914
* 说明: 连续读取2次有效的AD值,且这两次的偏差不能超过ERR_RANGE
满足条件,则认为读数正确,否则读数错误.
该函数能大大提高准确度
*************************************************************************************************************************/
#define ERR_RANGE 50 //误差范围
u8 Read_ADS2(u16 *x,u16 *y)
{
u16 x1,y1;
u16 x2,y2;
u8 flag;

flag = Read_ADS(&x1,&y1);
if(flag == 0)
return(0);
flag = Read_ADS(&x2,&y2);
if(flag == 0)
return(0);
if(((x2 <= x1 && x1 < x2 + ERR_RANGE) || (x1 <= x2 && x2 < x1 + ERR_RANGE))
&& ((y2 <= y1 && y1 < y2 + ERR_RANGE) || (y1 <= y2 && y2 < y1 + ERR_RANGE)))//前后两次采样在+-ERR_RANGE内
{
*x = (x1 + x2) / 2;
*y = (y1 + y2) / 2;
return 1;
}
else
return 0;
}


/*************************************************************************************************************************
* 函数:u8 TOUCH_ReadOneTP(void)
* 功能:读取一次原始坐标
* 参数:无
* 返回:1:转换结果有效;0:转换结果无效
* 依赖:u8 Read_ADS2(u16 *x,u16 *y)
* 作者:cp1300@139.com
* 时间:20120914
* 最后修改时间 : 20120914
* 说明: 调用Read_ADS2函数进行读取,如果Read_ADS2读取失败,重复读取,最多读取MAX_READ_ADS次
如果失败,将返回0,注意返回1代表结果有效
转换的结果存放在结构体Pen_Holder,的x0,y0中
*************************************************************************************************************************/
#define MAX_READ_ADS5//最大重试次数
u8 TOUCH_ReadOneTP(void)
{
u8 i;
u16 x,y;

for(i = MAX_READ_ADS;i != 0;i --)
{
if(Read_ADS2(&x,&y))
{
Pen_Point.x0 = x; //转换有效,存储结果
Pen_Point.y0 = y;
return 1;//返回成功
}
}

return 0;//返回失败
}



/*************************************************************************************************************************
* 函数:void TOUCH_ConvertPos(void)
* 功能:采集并转换触摸坐标
* 参数:无
* 返回:无
* 依赖:LCD.C,触摸屏ADC底层
* 作者:cp1300@139.com
* 时间:20120914
* 最后修改时间 : 20121006
* 说明: 根据触摸屏的校准参数来决定转换后的结果,保存在x,y中
* 需要先进行触摸校准
*************************************************************************************************************************/
void TOUCH_ConvertPos(void)
{
if(TOUCH_ReadOneTP())
{
Pen_Point.x = Pen_Point.xfac * Pen_Point.x0 + Pen_Point.xoff;
Pen_Point.y = Pen_Point.yfac * Pen_Point.y0 + Pen_Point.yoff;
}
}




//触摸屏校准相关
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if _TOUCH_ADJUST
#include "TFT_LCD.h"
#include "stdlib.h"
#include "math.h"
#include "delay.h"

/*************************************************************************************************************************
* 函数:void Drow_Touch_Point(u16 x,u16 y)
* 功能:画一个触摸点,用于校准
* 参数:x,y:触摸点中心位置
* 返回:无
* 依赖:LCD.C
* 作者:cp1300@139.com
* 时间:20120914
* 最后修改时间 : 20120914
* 说明: 会调用LCD.C中的画圆,画线,画矩形等函数
*************************************************************************************************************************/
void Drow_Touch_Point(u16 x,u16 y)
{
Draw_Circle(x,y,10,0xf0f0);//画圆
Draw_Circle(x,y,3,0xf0f0);//画圆
LCD_DrawLine(x - 15, y, x + 15, y,0xf0f0);//画线
LCD_DrawLine(x, y - 15, x, y + 15,0xf0f0);//画线
LCD_DrawRectangle(x - 10,y - 10,x + 10,y + 10,0xf0f0);//画矩形
}




/*************************************************************************************************************************
* 函数:void TOUCH_Adjust(void)
* 功能:进行触摸屏校准
* 参数:无
* 返回:无
* 依赖:LCD.C,触摸屏ADC底层
* 作者:cp1300@139.com
* 时间:20120914
* 最后修改时间 : 20120914
* 说明: 得到四个校准值
* (20,20)(LCD_XSIZE-20,20)
*
*
* (20,LCD_YSIZE-20)(LCD_XSIZE-20,LCD_YSIZE-20)
*************************************************************************************************************************/
void TOUCH_Adjust(void)
{
u16 pos_temp[4][2];//坐标缓存值
u8 cnt=0;
u16 d1,d2;
u32 tem1,tem2;
float fac;
cnt=0;


LCD_ClearScreen(0xffff);//清屏
Drow_Touch_Point(20,20);//画点1
//Pen_Point.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误
while(1)
{
if(GetPenStartus() == TOUCH_DOWN)//按键按下了
{
if(TOUCH_ReadOneTP())//得到单次按键值
{
pos_temp[cnt][0]=Pen_Point.x0;
pos_temp[cnt][1]=Pen_Point.y0;
cnt++;
}
while(GetPenStartus() == TOUCH_DOWN);//等待按键抬起
switch(cnt)
{
case 1:
LCD_ClearScreen(0xffff);//清屏
Drow_Touch_Point(LCD_XSIZE-20,20);//画点2
break;
case 2:
LCD_ClearScreen(0xffff);//清屏
Drow_Touch_Point(20,LCD_YSIZE-20);//画点3
break;
case 3:
LCD_ClearScreen(0xffff);//清屏
Drow_Touch_Point(LCD_XSIZE-20,LCD_YSIZE-20);//画点4
break;
case 4: //全部四个点已经得到
//对边相等
tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2
tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,2的距离

tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4
tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4
tem1*=tem1;
tem2*=tem2;
d2=sqrt(tem1+tem2);//得到3,4的距离
fac=(float)d1/d2;
if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格
{
cnt=0;
LCD_ClearScreen(0xffff);//清屏
Drow_Touch_Point(20,20);
continue;
}
tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3
tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,3的距离

tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4
tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4
tem1*=tem1;
tem2*=tem2;
d2=sqrt(tem1+tem2);//得到2,4的距离
fac=(float)d1/d2;
if(fac<0.95||fac>1.05)//不合格
{
cnt=0;
LCD_ClearScreen(0xffff);//清屏
Drow_Touch_Point(20,20);
continue;
}//正确了

//对角线相等
tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3
tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,4的距离

tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4
tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4
tem1*=tem1;
tem2*=tem2;
d2=sqrt(tem1+tem2);//得到2,3的距离
fac=(float)d1/d2;
if(fac<0.95||fac>1.05)//不合格
{
cnt=0;
LCD_ClearScreen(0xffff);//清屏
Drow_Touch_Point(20,20);
continue;
}//正确了
//计算结果
Pen_Point.xfac=(float)(LCD_XSIZE-40)/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac
Pen_Point.xoff=(LCD_XSIZE-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff

Pen_Point.yfac=(float)(LCD_YSIZE-40)/(pos_temp[2][1]-pos_temp[0][1]);//得到yfac
Pen_Point.yoff=(LCD_YSIZE-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff
//Wire_Touch();//存储校准结果
LCD_ClearScreen(0xffff);//清屏
Show_Char(35,LCD_YSIZE/2,"Touch Screen Adjust OK!",0xf800,0xffff,0x80);
Delay_MS(1000);
LCD_ClearScreen(0xffff);//清屏
return;//校正完成
}
}
}
}


#endif //_TOUCH_ADJUST
///////////////////////////////////////////////////////////////////////////////////////////////////////////////


touch.h

/*************************************************************************************************************
* 文件名:Touch.h
* 功能:S3C6410 电阻触摸屏驱动
* 作者:cp1300@139.com
* 创建时间:2012年10月6日17:31
* 最后修改时间:2012年10月6日
* 详细:需要底层的ADC支持
*************************************************************************************************************/
#ifndef TOUCH_H_
#define TOUCH_H_

#include "adc.h"

#ifndef TOUCH_DOWN
#define TOUCH_DOWN 0
#endif //TOUCH_DOWN
#ifndef TOUCH_UP
#define TOUCH_UP 1
#endif //TOUCH_UP



//笔杆结构体
typedef struct
{
u16 x0;//原始坐标
u16 y0;
u16 x; //最终/暂存坐标
u16 y;
u8 Touch_Sta;//笔的状态
//触摸屏校准参数
float xfac;
float yfac;
short xoff;
short yoff;
}Pen_Holder;
extern Pen_Holder Pen_Point;//定义一个笔杆的结构变量



void TOUCH_Init(FunctionalState EnableInt);//触摸屏初始化函数
u8 TOUCH_ReadOneTP(void);//读取一次坐标
#define GetPenStartus()Get_TouchState()//获取触摸笔状态
void TOUCH_ConvertPos(void);//获取转换后的实际坐标




#endif /*TOUCH_H_*/

主函数测试程序

main.c

#include "system.h"
#include "uart.h"
#include "tft_lcd.h"
#include "other.h"
#include "delay.h"
#include "timer.h"
#include "touch.h"


//LED1闪烁程序,在定时器0中断服务程序中闪烁,周期400MS
void LED1_flash(void)
{
LED1_FLASH();
}



int main(void)
{
LCD_Init();//初始化LCD
UART0_Init(DISABLE,115200);//初始化串口,失能中断接收,波特率115200
LED_Init();//初始化LED

Timer1_Init(400000-1,ENABLE,LED1_flash);//初始化定时器0,周期400ms
TOUCH_Init(DISABLE);//初始化触摸屏

lcd_printf("Get_FCLK : %d Hz\n",Get_FCLK());
lcd_printf("Get_PCLK : %d Hz\n",Get_PCLK());

while(1)
{
//LED2_FLASH();//LED2闪烁
//Delay_US(600000);
if(GetPenStartus() == TOUCH_DOWN)//笔按下
{
TOUCH_ConvertPos();
//lcd_printf("X:%d; Y:%d\n",Pen_Point.x,Pen_Point.y);
Draw_Big_Point(Pen_Point.x,Pen_Point.y,0xf800);
Delay_MS(1);
}
}
}




//补充ADC相关寄存器结构

#define ADC_BASE0x7E00B000

//ADC 寄存器
typedef struct
{
vu32CON;//ADC控制寄存器
vu32TSC;//触摸屏控制寄存器
vu32DLY;//ADC开始延迟寄存器
vu32DAT0;//ADC数据寄存器0
vu32DAT1;//ADC数据寄存器1
vu32UPDN;//触摸屏UP-DOWN寄存器
vu32CLRINT;//ADC中断清除寄存器
u32Reserved;
vu32CLRINTPNDNUP;//触摸屏笔中断寄存器
}ADC_TypeDef;

#define ADC((ADC_TypeDef*)ADC_BASE)