XuSenfeng

个人站

复读了,更新随缘,有的文件不全或者图片缺失具体看我的笔记库(https://github.com/XuSenfeng/note)


触摸屏

目录

触摸屏

电阻触摸屏只能一次一个点, 电容屏可以有多个

  • 电阻屏: 有两层均匀的电阻叫做ITO层, 有间隔点隔开, 受到压力的时候会接触, 在接触点链接, 使得电阻变化, 一般会引出四根线, X+, X-, Y+, Y-, 分别检测电阻, x和y分开时间供电, 一侧供电, 另一侧检测电压, 使用ADC进行检测, 也可以使用专门的芯片进行检测

触摸校准: 由于硬件的信息不同, 需要校准

  • 电容屏: 直接可以得出触点的坐标, 也是用ITO层, X轴Y轴不导电, 之间产生电容, 平时对X轴产生一个波动信号, 当手放上的时候, 会对电路分流, 使得Y达到电压阈值的时间变大, 轮流通电, 同时检测, 可以得到实际的位置

image-20230713181001349

实现

image-20230713181852133

一遍链接电阻屏, 另一边链接stm32, PENDIRQ, 有信号之后产生信号, AUX电压辅助通道不使用

控制原理

实际上是一个十二位的SDC, 最大为4096, 通过比例获得位置, 使用内部电压源, 通过发送命令获得数据

image-20230713182801896

7: 准备开始检测

6-4:

image-20230713191549154

3: 检测的模式

2: 设置为0, 1的时候使用AUX引脚

1-0: 节省电源, 设置为00的时候会在获取数据的时候再去产生电场

设置为0x90, 获取X通道数字, 0xD0获取Y的数字

image-20230713192050741

使用软件SPI

//发送命令
void XPT2046_SendCMD(uint8_t cmd)	
{
	uint8_t i;
	
	/*设置引脚的初始状态*/
	XPT2046_CS_ENABLE();//片选引脚设置为低电平
	XPT2046_CLK_LOW();//时钟为低电平
	XPT2046_MOSI_0();
	
	/*片选选中*/
	XPT2046_DelayUS(10);
	XPT2046_CS_DISABLE();
	
	/*产生8个时钟,发送数据*/
	for(i=0;i<8;i++)
	{
		if( (cmd & (0x80>>i)) == 0 )
		{
			XPT2046_MOSI_0();
		}
		else
		{
			XPT2046_MOSI_1();		
		}		
		
		XPT2046_CLK_HIGH();		
		XPT2046_DelayUS(5);
			
		XPT2046_CLK_LOW();
		XPT2046_DelayUS(5);	
	}	
	
//	/*片选取消*/
//	XPT2046_CS_ENABLE();
	
}

在上升沿的时候采样, 高数据位先行

//读取数据
uint16_t XPT2046_ReceiveData(void)	
{
	uint8_t i;
	
	uint16_t receive_temp=0;
	
//	/*设置引脚的初始状态*/
//	XPT2046_CS_ENABLE();
//	XPT2046_CLK_LOW();
//	XPT2046_MOSI_0();
//	
//	/*片选选中*/
//	XPT2046_DelayUS(10);
//	XPT2046_CS_DISABLE();
	
		XPT2046_CLK_HIGH();		
		XPT2046_DelayUS(5);
		XPT2046_CLK_LOW();
		XPT2046_DelayUS(5);	
	
	/*产生12个时钟,读取数据*/
	for(i=0;i < 12;i++)
	{		
		receive_temp = receive_temp << 1;

		XPT2046_CLK_HIGH();		
		XPT2046_DelayUS(5);
		
		
		if( XPT2046_MISO() == Bit_SET)
		{
			receive_temp |= 0x01;
		}
		else
		{
			receive_temp |= 0x00;		
		}				
			
		XPT2046_CLK_LOW();
		XPT2046_DelayUS(5);	

	}	
	
	/*片选取消*/
	XPT2046_CS_ENABLE();
	
	return receive_temp;
	
}

高电平的时候数据是稳定的

在发送命令到接收时序直接片选不能中断, 且两个中间有一个时钟间隔, 可以使用一直片选

使用状态机检测

检测输出按下释放两种状态

检测

image-20230713201105922

//触摸检测状态机
uint8_t touch_detect(void)
{
	static Touch_State touch_state = XPT2046_STATE_RELEASE; 
	static uint8_t i;
	uint8_t result;
	
	switch(touch_state)
	{
		case XPT2046_STATE_RELEASE:
				//之前没有按下,现在检测为低电平
				if(XPT2046_PENIRQ_Read() == XPT2046_PENIRQ_ActiveLevel)
				{
				
					touch_state = XPT2046_STATE_WAITING;
					result = TOUCH_NOT_PRESSED;
				}
				else
				{							
					touch_state = XPT2046_STATE_RELEASE;
					result = TOUCH_NOT_PRESSED;
				}						
		break;
		
		case XPT2046_STATE_WAITING:
			//在等待状态,再次检测
			if(XPT2046_PENIRQ_Read() == XPT2046_PENIRQ_ActiveLevel)
				{
					i++;
					
					if(i>10)
					{
						//进行延时后检测为按下
						touch_state = XPT2046_STATE_PRESSED;
						result = TOUCH_PRESSED;
					}		
					else
					{	//等待没有结束
						touch_state = XPT2046_STATE_WAITING;
						result = TOUCH_NOT_PRESSED;							
					}										
						
				}
				else
				{					
						i = 0;
						touch_state = XPT2046_STATE_RELEASE;
						result = TOUCH_NOT_PRESSED;
				}				
		
			break;
		
		case XPT2046_STATE_PRESSED:			
						if(XPT2046_PENIRQ_Read() == XPT2046_PENIRQ_ActiveLevel)
						{
								touch_state = XPT2046_STATE_PRESSED;
								result = TOUCH_PRESSED;
						}
						else
						{							
								touch_state = XPT2046_STATE_RELEASE;
								result = TOUCH_NOT_PRESSED;
						}	
			
			break;
	
	}
	
	return result;
}