基于单片机的ILI2132驱动调试

文章介绍了如何在没有可用的Linux驱动参考情况下,基于单片机实现奕力ILI2132电容式触摸屏的驱动调试。通过IIC总线协议与TP芯片通信,读取和解析寄存器数据,包括IC固件版本、分辨率等信息,以确保单片机与TP的IC通讯正常并能处理触摸事件。
摘要由CSDN通过智能技术生成

基于单片机的ILI2132驱动调试

    由于工作原因,需要将原先的电阻式触摸屏更换为电容式(TP)的。TOUCH方案选择了可靠性更高的奕力ILI2132,厂家提供的参考代码是基于Linux的,没法直接使用;而且厂家提供的驱动过于庞杂,对于不怎么接触Linux或者没写过TOUCH驱动的工程师来说比较困难。故此根据奕力提供的说明手册,自己实现了一个基于单片机的驱动;  
  1. IIC总线调试
    一般的电容式触摸屏均是通过IIC通讯的,成品对外引脚有6根,分别是SDA,SCL,INT,RST,VCC,GND;其中SDA与SCL是IIC通讯引脚,INT是中断引脚,当TP芯片检测到触摸信号时,会拉低该引脚;单片机可检测该引脚的电平变化来判断是否读取TP的信息;RST是TP的复位引脚,VCC和GND分别为电源和地;
    关于IIC总线的协议,可自行搜索了解。由于TP芯片出厂时会自行烧录一份固件程序,所以一般在使用的过程中几乎不会去往TP的IC寄存器中写数据,我们只需要读取相应的寄存器数据即可,下图(图1)为TP的IC手册提供的读信号操作;
    图1
    其中Slave Address为TP的IC作为从机的地址,根据芯片2132手册,地址是7位的,值为0x41,加上读写标志位一个bit,共同构成一个Byte,其中高7位为从机地址,最后一位为读写标志位,0表示写,1表示读;故写数据是地址为0x82,读数据是地址为0x83,如下图(图2);
    图2
    根据图1与图2,iic从TP的ic中读取信息分为两步,第一是要和IC握手成功,然后IC会根收到的命令返回寄存器中的内容;参考代码如下;
/*******************************************************************************
* Function Name  : ILI_WR_Reg
* Description    : 向ILI读入一次数据
* Input          : reg:起始寄存器地址
                   buf:数据缓缓存区
                   len:写数据长度
* Output         : None
* Return         : 0,成功;1,失败.
*******************************************************************************/
uint8_t ILI_WR_Reg(uint8_t reg,uint8_t *buf,uint8_t len)
{
	struct i2c_msg msgs[2];
    int32_t ret=-1;
    int32_t retries = 0;

    /*一个读数据的过程可以分为两个传输过程:
     * 1. IIC  写入 要读取的寄存器地址
     * 2. IIC  读取  数据
     * */

    msgs[0].flags = !I2C_M_RD;					
    msgs[0].addr  = GTP_ADDRESS;					
    msgs[0].len   = GTP_ADDR_LENGTH;	    
    msgs[0].buf   = ®//&buf[0];					
    
    msgs[1].flags = I2C_M_RD;					
    msgs[1].addr  = GTP_ADDRESS;				
    msgs[1].len   = len ;	
    msgs[1].buf   = &buf[0];	

    while(retries < 5)
    {
        ret = I2C_Transfer( msgs, 2);					//调用IIC数据传输过程函数,有2个传输过程
        if(ret == 2)break;
        retries++;
    }
    if((retries >= 5))
    {
    }
    return ret;
}

传输函数

 /**
  * @brief   使用IIC进行数据传输
  * @param
  *		@arg i2c_msg:数据传输结构体
  *		@arg num:数据传输结构体的个数
  * @retval  正常完成的传输结构个数,若不正常,返回0xff
  */
int I2C_Transfer( struct i2c_msg *msgs,int num)
{
    int im = 0;
    int ret = 0;

    for (im = 0; ret == 0 && im != num; im++)
    {
        if ((msgs[im].flags&I2C_M_RD))																//根据flag判断是读数据还是写数据
        {
            ret = Touch_I2C_ReadBytes(msgs[im].addr, msgs[im].buf, msgs[im].len);		//IIC读取数据
        }
        else
        {
            ret = Touch_I2C_WriteBytes(msgs[im].addr,  msgs[im].buf, msgs[im].len);	//IIC写入数据
        }
    }

	if(ret)
		return ret;

	return im;   													//正常完成的传输结构个数
}
      
        

读数据

/**
  * @brief   Read bytes by I2C
  * @param   
  *  @arg deviceAddr:Address of device.
  *		@arg pBuffer:pointer to data buffer.
  *		@arg NumByteToRead: number of data.
  * @retval
  */
uint32_t Touch_I2C_ReadBytes(uint8_t deviceAddr,uint8_t* pBuffer, uint16_t NumByteToRead)
{
	
		/* step 1: start I2C */
		Touch_I2C_Start();
		
		/* step 2: send device address and w/r control. */
		Touch_I2C_SendByte(deviceAddr | Touch_I2C_RD);
		
		/* step 3: wait ack. */
		if (Touch_I2C_WaitAck() != 0)
		{
			/* stop I2C */
					Touch_I2C_Stop();
					return 1;
		}

    while(NumByteToRead) 
    {
        *pBuffer = Touch_I2C_ReadByte();
        /* increment the pointer. */
        pBuffer++; 
			if(NumByteToRead == 1)
        {
            Touch_I2C_NoAck();	/* Read the last byte data,then cpu send NoACK(SDA = 1). */
           /* stop I2C. */
            Touch_I2C_Stop();
       }
        /* decrement the counter. */
        NumByteToRead--; 
        Touch_I2C_Ack();	/* Send ack(SDA = 0). */  
    }

			/* Stop I2C. */
			Touch_I2C_Stop();
	return 0;	/* Seccessful. */
}

写数据

/**
 1. @brief   Write bytes by I2C
 2. @param   
 3.     @arg deviceAddr:Address of device.
 4. 	@arg pBuffer:pointer to data buffer.
 5. 	@arg NumByteToWrite:number od data.
 6. @retval
  */
uint32_t Touch_I2C_WriteBytes(uint8_t deviceAddr,uint8_t* pBuffer,  uint8_t NumByteToWrite)
{
    uint16_t m;	
    Touch_I2C_Stop();
  
    for (m = 0; m < 1000; m++)
    {				
        /* step 1: start I2C */
        Touch_I2C_Start();
        
        /* step 2: send device address and w/r control. */
        Touch_I2C_SendByte(deviceAddr | Touch_I2C_WR);	/* ?????? */
        
        /* step 3: wait ack. */
        if (Touch_I2C_WaitAck() == 0)
        {
            break;
        }
    }
    if (m  == 1000)
    {
        Touch_I2C_Stop();
        return 1;
    }	
	
    while(NumByteToWrite--)
    {
        /* step 4:send data */
        Touch_I2C_SendByte(*pBuffer);
    
        /* step 5:wait ack. */
        if (Touch_I2C_WaitAck() != 0)
        {
            Touch_I2C_Stop();
            return 1;	
        }
        
        pBuffer++;	/* increment the pointer. */		
    }
	
	/* stop I2C */
	Touch_I2C_Stop();
	return 0;
}

2. 根据TP的IC命令读取相应的数据内容
根据TP的IC手册来读取信息;下图中(图3)命令0x40表示读取IC固件的版本信息,0x42表示读取固件协议的版本信息,一般用于通过读取Chip ID以及Major Protocol version来判断单片机与TP的IC通讯是否OK,若读取的信息与IC固件的烧录信息一致,表示通讯OK,可进行下一步的操作;
图3
读取TP的 IC固件分辨率(非常重要);当有触摸时,TP的IC会记录触摸位置的坐标,这个坐标是相对于TP的IC分辨率的,并不是相对于屏幕的,要与屏幕一一对应就要将固件的分辨率与屏的分辨率一一映射;下图(图4)为固件配置的基本信息;
图4
从0x20处读取的0-1个字节是X最大分辨率,2-3为Y的最大分辨率;第4-5个字节为TOUCH配置的X方向通道数(表格有误),第5-6个字节为TOUCH配置的Y方向的通道数(表格有误),第7个字节为TOUCH配置的最大支持的手指触摸的个数,等等…
当有触摸时,触摸点的坐标可从0X10处读取;如下图(图5)
图5
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 )
3.实际调试信息
基本信息读取
图6

坐标信息读取
图7
驱动完整代码连接
https://download.csdn.net/download/WQIANGEE/87722582

在使用ILI2132 I2C开发中,你需要了解该设备的命令集和数据结构。以下是基本步骤来读取版本信息和坐标点: 1. **版本号读取**: - 首先,你需要找到ILI2132设备的I2C地址。大多数此类显示器的默认地址是0x39或0x3A(取决于你是连接到SCL低还是高)。 - 发送命令序列,例如`0x5A`(寄存器地址,通常是`REG_STATUS`)来读取状态信息,然后发送`0x01`(读操作),再发送一个确认字节(比如0x00)。 - 接收两个字节作为响应,第一个字节是寄存器的内容,第二个字节是校验和。版本信息通常在`REG_VERSION`寄存器里,它的内容包含版本号。 ```c uint8_t i2c_address = 0x39; //假设地址为0x39 uint8_t data[2]; i2c_write(i2c_address, &REG_STATUS, 1); //写入REG_STATUS i2c_read(i2c_address, &data[0], 1); //读取第一字节 if (data[0] == REG_VERSION) { i2c_read(i2c_address, &data[1], 1); //读取版本号 } ``` 2. **坐标点读取**: - 写入命令以获取触摸坐标,这通常涉及向`REG_TOUCH_X`或`REG_TOUCH_Y`寄存器发送读取请求,并等待响应。 - 根据需要循环读取多个坐标点,每次读取后可能需要处理一次或多次,直到所有点都被读取完毕。 ```c i2c_write(i2c_address, &REG_TOUCH_X, 1); while (true) { // 循环读取直到没有更多数据 i2c_read(i2c_address, &data[0], 2); if (data[0] == END_OF_DATA) break; // 结束标志 process_touch_data(data[1], data[2]); // 处理坐标值 } ``` 请注意,这里的函数`i2c_write()`和`i2c_read()`是你需要自定义的I2C通信函数,它们会根据你的硬件平台(如PCA9685之类的I2C接口控制器)和实际驱动有所不同。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值