关于I2C总线的感悟

来源:互联网 发布:1.76我本沉默复古淘宝 编辑:程序博客网 时间:2024/04/29 02:16

最近几天研究了一下I2C总线,一开始感到非常困难,经过一番周折,终于搞定了。。。下面总结几点个人觉得需要注意的地方

1.主机 由 从机读取数据结束后应当发送非应答信号结束读取

2.每一次写入数据都需要进行一定的延时

3.读取数据的时候要先左移,在读取数据


接下来是具体的程序

a.延时5us函数,I2C有需要大于延时4.7us和4us的时间,这里均延时5us

void i2c_delay(unsigned char i)
{
    do
    {
        _nop_();
    }
    while(i--);        
}

b.启动I2C函数

void Start_I2C()//
{
SDA=1;
_nop_();
SCL=1;
i2c_delay(5);
SDA=0;
i2c_delay(5);
SCL=0;
_nop_();
_nop_();
}

c.结束I2C函数

void Stop_I2C()/
{  
 SDA=0;
 _nop_();
 SCL=1;
 i2c_delay(5);
 SDA=1;     
 i2c_delay(5);
}

d.读取(接收)字节函数

uchar RecByte_I2C(void)
{
uchar R_Data;
uchar i;
for(i=0;i<8;i++)
{
SCL=1;
i2c_delay(5);
R_Data<<=1;
if(SDA)
{
R_Data|=0x01;
}
SCL=0;
i2c_delay(5);
}
return R_Data;
}

SDA=1;
SCL=1;
_nop_();
_nop_();

e.发送字节函数

void SendByte_I2C(uchar S_Data)
{
uchar i;
for(i=0;i<8;i++)
{
SCL=0;//???????????
i2c_delay(5);
if(S_Data&0x80)
SDA=1;
else 
SDA=0;
SCL=1;
i2c_delay(5);
S_Data<<=1;
SCL=0;//这个非常重要,不能缺少
_nop_();
_nop_();
}
SDA=1;
SCL=1;

_nop_();//此处需要释放总线

_nop_();

}

f.等待应答函数

uchar WaitAck_I2C(void)//1应答 0非应答
{
uchar W_Ack;
SCL=1;
i2c_delay(5);
    W_Ack = ~SDA;
    SCL = 0;
    i2c_delay(5);
return W_Ack;
}

g.发送应答函数

void SendAck_I2C(uchar S_Ack)//1应答 0非应答
{
SCL=0;
i2c_delay(5);
if(S_Ack==1)SDA=0;              /*???????????? */
else SDA=1;
i2c_delay(5);      
SCL=1;
i2c_delay(5);
}

0 0
原创粉丝点击