I2C介绍及驱动程序

 

总线空闲状态 
  I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

 启动信号 
  在时钟线SCL保持高电平期间,数据线SDA上的电平被拉低(下降沿),定义为I2C总线总线的启动信号,它标志着一次数据传输的开始。启动信号是由主控器主动建立的,在建立该信号之前I2C总线必须处于空闲状态。

void I2C_Start()
{
    I2C_SDA = 1;
    I2C_Delay10us();
    I2C_SCL = 1;
    I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7us
    I2C_SDA = 0;
    I2C_Delay10us();//保持时间是>4us
    I2C_SCL = 0;            
    I2C_Delay10us();        
}

重启动信号 
  在主控器控制总线期间完成了一次数据通信(发送或接收)之后,如果想继续占用总线再进行一次数据通信(发送或接收),而又不释放总线,就需要利用重启动Sr信号时序。重启动信号Sr既作为前一次数据传输的结束,又作为后一次数据传输的开始。利用重启动信号的优点是,在前后两次通信之间主控器不需要释放总线,这样就不会丢失总线的控制权,即不让其他主器件节点抢占总线。

 

停止信号 
  在时钟线SCL保持高电平期间,数据线SDA被释放,使得SDA返回高电平(上升沿),称为I2C总线的停止信号,它标志着一次数据传输的终止。停止信号也是由主控器主动建立的,建立该信号之后,I2C总线将返回空闲状态。

 

 void I2C_Stop()
{
    I2C_SDA = 0;
    I2C_Delay10us();
    I2C_SCL = 1;
    I2C_Delay10us();//建立时间大于4.7us
    I2C_SDA = 1;
    I2C_Delay10us();        
}

 
数据位传送 
  在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。进行数据传送时,在SCL呈现高电平期间,SDA上的电平必须保持稳定,低电平为数据0,高电平为数据1。只有在SCL为低电平期间,才允许SDA上的电平改变状态。

 

 

uchar I2C_SendByte(uchar dat, uchar ack)
{
    uchar a = 0,b = 0;//最大255,一个机器周期为1us,最大延时255us。
            
    for(a=0; a<8; a++)//要发送8位,从最高位开始
    {
        I2C_SDA = dat >> 7;     //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
        dat = dat << 1;
        I2C_Delay10us();
        I2C_SCL = 1;
        I2C_Delay10us();//建立时间>4.7us
        I2C_SCL = 0;
        I2C_Delay10us();//时间大于4us        
    }

    I2C_SDA = 1;
    I2C_Delay10us();
    I2C_SCL = 1;
    while(I2C_SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低
    {
        b++;
        if(b > 200)     //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
        {
            I2C_SCL = 0;
            I2C_Delay10us();
            return 0;
        }
    }

    I2C_SCL = 0;
    I2C_Delay10us();
     return 1;        
}

uchar I2C_ReadByte()
{
    uchar a = 0,dat = 0;
    I2C_SDA = 1;            //起始和发送一个字节之后I2C_SCL都是0
    I2C_Delay10us();
    for(a=0; a<8; a++)//接收8个字节
    {
        I2C_SCL = 1;
        I2C_Delay10us();
        dat <<= 1;
        dat |= I2C_SDA;
        I2C_Delay10us();
        I2C_SCL = 0;
        I2C_Delay10us();
    }
    return dat;        
}
 

应答信号 
  I2C总线上的所有数据都是以8位字节传送的,发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。 对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值