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通信,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