最近几天研究了一下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);
}