I2C协议

I2C协议解析

基本概述

I2C是一种串行总线,使用主从架构。

  • 只需要SCL(串行时钟线)和SDA(串行数据线)两条总线,两条线都需要上拉电阻
  • 所有组件之间都存在简单的主从关系,连接到总线的每个设备均可以通过唯一地址进行软件寻址
  • 最大设备数无限制,最大从机数理论上是127(7位地址数据)

传输协议

在这里插入图片描述
开始信号、7个地址位、1个读写位、1个应答位、8个数据位、1个应答位、结束信号
开始条件和停止条件
在这里插入图片描述

  • 开始条件:SCL为高时,拉低SDA
  • 停止条件:SCL为高时,拉高SDA
    当主设备发送开始条件信号之后,所有从机设备即使处于睡眠模式,也会变为活动状态,并等待接收地址位
    数据传输
    在这里插入图片描述
    在这里插入图片描述

传输格式

  • 传输的数据总共有8位,由发送方设置,先发送数据的高地址,发送完8位数据后,接收方在第9个时钟会紧跟一个ACK位,成功接收为0,否则保持为1。以此往复,直到数据完全传输为止。
  • 谁发送数据谁就驱动SDA线,由于上拉电阻的存在,默认是高电平,谁驱动谁就拉低SDA的电平
  • 发送数据时,SDA的电平在SCL的低电平处变化,在高电平时接接收方读取数据
  • ACK为高时,会引起主设备发生重启或者停止

软件模拟I2C协议

Bool Panel_i2c_Start( void )
{
    Set_Panel_I2C_SDA();
    Set_Panel_I2C_SCL();
    Panel_i2c_Delay();
    if( Panel_I2C_SDALo() || Panel_I2C_SCLLo() )
        return FALSE;
    Clr_Panel_I2C_SDA();
    Panel_i2c_Delay();
    Clr_Panel_I2C_SCL();
    Panel_i2c_Delay();
    return TRUE;
}

Bool Panel_i2c_SendByte( BYTE value )
{
    BYTE i;
    Bool result;

    for( i = 0; i < 8; i++ ) // Send data via i2c pin
    {
        if( value & BIT7 )
         Set_Panel_I2C_SDA();
        else
         Clr_Panel_I2C_SDA();
        Panel_i2c_Delay();
        Set_Panel_I2C_SCL();
        Panel_i2c_Delay();
        value <<= 1;
        Clr_Panel_I2C_SCL();
    }
    Set_Panel_I2C_SDA();
    Panel_i2c_Delay();
    result = Panel_Wait_i2C_Ack();
    Set_Panel_I2C_SCL();
    Panel_i2c_Delay();
    Clr_Panel_I2C_SCL();
    Panel_i2c_Delay();
    Clr_Panel_I2C_SDA();

    return result;
}

Bool Panel_Wait_i2C_Ack( void )
{
    BYTE i;
    for( i = 0; i < 5; i++ )
    {
        if( Panel_I2C_SDALo() )
            return TRUE;
        Panel_i2c_Delay();
    }

    if( Panel_I2C_SDALo() )
        return TRUE;
    else
        return FALSE;
}

void Panel_i2c_Stop( void )
{
    // SCL=L, SDA=L, Stop condition.
    Clr_Panel_I2C_SCL();
    Clr_Panel_I2C_SDA();
    Panel_i2c_Delay();
    Set_Panel_I2C_SCL();
    Panel_i2c_Delay();
    Set_Panel_I2C_SDA();
    Panel_i2c_Delay();
}
Bool Panel_i2c_AccessStart(BYTE SlaveAdr, Panel_I2cIoTransType trans_t)
{
    BYTE Dummy; // loop dummy

    if (trans_t == PANEL_I2C_TRANS_READ) // check i2c read or write
        SlaveAdr = PANEL_I2C_DEVICE_ADR_READ(SlaveAdr); // read
    else
        SlaveAdr = PANEL_I2C_DEVICE_ADR_WRITE(SlaveAdr); // write

    Dummy = PANEL_I2C_ACCESS_DUMMY_TIME;
    while (Dummy--)
    {
        if (Panel_i2c_Start() == FALSE)
        {
            Panel_i2c_Stop();
            continue;
        }

        if (Panel_i2c_SendByte(SlaveAdr) == TRUE) // check acknowledge
            return TRUE;

        Panel_i2c_Stop();

        ForceDelayNVRAM(1);
    }

    return FALSE;
}

void i2cBurstWriteBytes(BYTE SlaveAdr, BYTE *pBuf, BYTE bufLen)
{
    BYTE Dummy; // loop dummy
    Dummy = I2C_ACCESS_DUMMY_TIME;
    whlie(Dummy--)
    {
        if(Panel_i2c_AccessStart(SlaveAdr, PANEL_I2C_TRANS_WRITE) == FALS)
            continue;
        whlie(buflen--)
        {
            Panel_i2c_SendByte(*pBuf); // send byte
            pBuf++; // next byte pointer
        }
        break;
    }
    Panel_i2c_Stop();
}

时钟同步和仲裁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值