硬件驱动篇 | STM8驱动 触摸控制芯片IQS263
I2C 与 Touch slide
最近做了一个与触摸滑条相关的测试,利用I2C通讯协议来配置触摸控制芯片的相关寄存器,读取触摸读数,并通过STM Studio动态显示触摸读数的变化过程。这个测试相对简单,只要搞定I2C通讯协议,后面的触摸控制芯片的相关寄存器配置就变得很简单了,所以我就简单地总结一下I2C通讯部分笔记。
实验平台:IAR 及 STM Studio
实验主芯片:自制STM8L051/101评估板
触摸控制芯片:ProxSense IQS263
使用硬件触摸滑条(Touch slide),如下图:
一、触摸控制芯片IQS263简介
IQS 263 ProxSense IC是一种3通道投影(或自)电容接近和触摸控制器,具有最佳的类灵敏度,信噪比和功耗。
- 硬件原理图
其中,通信线为RDY,SDA,SCL,都接有上拉电阻。RDY是通讯使能脚,当RDY为低电平时才支持I2C通信。
二、I2C软件模拟协议的实现:
- 自定义宏定义
#define I2C_PORT GPIOC #define I2C_SCL_PIN GPIO_Pin_1 #define I2C_SDA_PIN GPIO_Pin_0 #define SCL_H I2C_PORT->ODR |= I2C_SCL_PIN #define SCL_L I2C_PORT->ODR &= ~I2C_SCL_PIN #define SDA_H I2C_PORT->ODR |= I2C_SDA_PIN #define SDA_L I2C_PORT->ODR &= ~I2C_SDA_PIN
- 起始信号和停止信号
起始信号:当 SCL 线是高电平时 SDA 线从高电平向低电平切换
软件模拟协议实现如下:
1 /************************************** 2 起始信号 3 **************************************/ 4 void Touch_Sen_Start() 5 { 6 SDA_H; //拉高数据线 7 SCL_H; //拉高时钟线 8 I2C_DELAY; //延时 9 SDA_L; //产生下降沿 10 I2C_DELAY; //延时 11 SCL_L; //拉低时钟线 12 }
停止信号: 当 SCL 是高电平时 SDA 线由低电平向高电平切换
软件模拟协议实现如下:
1 /************************************** 2 停止信号 3 **************************************/ 4 void Touch_Sen_Stop() 5 { 6 SDA_L; //拉低数据线 7 SCL_H; //拉高时钟线 8 I2C_DELAY; //延时 9 SDA_H; //产生上升沿 10 I2C_DELAY; //延时 11 }
注:I2C的延迟函数一般设置为5us以上
- 应答和非应答
传输时主机产生时钟,在第9个时钟时,数据发送端会释放SDA的控制权,由数据接收端控制SDA,若SDA为高电平,表示非应答信号(NACK),低电平表示应答信号(ACK)
应答信号(ACK):SDA为低电平
非应答信号(NACK):SDA为高电平
软件模拟协议实现如下:
1 /************************************** 2 发送应答信号 3 入口参数:ack (0:ACK 1:NAK) 4 **************************************/ 5 void Touch_Sen_SendACK(u8 ack) 6 { 7 8 9 if (ack)//写应答信号 10 { 11 SDA_H; 12 } 13 else 14 { 15 SDA_L; 16 } 17 18 19 SCL_H; //拉高时钟线 20 I2C_DELAY; //延时 21 SCL_L; //拉低时钟线 22 I2C_DELAY; //延时 23 } 24 25 /************************************** 26 接收应答信号 27 **************************************/ 28 u8 Touch_Sen_RecvACK() 29 { 30 I2C_PORT->DDR &= ~I2C_SDA_PIN; //Set as input mode 31 SCL_H; //拉高时钟线 32 I2C_DELAY; //延时 33 34 if(I2C_PORT->IDR & I2C_SDA_PIN) 35 { 36 ack = 1; //读应答信号 37 } 38 else 39 { 40 ack = 0; //读应答信号 41 } 42 43 I2C_PORT->DDR |= I2C_SDA_PIN; //Set as output mode 44 45 46 SCL_L; //拉低时钟线 47 I2C_DELAY; //延时 48 49 return ack; 50 }
- I2C读写
1 /************************************** 2 向I2C总线发送一个字节数据 3 **************************************/ 4 void Touch_Sen_SendByte(u8 dat) 5 { 6 u8 i; 7 8 for (i=0; i<8; i++) //8位计数器 9 { 10 if (dat & 0x80) 11 { 12 SDA_H; 13 } 14 else 15 { 16 SDA_L; 17 } 18 19 dat <<= 1; //移出数据的最高位 20 I2C_DELAY; //延时 21 22 SCL_H; //拉高时钟线 23 I2C_DELAY; //延时 24 SCL_L; //拉低时钟线 25 I2C_DELAY; //延时 26 } 27 Touch_Sen_RecvACK(); 28 } 29 30 /************************************** 31 从I2C总线接收一个字节数据 32 **************************************/ 33 u8 Touch_Sen_RecvByte() 34 { 35 u8 i; 36 u8 dat = 0; 37 38 SDA_H; //使能内部上拉,准备读取数据, 39 I2C_PORT->DDR &= ~I2C_SDA_PIN; //Set as input mode 40 41 for (i=0; i<8; i++) //8位计数器 42 { 43 dat <<= 1; 44 SCL_H; //拉高时钟线 45 I2C_DELAY; //延时 46 if (I2C_PORT->IDR & I2C_SDA_PIN)//读数据 47 { 48 dat |=1; 49 } //esle curret bit is 0 50 51 SCL_L; //拉低时钟线 52 I2C_DELAY; //延时 53 } 54 55 I2C_PORT->DDR |= I2C_SDA_PIN; //Set as output mode 56 return dat; 57 }
1 //******单字节写入******************************************* 2 3 void Single_Write_Touch_Sen(u8 REG_Address,u8 REG_data) 4 { 5 Touch_Sen_Start(); //起始信号 6 Touch_Sen_SendByte(I2C_SLAVE_ADDR_WR); //发送设备地址+写信号 7 Touch_Sen_SendByte(REG_Address); //内部寄存器地址 8 Touch_Sen_SendByte(REG_data); //内部寄存器数据 9 Touch_Sen_Stop(); //发送停止信号 10 } 11 12 //********单字节读取***************************************** 13 14 u8 Single_Read_Touch_Sen(u8 REG_Address) 15 { 16 u8 REG_data; 17 18 Touch_Sen_Start(); //起始信号 19 Touch_Sen_SendByte(I2C_SLAVE_ADDR_WR); //发送设备地址+写信号 20 Touch_Sen_SendByte(REG_Address); //发送存储单元地址,从0开始 21 Touch_Sen_Start(); //起始信号 22 Touch_Sen_SendByte(I2C_SLAVE_ADDR_RD); //发送设备地址+读信号 23 REG_data=Touch_Sen_RecvByte(); //读出寄存器数据 24 Touch_Sen_SendACK(1); 25 Touch_Sen_Stop(); //停止信号 26 27 return REG_data; 28 }
三、Touch Slide测试及结果
注:IQS263芯片的一个地址对应好几个字节的寄存器,对IQS263 IC进行I2C读写时,需要进行多字节读写,I2C的多字节读写可参考上面的单字节读写部分代码。
滑动Touch Slide,STM Studio动态显示读数变化。