ili9325 stm32f100

Başlatan muhittin_kaplan, 21 Mart 2013, 10:36:25

Mucit23

Dün deney kiti ile ilgili kodları ayıklarken Touch Panel Kalibrasyonu üzerine güzel bir uygulama buldum.

TCS2046 için kullanılan kütüphane budur

Touch.h
#ifndef __TOUCH_H
#define __TOUCH_H	

/* °´¼ü״̬	*/ 
#define Key_Down 0x01
#define Key_Up   0x00 
/* ±Ê¸Ë½á¹¹Ìå */
typedef struct 
{
	u16 X0;//ԭʼ×ø±ê
	u16 Y0;
	u16 X; //×îÖÕ/ÔÝ´æ×ø±ê
	u16 Y;						   	    
	u8  Key_Sta;//±ÊµÄ״̬			  
	//´¥ÃþÆÁУ׼²ÎÊý
	float xfac;
	float yfac;
	short xoff;
	short yoff;
}Pen_Holder;
extern Pen_Holder Pen_Point;

/*´¥ÃþÆÁоƬÁ¬½ÓÒý½ÅÅäÖÃ	*/   
#define PEN  PCin(4)   //PC4 INT
#define DOUT PAin(6)   //PA6  MISO
#define TDIN PAout(7)  //PA7  MOSI
#define TCLK PAout(5)  //PA5  SCLK
#define TCS  PCout(6)  //PC6  CS 

/* ADS7843/7846/UH7843/7846/XPT2046/TSC2046 Ö¸Á */
#define CMD_RDY 0X90  //0B10010000¼´Óòî·Ö·½Ê½¶ÁX×ø±ê
#define CMD_RDX	0XD0  //0B11010000¼´Óòî·Ö·½Ê½¶ÁY×ø±ê  
  
void Touch_Init(void);
void Touch_Adjust(void);
void Convert_Pos(void);
void Pen_Int_Set(uint8_t en);
void Touch_Configuration(void);
void ADS_Write_Byte(uint8_t num);
uint16_t ADS_Read_AD(uint8_t CMD);
uint16_t ADS_Read_XY(uint8_t xy);
uint8_t Read_TP_Once(void);
uint8_t Read_ADS2(uint16_t *x,uint16_t *y);
uint8_t Read_ADS(uint16_t *x,uint16_t *y);
void Draw_Big_Point(uint8_t x,uint16_t y);
void Drow_Touch_Point(uint8_t x,uint16_t y);

#endif


Touch.c
/**************************************************************
** 	»ðÅ£¿ª·¢°å
**	¹¦ÄܽéÉÜ£º ´¥ÃþÆÁÇý¶¯´úÂë
**  °æ±¾£ºV1.0  
**	ÂÛ̳£ºbbs.openmcu.com
**	Íú±¦£ºwww.openmcu.com   
**  ÓÊÏ䣻support@openmcu.com 
***************************************************************/
 
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "hardware_conf.h"
#include "Touch.h"
#include "ili932x_conf.h"
#include "stdlib.h"
#include "math.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
Pen_Holder Pen_Point;	/* ¶¨Òå±ÊʵÌå */ 
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
EXTI_InitTypeDef EXTI_InitStructure;

extern void Delay(__IO uint32_t nTime);
  
void ADS_Write_Byte(uint8_t num)    
{  
	uint8_t count=0;   
	for(count=0;count<8;count++)  
	{ 	  
		if(num&0x80)TDIN=1;  
		else TDIN=0;   
		num<<=1;    
		TCLK=0;	 
		TCLK=1;      
	} 			    
} 		 
	   
uint16_t ADS_Read_AD(uint8_t CMD)	  
{ 	 
	uint8_t i;
	uint8_t count=0; 	  
	uint16_t Num=0; 
	TCLK=0; 	 
	TCS=0; 
	ADS_Write_Byte(CMD);
	for(i=100;i>0;i--);
//	delay_us(6);//ADS7846µÄת»»Ê±¼ä×Ϊ6us
	TCLK=1;//¸ø1¸öʱÖÓ£¬Çå³ýBUSY   	    
	TCLK=0; 	 
	for(count=0;count<16;count++)  
	{ 				  
		Num<<=1; 	 
		TCLK=0;//ϽµÑØÓÐЧ  	    	   
		TCLK=1;
		if(DOUT)Num++; 		 
	}  	
	Num>>=4;  
	TCS=1; 
	return(Num);   
}

#define READ_TIMES 15 
#define LOST_VAL 5	  
uint16_t ADS_Read_XY(uint8_t xy)
{
	uint16_t i, j;
	uint16_t buf[READ_TIMES];
	uint16_t sum=0;
	uint16_t temp;
	for(i=0;i<READ_TIMES;i++)
	{				 
		buf[i]=ADS_Read_AD(xy);	    
	}				    
	for(i=0;i<READ_TIMES-1; i++)
	{
		for(j=i+1;j<READ_TIMES;j++)
		{
			if(buf[i]>buf[j])
			{
				temp=buf[i];
				buf[i]=buf[j];
				buf[j]=temp;
			}
		}
	}	  
	sum=0;
	for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++)sum+=buf[i];
	temp=sum/(READ_TIMES-2*LOST_VAL);
	return temp;   
} 

uint8_t Read_ADS(uint16_t *x,uint16_t *y)
{
	uint16_t xtemp,ytemp;			 	 		  
	xtemp=ADS_Read_XY(CMD_RDX);
	ytemp=ADS_Read_XY(CMD_RDY);	  												   
	if(xtemp<100||ytemp<100)return 0;
	*x=xtemp;
	*y=ytemp;
	return 1;
}

#define ERR_RANGE 50 
uint8_t Read_ADS2(uint16_t *x,uint16_t *y) 
{
	uint16_t x1,y1;
 	uint16_t x2,y2;
 	uint8_t 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)))
    {
        *x=(x1+x2)/2;
        *y=(y1+y2)/2;
        return 1;
    }else return 0;	  
} 

uint8_t Read_TP_Once(void)
{
	uint8_t t=0;	    
	Pen_Int_Set(0);
	Pen_Point.Key_Sta=Key_Up;
	Read_ADS2(&Pen_Point.X,&Pen_Point.Y);
	while(PEN==0&&t<=250)
	{
		t++;
		Delay(10);
	};
	Pen_Int_Set(1);	 
	if(t>=250)return 0;
	else return 1;	
}

void Drow_Touch_Point(uint8_t x,uint16_t y)
{
	LCD_DrawLine(x-12,y,x+13,y);
	LCD_DrawLine(x,y-12,x,y+13);
	LCD_DrawPoint(x+1,y+1);
	LCD_DrawPoint(x-1,y+1);
	LCD_DrawPoint(x+1,y-1);
	LCD_DrawPoint(x-1,y-1);
	Draw_Circle(x,y,6);
}	  

void Draw_Big_Point(uint8_t x,uint16_t y)
{	    
	LCD_DrawPoint(x,y);
	LCD_DrawPoint(x+1,y);
	LCD_DrawPoint(x,y+1);
	LCD_DrawPoint(x+1,y+1);	 	  	
}

void Convert_Pos(void)
{		 	  
	if(Read_ADS2(&Pen_Point.X,&Pen_Point.Y))
	{
		Pen_Point.X0=Pen_Point.xfac*Pen_Point.X+Pen_Point.xoff;
		Pen_Point.Y0=Pen_Point.yfac*Pen_Point.Y+Pen_Point.yoff;  
	}
}

void Touch_Adjust(void)
{								 
	uint16_t pos_temp[4][2];
	uint8_t  cnt=0;	
	uint16_t d1,d2;
	uint32_t tem1,tem2;
	float fac; 	   
	cnt=0;				
	POINT_COLOR=BLUE;
	BACK_COLOR =WHITE;
	LCD_Clear(WHITE);  
	POINT_COLOR=RED;
	LCD_Clear(WHITE);
	Drow_Touch_Point(20,20); 
	Pen_Point.Key_Sta=Key_Up;
	Pen_Point.xfac=0;	 
	while(1)
	{
		if(Pen_Point.Key_Sta==Key_Down)
		{
			if(Read_TP_Once())
			{  								   
				pos_temp[cnt][0]=Pen_Point.X;
				pos_temp[cnt][1]=Pen_Point.Y;
				cnt++;
			}			 
			switch(cnt)
			{			   
				case 1:
					LCD_Clear(WHITE);
					Drow_Touch_Point(220,20);
					break;
				case 2:
					LCD_Clear(WHITE);
					Drow_Touch_Point(20,300);
					break;
				case 3:
					LCD_Clear(WHITE);
					Drow_Touch_Point(220,300);
					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);
					
					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);
					fac=(float)d1/d2;
					if(fac<0.95||fac>1.05||d1==0||d2==0)
					{
						cnt=0;
						LCD_Clear(WHITE);
						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);
					
					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);
					fac=(float)d1/d2;
					if(fac<0.95||fac>1.05)
					{
						cnt=0;
						LCD_Clear(WHITE);
						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);
	
					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);
					fac=(float)d1/d2;
					if(fac<0.95||fac>1.05)
					{
						cnt=0;
						LCD_Clear(WHITE);
						Drow_Touch_Point(20,20);
						continue;
					}

					Pen_Point.xfac=(float)200/(pos_temp[1][0]-pos_temp[0][0]);		 
					Pen_Point.xoff=(240-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;
						  
					Pen_Point.yfac=(float)280/(pos_temp[2][1]-pos_temp[0][1]);
					Pen_Point.yoff=(320-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;
					POINT_COLOR=BLUE;
					LCD_Clear(WHITE);
					LCD_ShowString(35,110,"Touch Screen Adjust OK!");
					Delay(1000);
					LCD_Clear(WHITE); 
					return;			 
			}
		}
	} 
}
void Touch_Init()
{
	Touch_Configuration();
 	Read_ADS(&Pen_Point.X,&Pen_Point.Y);//µÚÒ»´Î¶ÁÈ¡³õʼ»¯			 

  	/* Connect PEN EXTI Line to Key Button GPIO Pin */
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4);

  	/* Configure PEN EXTI Line to generate an interrupt on falling edge */  
  	EXTI_InitStructure.EXTI_Line = EXTI_Line4;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);

  	/* Generate software interrupt: simulate a falling edge applied on PEN EXTI line */
  	EXTI_GenerateSWInterrupt(EXTI_Line4);

	LCD_Clear(WHITE);
    Touch_Adjust(); 			   
}
void Touch_Configuration()
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE );  //ÖØÒª£¡£¡

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(GPIOC,&GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 	
	GPIO_Init(GPIOC,&GPIO_InitStructure);
}

void Pen_Int_Set(uint8_t en)
{
	if(en)EXTI->IMR|=1<<4;   	  	
	else EXTI->IMR&=~(1<<4);	   
}

void EXTI4_IRQHandler()
{
  if(EXTI_GetITStatus(EXTI_IMR_MR4) != RESET)
	{
		Pen_Point.Key_Sta=Key_Down;//°´¼ü°´Ï  		  				 
    EXTI_ClearITPendingBit(EXTI_IMR_MR4);
	}
}


Touch_Adjust diye bir fonksiyon var. Kalibrasyon işlemi burada yapılıyor. Yine Yapılan işlemi pek anlayamadım ama gerçekte denedim oluşan şunlar.

Sırayla Ekranın 4 köşesine bir işaret koyuluyor. Ben her seferinde ekrana yerleştirilen işaret üzerine dokunduğumda o an verdiğim kordinatlar kaydediliyor. Sonra Başka bir köşeye nokta koyuluyor. Bu işlem Ekranın 4 köşesine uygulanınca kalibrasyon işlemi bitiyor ve bazı hesaplamalar yapıyor. Bu hesaplamaları yine anlayamadım ama çözerim.

Fakat dikkatimi çekti TCS2446 ile daha uğraşmış olduğum STMPE811 deki gibi rastgele kordinat verme olayları kesinlikle gerçekleşmiyor. Demekki yazılımın rolü çok büyük.