⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 touch_screen.c

📁 arm9 嵌入式系统开发与实践光盘
💻 C
字号:
/**************************************************************
Touch Screen control
**************************************************************/
#include "def.h"
#include "2410addr.h"
#include "config.h"
#include "board.h"
#include "utils.h"
#include "Touch_Screen.h"
#include "LCD_LTS350Q1_PE1.h"

#define ADCPRS 39

#define GET_XY_TIMES 5	
volatile U16 TP_BUF[GET_XY_TIMES][2];
//#define Pen_Up_Down		( (rADCDAT0&(0x8000)) || (rADCDAT1&(0x8000)) )

static volatile U32 PenDown = 0;

//*************************************************************
#define UD_SEN			(1 << 8)
#define DOWN_INT		(UD_SEN*0)
#define UP_INT			(UD_SEN*1)
#define YM_SEN			(1 << 7)
#define YM_HIZ			(YM_SEN*0)
#define YM_GND			(YM_SEN*1)
#define YP_SEN			(1 << 6)
#define YP_EXTVLT		(YP_SEN*0)
#define YP_AIN			(YP_SEN*1)
#define XM_SEN			(1 << 5)
#define XM_HIZ			(XM_SEN*0)
#define XM_GND			(XM_SEN*1)
#define XP_SEN			(1 << 4)
#define XP_EXTVLT		(XP_SEN*0)
#define XP_AIN			(XP_SEN*1)
#define XP_PULL_UP		(1 << 3)
#define XP_PULL_UP_EN	(XP_PULL_UP*0)
#define XP_PULL_UP_DIS	(XP_PULL_UP*1)
#define AUTO_PST		(1 << 2)
#define CONVERT_MAN		(AUTO_PST*0)
#define CONVERT_AUTO	(AUTO_PST*1)
#define XP_PST(x)		(x << 0)
#define	WAIT_INT_MODE	3

#define wait_down_int()	do { rADCTSC = DOWN_INT | XP_PULL_UP_EN | \
				XP_AIN | XM_HIZ | YP_AIN | YM_GND | \
				XP_PST(WAIT_INT_MODE); } while(0)
#define wait_up_int()	do { rADCTSC = UP_INT | XP_PULL_UP_EN | XP_AIN | XM_HIZ | \
				YP_AIN | YM_GND | XP_PST(WAIT_INT_MODE); } while(0)
				
static __inline void GetPenXY(void)
{
	int i;
	for(i=0;i<GET_XY_TIMES;i++)
	{
		rADCTSC  = (1<<7)|(1<<6)|(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0);            
		rADCCON |= 0x1;             //Start Auto conversion
		while(rADCCON & 0x1);       //Check if Enable_start is low
		while(!(0x8000&rADCCON));   //Check ECFLG
		
		TP_BUF[i][0] = (0x3ff&rADCDAT0) * 10 ;
		TP_BUF[i][1] = (0x3ff&rADCDAT1) * 10 ;
		//printf( "x = %d\ty = %d\n", TP_BUF[i][0], TP_BUF[i][1] ) ;
	}
        
}

/**************************************************************
The interrupt function for Touch Screen
**************************************************************/
void __irq Touch_Screen( void )
{
    rINTSUBMSK |= (BIT_SUB_ADC | BIT_SUB_TC);     //Mask sub interrupt (ADC and TC) 
    
    if(!PenDown) {
		PenDown = 1;
		//printf("PEN down\n");

		//GetPenXY();		
		//wait_up_int();  	  
	} else {
		PenDown = 0;
		//printf("PEN up\n");
		wait_down_int();
	}
	
    rSUBSRCPND |= BIT_SUB_TC;
    rINTSUBMSK  =~(BIT_SUB_TC);   //Unmask sub interrupt (TC)     
    ClearPending(BIT_ADC);
}

/**************************************************************
The Initial of Touch Screen
**************************************************************/
void Touch_Screen_Init(void)
{
    rADCDLY = (30000);    // ADC Start or Interval Delay

    rADCCON = (1<<14)|(ADCPRS<<6)|(0<<3)|(0<<2)|(0<<1)|(0); 
  
	wait_down_int();

	rSUBSRCPND |= BIT_SUB_TC;
    rINTSUBMSK  =~(BIT_SUB_TC);
    
    pISR_ADC    = (unsigned)Touch_Screen;
    rINTMSK    &= ~(BIT_ADC);
    rINTSUBMSK &= ~(BIT_SUB_TC);
}

/**************************************************************
The Initial of Touch Screen
**************************************************************/
void Touch_Screen_Off(void)
{
	rINTMSK    |= (BIT_ADC);
    rINTSUBMSK |= (BIT_SUB_TC);
}


/**************************************************************
Touchpanel test
**************************************************************/
void TouchPanel_test(void)
{
	static int TouchPanelOn = 0;
	
	TouchPanelOn = TouchPanelOn ? 0 : 1 ;
	printf("Turn touchpanel %s\n", TouchPanelOn?"on":"off");
	
	if(TouchPanelOn)
		Touch_Screen_Init();
	else
		Touch_Screen_Off();
}

static U16 x_factor = 37 ;
static U16 y_factor = 27 ;
static U16 x_offset = 9726 ;
static U16 y_offset = 9702 ;
static U16 x_inverse = 1 ;
static U16 y_inverse = 1 ;
static int calibrate = 0 ;

int CheckTouchPanelEvent(U16 *x, U16 *y, U32 *tm)
{
	int i;
	U32 x_tot = 0, y_tot = 0;

	if( !PenDown )
 		return 0;
 	
  	GetPenXY();
 	DisableInt();
 	if(!PenDown)
	 	wait_down_int();
 	else {
		wait_up_int();		
	}
	EnableInt();

	Delay(1);

	if( !PenDown ) 
	{
   			return 0;
	}

   			
	for(i=0; i<GET_XY_TIMES; i++)
	{
		if( !TP_BUF[i][0] || !TP_BUF[i][1] )
			return -1;
		x_tot += TP_BUF[i][0] ;
		y_tot += TP_BUF[i][1] ;
	}
	
	*x = x_tot/GET_XY_TIMES;
	*y = y_tot/GET_XY_TIMES;
	
	if(calibrate)
		return 1;
	//printf("x=%d,y=%d\n", *x, *y);
	if(x_inverse) 
	{
		if(*x > x_offset) 
			*x =  x_offset;
		*x = (x_offset - *x)/x_factor ;
	} 
	else 
	{
		if(*x < x_offset)
			*x = x_offset;
		*x = (*x - x_offset)/x_factor ;
	}
	
	if(y_inverse) 
	{
		if(*y > y_offset) 
			*y =  y_offset;
		*y = (y_offset - *y)/y_factor ;
	} 
	else 
	{
		if(*y < y_offset) 
			*y =  y_offset;
		*y = (*y - y_offset)/y_factor ;
	}
	
	if(tm)
		*tm = 0;
//	printf("X=%d,Y=%d\n", *x, *y);
	return 1;
}


static int _TouchPanelCalibrate(U16 lcd_x, U16 lcd_y)
{
	U16 x1, y1, x2, y2, x3, y3, x4, y4, x5, y5;
	
	Touch_Screen_Init();

calibrate_again:
	
	calibrate = 1;
	
	Glib_ClearScr(0xffff);	
	Glib_Line(10, 19, 30, 19, 0);
	Glib_Line(10, 20, 30, 20, 0);
	Glib_Line(10, 21, 30, 21, 0);
	Glib_Line(19, 10, 19, 30, 0);
	Glib_Line(20, 10, 20, 30, 0);
	Glib_Line(21, 10, 21, 30, 0);
	
	while(!PenDown);		//如果触摸笔没有点屏
	while(CheckTouchPanelEvent(&x1, &y1, NULL)<1);
	while(PenDown);			//如果触摸笔没有还没有拿起来
	printf("\n●point1 %d,%d\n", x1, y1);

	Glib_ClearScr(0xffff);	
	Glib_Line(lcd_x-10, 19, lcd_x-30, 19, 0);
	Glib_Line(lcd_x-10, 20, lcd_x-30, 20, 0);
	Glib_Line(lcd_x-10, 21, lcd_x-30, 21, 0);
	Glib_Line(lcd_x-19, 10, lcd_x-19, 30, 0);
	Glib_Line(lcd_x-20, 10, lcd_x-20, 30, 0);
	Glib_Line(lcd_x-21, 10, lcd_x-21, 30, 0);
	
	while(!PenDown);		//如果触摸笔没有点屏
	while(CheckTouchPanelEvent(&x2, &y2, NULL)<1);
	while(PenDown);			//如果触摸笔没有还没有拿起来
	printf("●point2 %d,%d\n", x2, y2);
	
	Glib_ClearScr(0xffff);	
	Glib_Line(10, lcd_y-19, 30, lcd_y-19, 0);
	Glib_Line(10, lcd_y-20, 30, lcd_y-20, 0);
	Glib_Line(10, lcd_y-21, 30, lcd_y-21, 0);
	Glib_Line(19, lcd_y-10, 19, lcd_y-30, 0);
	Glib_Line(20, lcd_y-10, 20, lcd_y-30, 0);
	Glib_Line(21, lcd_y-10, 21, lcd_y-30, 0);
	
	while(!PenDown);		//如果触摸笔没有点屏
	while(CheckTouchPanelEvent(&x3, &y3, NULL)<1);
	while(PenDown);			//如果触摸笔没有还没有拿起来
	printf("●point3 %d,%d\n", x3, y3);
	
	Glib_ClearScr(0xffff);	
	Glib_Line(lcd_x-10, lcd_y-19, lcd_x-30, lcd_y-19, 0);
	Glib_Line(lcd_x-10, lcd_y-20, lcd_x-30, lcd_y-20, 0);
	Glib_Line(lcd_x-10, lcd_y-21, lcd_x-30, lcd_y-21, 0);
	Glib_Line(lcd_x-19, lcd_y-10, lcd_x-19, lcd_y-30, 0);
	Glib_Line(lcd_x-20, lcd_y-10, lcd_x-20, lcd_y-30, 0);
	Glib_Line(lcd_x-21, lcd_y-10, lcd_x-21, lcd_y-30, 0);
	
	while(!PenDown);		//如果触摸笔没有点屏
	while(CheckTouchPanelEvent(&x4, &y4, NULL)<1);
	while(PenDown);			//如果触摸笔没有还没有拿起来
	printf("●point4 %d,%d\n", x4, y4);
	
	x1 = (x1+x3)>>1;
	x2 = (x2+x4)>>1;
	y1 = (y1+y2)>>1;
	y2 = (y3+y4)>>1;
	
	printf("\nxl=%d,xr=%d,yt=%d,yb=%d\n", x1, x2, y1, y2);
	
	x_inverse = y_inverse = 0;
	
	if(x1<x2)
		x_factor = (x2-x1)/(lcd_x-40);
	else {
		x_factor = (x1-x2)/(lcd_x-40);
		x_inverse = 1;
	}
		
	if(y1<y2)
		y_factor = (y2-y1)/(lcd_y-40);
	else {
		y_factor = (y1-y2)/(lcd_y-40);
		y_inverse = 1;
	}

	x_offset = x_inverse?(x1 + 20*x_factor) : (x1 - 20*x_factor);
	y_offset = y_inverse?(y1 + 20*y_factor) : (y1 - 20*y_factor);
	
	printf("\nx_factor=%d,x_offset=%d,y_factor=%d,y_offset=%d\n",
			x_factor, x_offset, y_factor, y_offset);
	printf("\nx_inverse=%d,y_inverse=%d\n\n", x_inverse, y_inverse);
	
	if( x_factor == 0 )		x_factor = 1 ;
	if( y_factor == 0 )		y_factor = 1 ;
	
	calibrate = 0;
	
	Glib_ClearScr(0xffff);
	Glib_Line(lcd_x/2-10, lcd_y/2-1, lcd_x/2+10, lcd_y/2-1, 0);
	Glib_Line(lcd_x/2-10, lcd_y/2, lcd_x/2+10, lcd_y/2, 0);
	Glib_Line(lcd_x/2-10, lcd_y/2+1, lcd_x/2+10, lcd_y/2+1, 0);
	Glib_Line(lcd_x/2-1, lcd_y/2-10, lcd_x/2-1, lcd_y/2+10, 0);
	Glib_Line(lcd_x/2, lcd_y/2-10, lcd_x/2, lcd_y/2+10, 0);
	Glib_Line(lcd_x/2+1, lcd_y/2-10, lcd_x/2+1, lcd_y/2+10, 0);

	while(!PenDown);		//如果触摸笔没有点屏
	while(CheckTouchPanelEvent(&x5, &y5, NULL)<1);
	while(PenDown);		//如果触摸笔没有还没有拿起来
	printf("●point5 %d,%d\n", x5, y5) ;
	
	//( ((x5,120)>48) || ((y5,160)>64)  )
	if(abs_diff(x5, lcd_x/2)>(lcd_x>>5)||abs_diff(y5, lcd_y/2)>(lcd_y>>5)) {
		printf("Invalid calibrate!\n");
		goto calibrate_again;
	}	

	printf( "\ncalibrate is finished!\n" ) ;
	return 0;
}


//--------------------------------------------------------------
int TouchPanelCalibrate( U32 a1, U32 a2, U32 a3, U32 a4 )
{
	if(!a1||!a2)
		return  _TouchPanelCalibrate(LCD_XSIZE_TFT_240320, LCD_YSIZE_TFT_240320);
	else
		return  _TouchPanelCalibrate(a1, a2);
}

static char TouchPanelCalibrateTitle[] = "触摸屏校准";
static char TouchPanelCalibrateTip[] = "触摸屏校准程序,请用触笔依此点击LCD上显示的5个点";

TEST_PROGRAM_ITEM TouchPanelCalibrateItem = {
	TouchPanelCalibrate,
	TouchPanelCalibrateTitle,
	TouchPanelCalibrateTip,
	0
	};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -