概述
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);//读取产品IDili2130_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"); //打印IDreturn 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"); //打印IDfor(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博客