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

📄 touchstreen.c

📁 STM32+Grlib
💻 C
📖 第 1 页 / 共 2 页
字号:
/*

* @file   touchstreen.c
  
* @author  dayong
* @version V1.0
* @date    05/24/2012




*/




#include "stm32f10x.h"
#include "fsmc_sram.h"
#include "grlib/grlib.h"
#include "grlib/widget.h"
#include "touchstreen.h"

#include "Calibrate.h"//偏移量矫正算法

#include "lcdhal.h"

#include "usart.h"
//extern TOUCH_CorrectionTypeDef g_TouchCorrectionStruct;	//触摸屏矫正量	结构体


#define  Up  1	

#define  Down 0

extern unsigned char g_ucPenUpDownState;

extern PointTypeDef g_strDpy_Point;
extern TOUCH_CorrectionTypeDef g_strTouchCorrectionStruct;

static long (*g_pfnTSHandler)(unsigned long ulMessage, long lX, long lY);
/****************************************************************************
* 名    称:void XTP2046_Init(void)
* 功    能:TFT 触摸屏控制初始化
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:无 
****************************************************************************/
 void XTP2046_Init(void) 
{ 
	GPIO_InitTypeDef  GPIO_InitStructure; 
	SPI_InitTypeDef   SPI_InitStructure; 
	
	/* SPI1 时钟使能 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE); 
	
	/* SPI1 SCK(PA5)、MISO(PA6)、MOSI(PA7) 设置 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//口线速度50MHZ
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	        //复用模式
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;				 //触摸检测引脚
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  	GPIO_Init(GPIOB, &GPIO_InitStructure);
	/* SPI1 触摸芯片的片选控制设置 PB7 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//口线速度50MHZ 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			//推挽输出模式
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	
	/* 由于SPI1总线上挂接了4个外设,所以在使用触摸屏时,需要禁止其余3个SPI1 外设, 才能正常工作 */  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;           		//SPI1 SST25VF016B片选 
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                //SPI1 VS1003片选 
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                 //SPI1 网络模块片选
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOC, GPIO_Pin_4);							//SPI CS1
	GPIO_SetBits(GPIOB, GPIO_Pin_12);							//SPI CS4
	GPIO_SetBits(GPIOA, GPIO_Pin_4);							//SPI NSS	   
	
	/* SPI1总线 配置 */ 
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;   	//全双工  
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;						   	//主模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;					   	//8位
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;						   		//时钟极性 空闲状态时,SCK保持低电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;						   	//时钟相位 数据采样从第一个时钟边沿开始
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;							   	//软件产生NSS
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;  	//波特率控制 SYSCLK/64
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;				   		//数据高位在前
	SPI_InitStructure.SPI_CRCPolynomial = 7;							   	//CRC多项式寄存器初始值为7 
	SPI_Init(SPI1, &SPI_InitStructure);
	
	/* SPI1 使能 */  
	SPI_Cmd(SPI1,ENABLE);  
}

/****************************************************************************
* 名    称:unsigned char SPI_WriteByte(unsigned char data) 
* 功    能:SPI1 写函数
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:
****************************************************************************/  
unsigned char SPI_WriteByte(unsigned char ucData) 
{ 
  unsigned char ucDat = 0; 

  //等待发送缓冲区空
  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET); 
  // 发送一个字节  
  SPI_I2S_SendData(SPI1,ucData); 

   //等待是否接收到一个字节 
  while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET); 
  // 获得该字节
  ucDat = SPI_I2S_ReceiveData(SPI1); 

  // 返回收到的字节 
  return ucDat; 
}  


/****************************************************************************
* 名    称:unsigned char  XTP2046ReadX(void) 
* 功    能:触摸屏X轴数据读出
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:
****************************************************************************/  
unsigned int  XTP2046Read_X(void)
{ 
   unsigned int uiX=0;
   TP_CS();	                        //选择XPT2046 
   Delay(20);						//延时
   SPI_WriteByte(0x90);				//设置X轴读取标志
   Delay(20);						//延时
   uiX=SPI_WriteByte(0x00);			//连续读取16位的数据 
   uiX<<=8;
   uiX+=SPI_WriteByte(0x00);
   Delay(20);						//禁止XPT2046
   TP_DCS(); 					    								  
   uiX = uiX>>3;						//移位换算成12位的有效数据0-4095
   //uiX = uiX>>5;						//移位换算成10位有效数据
   return (uiX);
}
/****************************************************************************
* 名    称:unsigned char  XTP2046Read_Y(void)
* 功    能:触摸屏Y轴数据读出
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:
****************************************************************************/
unsigned int  XTP2046Read_Y(void)
{
   unsigned int uiY =0;
   TP_CS();	                        //选择XPT2046 
   Delay(20);						//延时
   SPI_WriteByte(0xD0);				//设置Y轴读取标志
   Delay(20);						//延时
   uiY=SPI_WriteByte(0x00);			//连续读取16位的数据 
   uiY<<=8;
   uiY+=SPI_WriteByte(0x00);
   Delay(20);						//禁止XPT2046
   TP_DCS(); 					    								  
   uiY = uiY>>3;						//移位换算成12位的有效数据0-4095
   //uiY = uiY>>5;						//移位换算成10位有效数据
   return (uiY);
}

/****************************************************************************
* 名    称:void Get_Coordinat(POINT *psPOINT)
* 功    能:读取触摸坐标,
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:
****************************************************************************/

//unsigned char  Get_Coordinat(POINT *psPOINT)
void Get_Coordinat(PointTypeDef *psPOINT)
{	
	unsigned int uiX,uiY;	    
	unsigned char  ucT,ucT1,ucCount = 0;			
	unsigned int  uiDatabuffer[2][30];    				         //触摸坐标过采样缓冲区
	unsigned int  uiTemp=0;	 
    do{			
		uiX	=XTP2046Read_X();		   
		uiY	=XTP2046Read_Y();				                             //循环读数30次	
		
		if(uiX>100&&uiX<4000&&uiY>100&&uiY<4000)             //如果是在触摸显示有效区范围的值,标示此读数有效
		{	
			  
			uiDatabuffer[0][ucCount]=uiX;
			uiDatabuffer[1][ucCount]=uiY;
			ucCount++;  
		} 		
	}while(ucCount<30); 
				  		 
	if(ucCount==30)                                    //每次度数一定要读到30次数据,否则丢弃
	{  
		
	    do                                            //将数据X升序排列
		{				
			ucT1=0;		  
			for(ucT=0;ucT<ucCount-1;ucT++)
			{
				if(uiDatabuffer[0][ucT]>uiDatabuffer[0][ucT+1])//升序排列
				{
					uiTemp=uiDatabuffer[0][ucT+1];
					uiDatabuffer[0][ucT+1]=uiDatabuffer[0][ucT];
					uiDatabuffer[0][ucT]=uiTemp;
					ucT1=1; 
				}  
			}
		}while(ucT1);
 	  
		do                                              //将数据Y升序排列
		{	

			ucT1=0;		 
			for(ucT=0;ucT<ucCount-1;ucT++)
			{
				if(uiDatabuffer[1][ucT]>uiDatabuffer[1][ucT+1])//升序排列
				{
					uiTemp=uiDatabuffer[1][ucT+1];
					uiDatabuffer[1][ucT+1]=uiDatabuffer[1][ucT];
					uiDatabuffer[1][ucT]=uiTemp;
					ucT1=1;	 
				}  
			}
		}while(ucT1);
		/* 从排序过的数组里中间抽取连续的10组数据,进行取平均值,获得较高的精度 */
		for(ucCount=10;ucCount<20; ucCount++)
		{
			uiX=uiX+uiDatabuffer[0][ucCount];
			uiY=uiY+uiDatabuffer[1][ucCount];
		}
		//USART_OUT(USART1,"0103");
		if(uiX%10 > 5)
		{
			psPOINT->uiX = uiX/10 +1;
		//	USART_OUT(USART1,"0104");
		}	
			
		else
		{
			psPOINT->uiX = uiX/10;
		//	USART_OUT(USART1,"0105");
		}
			
	
		if(uiY%10 > 5)
		{
			psPOINT->uiY = (uiY/10 + 1);
		//   USART_OUT(USART1,"0106");
		  }
		else
		{
			psPOINT->uiY = (uiY/10);
		//    USART_OUT(USART1,"0107");
		}
	//	USART_OUT(USART1,"0108");
		//return 1;
	}
	//USART_OUT(USART1,"0109");
	USART_OUT(USART1,"x=%d ",psPOINT->uiX);
	USART_OUT(USART1,"y=%d ",psPOINT->uiY);

}

  
/*
#define 	VALUE	5

unsigned char Get_Coordinat(POINT *psScreen)
{
	
	//POINT *Screen;

	int m0,m1,m2;

	unsigned char count = 0;

	unsigned int databuffer[2][9]={{0},{0}};//

	unsigned int temp[3];
	while(1)
	{
		do
		{
			databuffer[1][count] = XTP2046Read_X();	// V H coordinat swap	   
			databuffer[0][count] = XTP2046Read_Y();	//
			count ++;
		}while(count<9);
	
		if(count == 9)
		{
			temp[0]=(databuffer[0][0]+databuffer[0][1]+databuffer[0][2])/3;
			temp[1]=(databuffer[0][3]+databuffer[0][4]+databuffer[0][5])/3;
			temp[2]=(databuffer[0][6]+databuffer[0][7]+databuffer[0][8])/3;
	
			m0 = temp[0] - temp[1];
			m1 = temp[1] - temp[2];
			m2 = temp[2] - temp[0];
	
			m0 = m0 > 0 ? m0  : (0-m0);
			m1 = m1 > 0 ? m1  : (0-m1);
			m2 = m2 > 0 ? m2  : (0-m2);
	
			if(m0 > VALUE && m1 > VALUE && m2 > VALUE)
			{
			   	return 0;			
			}
		
			if(m0 < m1)
			{
	
				if(m2 < m0)
					psScreen->x = (temp[0] + temp[2])/2;
				else
					psScreen->x = (temp[0] + temp[1])/2;
					
			}
			else
				{				
					if(m2 < m1)
						psScreen->x = (temp[0] + temp[2])/2;
					else
						psScreen->x = (temp[1] + temp[2])/2;		
				}
	
			temp[0]=(databuffer[1][0]+databuffer[1][1]+databuffer[1][2])/3;
			temp[1]=(databuffer[1][3]+databuffer[1][4]+databuffer[1][5])/3;
			temp[2]=(databuffer[1][6]+databuffer[1][7]+databuffer[1][8])/3;
	
			m0 = temp[0] - temp[1];
			m1 = temp[1] - temp[2];
			m2 = temp[2] - temp[0];
	
			m0 = m0 > 0 ? m0  : (0-m0);
			m1 = m1 > 0 ? m1  : (0-m1);
			m2 = m2 > 0 ? m2  : (0-m2);
	
			if(m0 > VALUE && m1 > VALUE && m2 > VALUE)
			{
			   return 0;
			}
				
			if(m0 < m1)
			{
				if(m2 < m0)
				 	psScreen->y = (temp[0] + temp[2])/2;
					
				else
					psScreen->y = (temp[0] + temp[1])/2;
	
				return 1;
								
			}
			else
			{
				if(m2 < m1)
					psScreen->y = (temp[0] + temp[2])/2;
					
				else
					psScreen->y = (temp[1] + temp[2])/2;
	
				return 1;
				
			}
			break;
		}
	}
	return 0;
}
*/

/****************************************************************************
* 名    称:void Get_TouchCorrection(TOUCH_CorrectionTypeDef *TouchCorrectionStruct)
* 功    能:获取触摸屏校正量,
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:
****************************************************************************/ 
void Get_TouchCorrection(TOUCH_CorrectionTypeDef *TouchCorrectionStruct)
{

	PointTypeDef strPoint1;	//第一个校正点
	PointTypeDef strPoint2;	//第二个校正点
	unsigned char ucI;
	for(ucI=0; ucI<10; ucI++)
	{						   //在竖屏模式下,左上角显示第一个校正点点击区域
		
		PixelDraw (0,0,0+ucI,0xffff);
		
		PixelDraw (0,0+ucI,0,0xffff);
  	}
	USART_OUT(USART1,"push the first Point"); 	
	while (1)                   				   //等待点击第一个触摸校正点
	{    						   
		 if(PEN==0)					   			//点击第一个校正点 等待触摸检测电平变低
		 {							   
			Delay(34000);					   	//延时340ms 消除抖动
			if(PEN==0)
			{							   		//检测触摸中断线是否可靠点击
				while(PEN==0)		   			//点击未松开,持续读取触摸坐标
				{					   
				    Delay(1);					
					Get_Coordinat(&strPoint1);//读取触摸坐标
					   
					 //获得第一个校正点的X,Y
					TouchCorrectionStruct->uiXs=strPoint1.uiX;
					TouchCorrectionStruct->uiYs=strPoint1.uiY;	
					Delay(34000);			   //延时340ms 消除抖动		
				}

⌨️ 快捷键说明

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