ILI2130触控IC驱动

发布时间:2024年01月18日

概述

ili2130触控网上有关的介绍很少,官网也没有有用的东西,所以记录一其驱动(MCU驱动)。此外ILI2520, ILI2521, ILI2322, ILI2323, ILI2316, ILI2326, ILI2130, ILI2131, ILI2132这几款触控IC使用的是同一个用户指导手册,他们的驱动方式一样,所以驱动原理也是大差不差。

引脚介绍

它可以使用IIC和USB通讯,我们选用的是IIC通信的,成品对外引脚有6根,分别是SDA,SCL,INT,RST,VCC,GND;其中SDA与SCL是IIC通讯引脚,INT是中断引脚,当TP芯片检测到触摸信号时,会拉低该引脚;单片机可检测该引脚的电平变化来判断是否读取TP的信息;RST是TP的复位引脚,VCC和GND分别为电源和地。

IIC通信

它使用的IIC通信,7位地址是0x41,读地址是0x83,写地址是0x82,一般出厂的IC里面已经写好了寄存器配置,不需要我们再去重新配置,所以这里主要是读取IC寄存器就行了,读取IC寄存器主要是如上的协议,注意一次最长读取31个字节大小,超过31个要重新发送一次读取信号。?

驱动程序?

首先是最底层的IIC读写,底层的IIC自己实现,我这里只写出读写实现,我使用的是模拟IIC

//向ILI2130写入一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:写数据长度
//返回值:0,成功;1,失败.
uint8_t ILI2130_WR_Reg(uint8_t reg,uint8_t *buf,uint8_t len)
{
	uint8_t i;
	uint8_t ret=0;
	CT_IIC_Start();	
 	CT_IIC_Send_Byte(ILI_CMD_WR);   	//发送写命令 	 
	CT_IIC_Wait_Ack();
	CT_IIC_Send_Byte(reg);   	//发送高8位地址
	CT_IIC_Wait_Ack(); 	 										  		   
	for(i=0;i<len;i++)
	{	   
    	CT_IIC_Send_Byte(buf[i]);  	//发数据
		ret=CT_IIC_Wait_Ack();
		if(ret)break;  
	}
    CT_IIC_Stop();					//产生一个停止条件	    
	return ret; 
}

//从ILI2130读出一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:读数据长度			  
void ILI2130_RD_Reg(uint8_t reg,uint8_t *buf,uint8_t len)
{
	uint8_t i; 
 	CT_IIC_Start();	
 	CT_IIC_Send_Byte(ILI_CMD_WR);   //发送写命令 	 
	CT_IIC_Wait_Ack();
 	CT_IIC_Send_Byte(reg);   	//发送高8位地址
	CT_IIC_Wait_Ack(); 	 										  		   
 	CT_IIC_Start();  	 	   
	CT_IIC_Send_Byte(ILI_CMD_RD);   //发送读命令		   
	CT_IIC_Wait_Ack();	   
	for(i=0;i<len;i++)
	{	   
    	buf[i]=CT_IIC_Read_Byte(i==(len-1)?0:1); //发数据	  
	} 
    CT_IIC_Stop();//产生一个停止条件    
} 

//从ILI2130继续读出一次数据,读取的字节数大于31字节后使用
//buf:数据缓缓存区
//len:读数据长度			  
void ILI2130_RD_Reg_Continue(uint8_t *buf,uint8_t len)
{
	uint8_t i; 
										  		   
 	CT_IIC_Start();  	 	   
	CT_IIC_Send_Byte(ILI_CMD_RD);   //发送读命令		   
	CT_IIC_Wait_Ack();	   
	for(i=0;i<len;i++)
	{	   
    	buf[i]=CT_IIC_Read_Byte(i==(len-1)?0:1); //发数据	  
	} 
    CT_IIC_Stop();//产生一个停止条件    
} 

然后是ILI2130触摸芯片的初始化

void ILI2130_INT_Init(void)
{
    rcu_periph_clock_enable(ILI_INT_CLOCK);
    rcu_periph_clock_enable(RCU_SYSCFG);
	
	gpio_mode_set(ILI_INT_PORT,  GPIO_MODE_INPUT,  GPIO_PUPD_NONE,  ILI_INT_PIN);//模式设置
	gpio_output_options_set(ILI_INT_PORT,  GPIO_OTYPE_PP,  GPIO_OSPEED_50MHZ,  ILI_INT_PIN);	//输出设置

	#if 1	//打开中断的话,如果检测到按下则INT引脚会在每个检测周期都输出一个脉冲信号
	syscfg_exti_line_config(EXTI_SOURCE_GPIOC, EXTI_SOURCE_PIN8);
	exti_init(EXTI_8 , EXTI_INTERRUPT ,  EXTI_TRIG_FALLING);
	nvic_irq_enable(EXTI5_9_IRQn , 2, 0 );
	exti_interrupt_enable( EXTI_8);	
	#endif
	
}


//初始化ILI2130触摸屏
//返回值:0,初始化成功;1,初始化失败 
uint8_t ILI2130_Init(void)
{
	uint8_t temp[15] = {0}; 
	
//	rcu_periph_clock_enable(ILI_INT_CLOCK);
//	rcu_periph_clock_enable(ILI_RST_CLOCK);

//	gpio_mode_set(ILI_INT_CLOCK,  GPIO_MODE_OUTPUT,  GPIO_PUPD_PULLUP,  ILI_INT_PIN);//模式设置
//	gpio_output_options_set(ILI_INT_CLOCK,  GPIO_OTYPE_PP,  GPIO_OSPEED_50MHZ,  ILI_INT_PIN);	//输出设置
//	gpio_bit_set(ILI_INT_PORT,  ILI_INT_PIN);	//默认输出低电平
	
	gpio_mode_set(ILI_RST_CLOCK,  GPIO_MODE_OUTPUT,  GPIO_PUPD_PULLUP,  ILI_RST_PIN);//模式设置
	gpio_output_options_set(ILI_RST_CLOCK,  GPIO_OTYPE_OD,  GPIO_OSPEED_50MHZ,  ILI_RST_PIN);	//输出设置
	gpio_bit_reset(ILI_RST_PORT,  ILI_RST_PIN);	//默认输出低电平
                
	CT_IIC_Init();      	//初始化电容屏的I2C总线  
	CT_IIC_Stop();
	ILI_RST(0);				//复位
	delay_ms(50);
 	ILI_RST(1);				//释放复位		    
	ILI_RST(200); 
	CT_IIC_Stop();

	ILI2130_INT_Init();

	ILI2130_RD_Reg(Get_Panel_Information_Reg,temp,15);//读取产品ID
	
	ili2130_tp_dev.xfac = 480/(float)ILI2130_MAX_REPORT_VALUE_X;	//将触摸面板的坐标位置映射到屏幕坐标
	ili2130_tp_dev.yfac = 854/(float)ILI2130_MAX_REPORT_VALUE_y;
	
	printf("***%f,%f***\r\n",ili2130_tp_dev.xfac,ili2130_tp_dev.yfac);
	
//	printf("ILI Info:\r\n");	//打印ID
//	for(int i=0;i<15;i++)
//	{
//		printf("%x ",temp[i]);
//	}
//	printf("\r\n<--------->\r\n");	//打印ID

	return 0;
}

?最后就是读取坐标位置


//扫描触摸屏(采用查询方式)
//mode:0,正常扫描.
//返回值:当前触屏状态.
//0,触屏无触摸;1,触屏有触摸
uint8_t ILI2130_Scan(uint8_t mode)
{
	uint8_t sharebuf[31] = {0};
	uint16_t temp = 0,i=0;
	int x,y;
	
	ILI2130_RD_Reg(ILTK_GET_TH,sharebuf,31);
	
//	printf("ILI touch:\r\n");	//打印ID
//	for(int i=0;i<31;i++)
//	{
//		printf("%x ",sharebuf[i]);
//	}
//	printf("\r\n<+++++++++++>\r\n");	//打印ID
	
	for(i=0;i<6;i++)
	{
		x = (sharebuf[5*i+3] << 8) | sharebuf[5*i+2] ;
		y = (sharebuf[5*i+5] << 8) | sharebuf[5*i+4] ;
		
		//触摸按下
		if(sharebuf[5*i+1]>>4)
		{
			temp |= (1<<i);
			ili2130_tp_dev.sta = temp |TP_PRES_DOWN|TP_CATH_PRES;
			ili2130_tp_dev.x[i] = (int)(x * ili2130_tp_dev.xfac);
			ili2130_tp_dev.y[i] = (int)(y * ili2130_tp_dev.yfac);
			printf("<%d>(%d,%d), ",i, ili2130_tp_dev.x[i],ili2130_tp_dev.y[i]);
		}
		else{
			if(i==0)
			{
				if(ili2130_tp_dev.sta & TP_PRES_DOWN)
				{
					ili2130_tp_dev.x[0]=0xffff;
					ili2130_tp_dev.y[0]=0xffff;
					ili2130_tp_dev.sta&=0X00;	//清除点有效标记	
				}
			}		
			break;
		}
	}
	printf("\r\n");
}
 
void EXTI5_9_IRQHandler(void)
{
	if(SET == exti_interrupt_flag_get( EXTI_8))
	{
		exti_interrupt_flag_clear(EXTI_8);
		exti_interrupt_disable(EXTI_8);
		printf("999\r\n");
		ILI2130_Scan(1);
		exti_interrupt_enable( EXTI_8);	
		
	}
}

注意事项

坐标位置映射

(非常重要)ILI2130读取0x10寄存器读取出来的值是相对与触控面板的坐标的并不是屏幕的,这点和我们使用GT9111直接读出屏幕XY坐标位置不一样,所以需要将触控面板的坐标映射到屏幕上,我们需要使用到ILI2130的XY最大返回值即分辨率,所以在我的初始化ILI2130函数内是有

?? ?ili2130_tp_dev.xfac = 480/(float)ILI2130_MAX_REPORT_VALUE_X;?? ?//将触摸面板的坐标位置映射到屏幕坐标
?? ?ili2130_tp_dev.yfac = 854/(float)ILI2130_MAX_REPORT_VALUE_y;

这段程序映射的在?0x40寄存器有ILI2130的信息,如下

?从0x20处读取的0-1个字节是X最大分辨率,2-3为Y的最大分辨率;第4-5个字节为TOUCH配置的X方向通道数,第5-6个字节为TOUCH配置的Y方向的通道数,第7个字节为TOUCH配置的最大支持的手指触摸的个数,等等…
当有触摸时,触摸点的坐标可从0X10处读取,注意这个0x10寄存器位置是在手册并没有看到,而是在别人的文章里看到的基于单片机的ILI2132驱动调试-CSDN博客;触摸点坐标格式如下图:

如果使用IIC读取的话,读取0x10的第一个字节是0x48表示IIC,byte1是需要读取的手指坐标的状态,bit6表示是否有触摸,为1表示有触摸发生,0表示无效;bit0-bit5为该有效触摸点的ID,若为多点触控时,没跟手指触摸时对应的ID是不同的;byte2-byte3是触摸点的X坐标,byte4-5是触摸点的Y坐标;
屏实际对应的坐标通过下列公式计算:
X=((屏x轴分辨率)/ maximum X coordinate)(X Position )
Y=((屏y轴分辨率)/ maximumY coordinate)(Y Position )

这个手册上面写的是有10个触控点,但是实际需要看你所使用的芯片最大支持几个触控点,我所使用的ILI2130最大只有6个点。

读取坐标位置

/*
读取的0x20寄存器(15个字节):
C8 00 |90 01 |15 00 |0C 00 |0a |00 |01 |01 ?? ? ? |00 ? |01 |08
200 ? |400 ? |21 ? ?|12 ? ?|10 |0 ?| ? |modle ?|格式 | ? |

读取的0x10寄存器(51个字节):
48 |[40 b8 0 7c 1 ][0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 90 1 15 0] [c 0 a 0 1] [1 0 1 8 0] [0 0 0 0 0]?
IIC [0按下 184,380]

48 |[40 e 0 12 0 ][ 0 0 0 0 0][ 0 0 0 0 0][ 0 0 0 0 0][ 0 0 0 0 0 ][0 0 0 0 0 ][0 90 1 15 0 ][c 0 a 0 1 ][1 0 1 8 0 ][0 0 0 0 0]
?? ?[0按下 14,18 ]

48 |[40 9 0 15 0][ 41 27 0 41 0][ 42 4b 0 78 0][ 43 51 0 dc 0][ 44 80 0 f9 0 ][45 94 0 46 1 ][0 90 1 15 0 ][c 0 a 0 1 ][1 0 1 8 0 ][0 0 0 0 0 ]
? ? [0> 9,21]?? ? [1> 39,65]?? ??? ?[2> 75,120]?? ??? ?[3> 81,220]?? ? ?[4> 128,249] ? ?[5> 148,326] ??
*/

测试没问题

驱动程序:https://download.csdn.net/download/qq_44675660/88756269

参考:基于单片机的ILI2132驱动调试-CSDN博客

文章来源:https://blog.csdn.net/qq_44675660/article/details/135665903
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。