• 硬件驱动篇 | 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动态显示读数变化。

     

     

     

     

  • 相关阅读:
    Cornfields POJ
    二维RMQ模板
    降雨量 HYSBZ
    Frequent values UVA
    UVA
    Argus UVALive
    关于二分图有向边和无向边问题探讨
    Guardian of Decency UVALive
    SAM I AM UVA
    【062新题】OCP 12c 062出现大量新题-15
  • 原文地址:https://www.cnblogs.com/Tuple-Joe/p/9534350.html
Copyright © 2020-2023  润新知