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

📄 touch.c

📁 基于ADS1.2环境编写的操作NANDFLASH存储器的移植了UC/OS-II的源代码
💻 C
字号:
/****************************************************************
 *  本实验为触摸屏实验											*
 *																*
 *  描述:就是把ads7846触摸屏控制器读出的A/D转换值映射成LCD坐标	*
 *																*
 *  在第三部分《进阶》中可同图形用户界面GUI组合作为输入设备		*  
 *																*
 *  参考:\datashhet\ads7846.pdf								*
 *																*
 ***************************************************************/
 
#include "44b.h"
#include "def.h" 

#include "44blib.h"
#include "touch.h"

INT32 ulLcdTouchBufferIndex = -1;        //缓存区计数

INT32 GetTouchX,GetTouchY;

void Ads7846_Delay(void);                //CLK 的时钟脉宽,太快时ads7846不能接收


//当有触摸时,Exint7上的电平变为LOW
INT8U GetDInt()                      
{
	return (rPDATG & 0x80)?1:0;
}


//发送8bit的命令到ads7846(DIN 腿)
void Ads7846_SendCommand(INT8U ucCommand)
{
	INT8U i,data;

	data=ucCommand;
	
	for (i = 0; i < 8; i++)
	{
		if (data&0x80)
			DIN_H();        
		else 
		    DIN_L();
		
		data<<=1;            //下一 bit
		CLK_H();
		Ads7846_Delay();     
		CLK_L();             //H->L 下降沿ads7846读入1bit
		DIN_L();
		Ads7846_Delay();
	}
}


//ads7846返回12BIT的A/D转换值
INT32U Ads7846_Get(INT8U ucCommand)
{
	INT8U i;
	INT32U ulData = 0;


	CLK_L();            
	Ads7846_Delay();
	CS_L();						//片选为低: 选中Ads7846
	Ads7846_Delay();
	Ads7846_SendCommand(ucCommand);
	DIN_L();
	CLK_H();
	Ads7846_Delay();
	CLK_L();
	Ads7846_Delay();
	while (BUSY());           //Ads7846的转换时间
	for (i = 0; i < 12; i++)  //12 bit 的转换值
	{
		DIN_L();
		ulData <<= 1;		  
		ulData += DOUT();	  //读入一位
		CLK_H();             
		Ads7846_Delay();
		CLK_L();           
		Ads7846_Delay();
	}
	for (i = 0; i < 3; i++)   //丢调16-12=4位
	{
		DIN_L();
		CLK_H();     
		Ads7846_Delay();
		CLK_L();
		Ads7846_Delay();
	}
	CS_H();						//片选为高
	return ulData;
	
}



//读取完整的A/D值(X,Y)并换算成对应的LCD坐标(x,y)
INT32U QueryAds7846(void)
{
	INT8U i;
	INT32U ulMaxX = 0;
	INT32U ulMinX = 0xffffffff;
	INT32U ulMaxY = 0;
	INT32U ulMinY = 0xffffffff;
	INT32U ulX =  0;
	INT32U ulY =  0;
	INT32U ulAverageY = 0;
	INT32U ulAverageX = 0;

	
	if (GetDInt() == 0)
	{
		for (i = 0; i < 10; i++)		//取10次 Y 方向的A/D转换值
		{
			ulY = Ads7846_Get(COMMAND_GET_Y);
			if (ulY > ulMaxY)           //去除无理值
			{
				ulMaxY = ulY;
			}
			if (ulY < ulMinY)
			{
				ulMinY = ulY;
			}
			ulAverageY += ulY;
		}
		
		for (i = 0; i < 10; i++)		//取10次 X 方向的A/D转换值
		{
			ulX = Ads7846_Get(COMMAND_GET_X);
			if (ulX > ulMaxX)			//去除无理值
			{
				ulMaxX = ulX;
			}
			if (ulX < ulMinX)
			{
				ulMinX = ulX;
			}
			ulAverageX += ulX;
			
		}
		
		ulAverageX = (ulAverageX - ulMaxX - ulMinX) / 8;     //去除最大和最小值后取平均值
		ulAverageY = (ulAverageY - ulMaxY - ulMinY) / 8;

		if (ulAverageX < XORDINAMIN)  
		    {
		        ulAverageX = XORDINAMIN;
			}		  	
		if (ulAverageX > XORDINAMAX)
			{
		        ulAverageX = XORDINAMAX;
			}		  
		if (ulAverageY < YORDINAMIN)
	        {
	            ulAverageY = YORDINAMIN;
			}		 
		if (ulAverageY > YORDINAMAX)
		    {
		        ulAverageY = YORDINAMAX;
			}	
			
		ulLcdTouchBufferIndex++;
		if (ulLcdTouchBufferIndex == LCD_TOUCH_BUFFER_SIZE)
		{
			ulLcdTouchBufferIndex = 0;
		}
		GetTouchX = ADC2X(ulAverageX);
		GetTouchY = ADC2Y(ulAverageY);
		return 0x1;                       //按下
	}
	else
	{
		return 0x0;           //无按下
	}
	//Ads7846_Init();
}


//CLK时钟的脉宽
void Ads7846_Delay()
{
	volatile INT8U i;
	
	for (i = 0; i < 40; i++);                 
}


//CS 	PE5     
//CLK 	PF8=SIOCLK
//DIN	PF5=SIOTXD
//DOUT  PF7=SIORXD
//BUSY   PF6=SIORDY
//PenIrq  PG7=EXINT7
void Ads7846_Portinit(void)
{
	
//--CS:GPE5
	rPCONE = (rPCONE & ~0xC00) + (0x1 << 10);


//-- SPI(SIO):
	rPCONF=(rPCONF&0x3ff)+(1<<19)+(0<<16)+(0<<13)+(1<<10);
	rPUPF =(rPUPF&~0x1E0) |0x160;//SIORxD 必须接上上拉电阻

//--EXTINT7
	rPCONG &=~0xC000;		//PORTG口的第7位工作为输入方式EINT7
    rPUPG&=0x7f;			//打开Extint7 内部上拉电阻	    




}

/****************************************************************
 *                                                             	*
 *   按触摸屏的四个角分析得出                                  	*
 *	 XORDINAMAX     //X方向A/D最大值 							*  
 *   XORDINAMIN     //X方向A/D最小值							*
 *   YORDINAMAX     //Y方向A/D最大值							*
 *   YORDINAMIN     //Y方向A/D最小值							*
 *   然后校准上面的定义,再重新编译								*
 ****************************************************************/
 
void  CheckTouch(void)
{
	INT8U i;
	INT32U ulMaxX = 0;
	INT32U ulMinX = 0xffffffff;
	INT32U ulMaxY = 0;
	INT32U ulMinY = 0xffffffff;
	INT32U ulX =  0;
	INT32U ulY =  0;
	INT32U ulAverageX = 0;
	INT32U ulAverageY = 0;


	while(GetDInt());
	{
		for (i = 0; i < 130; i++)		//取10次 Y 方向的A/D转换值
		{
			ulY = Ads7846_Get(COMMAND_GET_Y);
			if (ulY > ulMaxY)           //去除无理值
			{
				ulMaxY = ulY;
			}
			if (ulY < ulMinY)
			{
				ulMinY = ulY;
			}
			ulAverageY += ulY;
		}
		
		
		for (i = 0; i < 130; i++)		//取10次 X 方向的A/D转换值
		{
			ulX = Ads7846_Get(COMMAND_GET_X);
			if (ulX > ulMaxX)			//去除无理值
			{
				ulMaxX = ulX;
			}
			if (ulX < ulMinX)
			{
				ulMinX = ulX;
			}
			ulAverageX += ulX;
		}

		ulAverageX = (ulAverageX - ulMaxX - ulMinX) / 128;     //去除最大和最小值后取平均值

		ulAverageY = (ulAverageY - ulMaxY - ulMinY) / 128;
		
		for (i=0;i<10;i++);	//****在此设断点
		
	}                                   
}


⌨️ 快捷键说明

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