IIC通讯

几个原则:
IIC通信,高位在先,低位在后

开始信号
在时钟信号线为为高时,拉低SDA
IIC通讯_第1张图片

结束信号
在时钟信号线为为高时,拉高SDA
IIC通讯_第2张图片

Ack信号
ACK信号为每次传输8bit(1字节)数据后,必须要有的响应信号,由接收方来发出
在SCK为高时(一个脉冲内),将SDA拉低(管脚开漏输出只能拉低,来表示回复)

NACK信号
在SCK为高时(一个脉冲内),将SDA置高(管脚开漏输出只能拉低,不操作时默认为高电平)

写数据
设备地址:设备地址为7位,发送的数据中一共八位,前七位是设备地址,最后一位是读写控制位,0是写,1是读
IIC通讯_第3张图片

从设备写取数据的过程如下:

  1. 发送起始信号
  2. 输出从机的地址(写位),获取从机的应答信号,没有应答则发送STOP信号,释放总线
  3. 先发送要写入的寄存器高八位的地址,获取从机的应答信号,同上
  4. 再发送要写入的寄存器低八位的地址,获取应答信号
  5. 接下来发送要写入的数据,字节数任意
  6. 不想发的时候,发送STOP信号,结束通信
    IIC通讯_第4张图片
    IIC通讯_第5张图片

读数据

  1. 发送开始信号
  2. 发送设备地址(写命令),并获取设备的应答信号
  3. 发送设备的高八位地址,等待应答信号
  4. 发送设备的低八位地址,等待应答信号
  5. 发送停止信号
  6. 重新发送开始信号(重启通信)
  7. 发送设备地址(读命令),等待设备应答信号
  8. 读取数据,读到数据后主机回复ACK信号
  9. 若主机不想接收数据了,给设备回复NACK 或者 发送停止信号
    IIC通讯_第6张图片

底层驱动函数有:

  1. IIC_Start
  2. IIC_Stop
  3. IIC_SendAck
  4. IIC_SendNack
  5. IIC_ReadAck:读取不到ACK信号时,要发送IIC_Stop
  6. IIC_WriteByte
  7. IIC_ReadByte

接收Ack

void delay(unsigned int t)
{//延时函数
    while(t){t--;};                    //延时循环计数
}
//-------------------------------------------------------------------
void delay_IIC(void)    
{//IIC总线限速延时函数。
//该函数是空函数,延时4个机器周期。
;;
}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC总线初始化函数
    IIC_SDA=1;//释放IIC总线的数据线。
    IIC_SCL=1;//释放IIC总线的时钟线。
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC总线产生起始信号函数  
    IIC_SDA=1;//拉高数据线
     IIC_SCL=1;//拉高时钟线
     delay_IIC();
     IIC_SDA=0;//在时钟线为高电平时,拉低数据线,产生起始信号。
     delay_IIC();
    IIC_SCL=0;//拉低时钟线
}
//-------------------------------------------------------------------
void IIC_stop(void) 
{//IIC总线产生停止信号函数
    IIC_SDA=0;//拉低数据线
    delay_IIC();
    IIC_SCL=1;//拉高时钟线。
    delay_IIC();
    IIC_SDA=1;//时钟时线为高电平时,拉高数据线,产生停止信号。
    delay_IIC();
}
//-------------------------------------------------------------------
bit IIC_Tack(void)
{//接收应答信号函数
    bit ack;//定义一个位变量,来暂存应答状态。
    IIC_SDA=1;//释放数据总线,准备接收应答信号。
    delay_IIC();
    IIC_SCL=1;//拉高时钟线。
    delay_IIC();
    ack=IIC_SDA;//读取应答信号的状态。
    delay_IIC();
    IIC_SCL=0;//拉低时钟线。
    delay_IIC();
    return ack;//返回应答信号的状态,0表示应答,1表示非应答。
}
//-------------------------------------------------------------------
void IIC_write_byte(unsigned char Data)
{//向IIC总线写入一个字节的数据函数 
    unsigned char i;
     for(i=0;i<8;i++)//有8位数据
    {
        IIC_SDA=Data&0x80;//写最高位的数据
          delay_IIC();
          IIC_SCL=1; //拉高时钟线,将数写入到设备中。
        delay_IIC();
        IIC_SCL=0;//拉低时钟线,允许改变数据线的状态
        delay_IIC();
        Data=Data<<1;//数据左移一位,把次高位放在最高位,为写入次高位做准备
    }
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte()
{//从IIC总线读取一个字节的数据函数
    unsigned char i;
    unsigned char Data;       //定义一个缓冲寄存器。
    for(i=0;i<8;i++)//有8位数据
    {
        IIC_SCL=1;//拉高时钟线,为读取下一位数据做准备。
        delay_IIC();
        Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
        delay_IIC();
        
        if(IIC_SDA)//如果数据线为高平电平。
            Data=Data|0x1;//则给缓冲字节的最低位写1。
        IIC_SCL=0;//拉低时钟线,为读取下一位数据做准备。
        delay_IIC();
    }
    return Data;//返回读取的一个字节数据。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(unsigned char Daddr,unsigned char Waddr,unsigned char Data)
{//向任意地址写入一个字节数据函数
    IIC_start();//产生起始信号
    IIC_write_byte(Daddr);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    IIC_write_byte(Data);//写入数据。
    IIC_Tack();//等待设备的应答。
    IIC_stop();//产生停止符号。
}
//-------------------------------------------------------------------
unsigned char IIC_single_byte_read(unsigned char Daddr,unsigned char Waddr)
{//从任意地址读取一个字节数据函数
    unsigned char Data;//定义一个缓冲寄存器。

    IIC_start();//产生起始信号
    IIC_write_byte(Daddr);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    
    IIC_start();//产生起始信号
    IIC_write_byte(Daddr+1);//写入设备地址(读)。
    IIC_Tack();//等待设备的应答。 
    Data=IIC_read_byte();//写入数据。
    IIC_stop();//产生停止符号。
    //-------------------返回读取的数据--------------------
    return Data;//返回读取的一个字节数据。
}

读取触摸坐标分为 中断方式 和 轮询方式
1. 中断方式
TP的INT引脚接在芯片的中断引脚上,触摸后,TP的INT引脚会输出高电平,触发芯片的中断,芯片进入中断服务函数ISR,ISR中读取TP指定寄存器的数据,将数据存在栈存储结构中,中断外再处理数据

2. 轮询方式
不使用TP的INT引脚,使用空闲任务读取TP的坐标等信息,可以在程序中处理数据

IIC最多支持多少个设备地址?
127个,八位中的最后一位是读写位,读1,写0

上拉电阻的阻值
4.7K,10K

一般TP初始化过程

  1. 通过RESET引脚硬件复位
  2. 延时一段时间
  3. 结束复位
  4. 通过INT引脚的电平设置设备地址
  5. 延时
  6. 软复位
  7. 若需要则要更新配置(分辨率等)
  8. 结束软复位

某些TP读寄存器坐标之后,要对其寄存器清零

你可能感兴趣的:(硬件电路)