S3C6410裸机电阻屏驱动

使用的是RVDS4.0编译的

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

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

 

adc.c

/*************************************************************************************************************
 * 文件名:	ADC.c
 * 功能:		S3C6410 ADC底层驱动函数
 * 作者:		[email protected]
 * 创建时间:	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_DELAY				500			//自动采样延时时间,



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



/*************************************************************************************************************************
*函数        :	void ADC_Init(void)
*功能        :	ADC初始始化
*参数        :	无
*返回        :	无
*依赖        : 	底层宏定义
*作者        :	[email protected]
*时间        :	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模式
*参数        :	无
*返回        :	无
*依赖        : 	底层宏定义
*作者        :	[email protected]
*时间        :	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坐标原始坐标值
*依赖        : 	底层宏定义
*作者        :	[email protected]
*时间        :	20121006
*最后修改时间:		20121006
*说明        :	读取的是ADC转换寄存器0
* 				需要先设置ADC模式
*************************************************************************************************************************/
u16 ADC_ReadX(void)
{
	ADC_Start();		//开始一次ADC转换
	ADC_Wait();			//等待转换完成
	return ADC_ReadData0();
}


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


/*************************************************************************************************************************
*函数        :	u8 Get_TouchState(void)
*功能        :	获取触摸状态
*参数        :	无
*返回        :	1:笔抬起;0:笔按下
*依赖        : 	底层宏定义
*作者        :	[email protected]
*时间        :	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_MODER		0	//普通的AD转换模式
#define ASUNDER_X_MODER		1	//分离的X采样模式
#define ASUNDER_Y_MODER		2	//分离的Y采样模式
#define AUTO_XY_MODER		3	//自动的X,Y采样模式//不知道为何不准,只能用分离的X,Y扫描模式
#define INT_AD_MODER		4	//等待中断的采样模式
#define STANDBY_AD_MODER	5	//掉电模式


//ADC通道选择
#define ADC_CH_AIN0		0
#define ADC_CH_AIN1		1
#define ADC_CH_AIN2		2
#define ADC_CH_AIN3		3
#define ADC_CH_YM		4
#define ADC_CH_YP		5
#define ADC_CH_XM		6
#define ADC_CH_XP		7


//读取转换寄存器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 电阻触摸屏驱动
 * 作者:		[email protected]
 * 创建时间:	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:笔中断使能
*返回        :	无
*依赖        : 	底层宏定义
*作者        :	[email protected]
*时间        :	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
* 作者	:	[email protected]
* 时间	:	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底层函数
* 作者	:	[email protected]
* 时间	:	20120914
* 最后修改时间 : 20120914
* 说明	: 	带滤波的坐标读取
			最小值不能少于MINI_ADC_DATA.
*************************************************************************************************************************/
#define MINI_ADC_DATA	100
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)
* 作者	:	[email protected]
* 时间	:	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) 
* 作者	:	[email protected]
* 时间	:	20120914
* 最后修改时间 : 20120914
* 说明	: 	调用Read_ADS2函数进行读取,如果Read_ADS2读取失败,重复读取,最多读取MAX_READ_ADS次
			如果失败,将返回0,注意返回1代表结果有效
			转换的结果存放在结构体Pen_Holder,的x0,y0中
*************************************************************************************************************************/
#define  MAX_READ_ADS	5	//最大重试次数
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底层
* 作者	:	[email protected]
* 时间	:	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
* 作者	:	[email protected]
* 时间	:	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底层
* 作者	:	[email protected]
* 时间	:	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 电阻触摸屏驱动
 * 作者:		[email protected]
 * 创建时间:	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_BASE	0x7E00B000

//ADC 寄存器
typedef struct
{
	vu32	CON;			//ADC控制寄存器 
	vu32	TSC;			//触摸屏控制寄存器
	vu32	DLY;			//ADC开始延迟寄存器
	vu32	DAT0;			//ADC数据寄存器0
	vu32	DAT1;			//ADC数据寄存器1
	vu32	UPDN;			//触摸屏UP-DOWN寄存器
	vu32	CLRINT;			//ADC中断清除寄存器
	u32		Reserved;
	vu32	CLRINTPNDNUP;	//触摸屏笔中断寄存器
}ADC_TypeDef;

#define ADC		((ADC_TypeDef*)ADC_BASE)


你可能感兴趣的:(c,struct,XP,UP,float,delay)