iic通信原理_电子知识之IIC通信原理和协议分享

IIC 的一些特征:

两条总线:串行数据总线(SDA)和串行时钟总线(SCL)
真正的多主机总线
连接到相同总线的ic数量只受到总线的最大电容400pF限制。
串行8位双向数据在标准模式下可达100K bit/s
快速模式400K bit/s,高速模式下3.4Mbit/s.数据有效性规定:
IIC总线在进行数据传输时,SCL在高电平区间,SDA上的电平必须保持稳定
SDA的数据的高或者低电平状态只有在SCL线的时钟信号是低电平时才能改变。起始和停止条件:
起始:SCL高电平时,SDA由高电平向低电平切换。
停止:SCL高电平时,SDA由低电平向高电平切换。模拟时序如下:
起始与终止:

ebdae46a0b689b58ed4329fc769441b8.png


应答与非应答:

b8b50fb35c82c5ffbdb568ff291f17df.png


总线上进行一次数据传输的通信格式:

3060d0bf5c7ecc68bf0b4689dae30ca2.png


相关模拟时序的驱动函数:包括(start,stop,respons,write_byte,read_byte)
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
//SCL高电平区间,SDA一个下降沿启动信号
void Start()
{
SDA=1;
delay();
SCL=1;
delay();
SDA=0;
delay();
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
//SCL在高电平区间,SDA一个上升沿停止信号
void Stop()
{
SDA=0;
delay();
SCL=1;
delay();
SDA=1;
delay();
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
//SCL在高电平区间,SDA被从设备拉低表示应答,
//(SDA==1)&&(i<255)表示如果一段时间未收到从期间
//的应答则默认从期间已经收到而不再等待应答信号
void Respons()
{
uchari=0;
SCL=1;
delay();
while((SDA==1)&&(i<255))
i++;
SCL=0;
delay();
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
//CY 为PSW寄存器中的CY位
//先移位,然互使用SCL控制发出去
void Write_Byte(uchar date)
{
uchari,temp;
temp=tada;
for(i=0;i<8;i++)
{
temp=temp<<1;
SCL=0;
delay();
SDA=CY;
delay();
SCL=1;
delay();
}
SCL=0;
delay();
SDA=1;
delay();
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
//定义临时变量K,K左移一位后与SDA进行或运算,
//依次把8个独立地位放入一个字节中来接受完成
void Read_Byte()
{
uchari,k;
SCL=0;
delay();
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;
delay();
k=(k<<1)|SDA;
SCL=0;
delay();
}
delay();
returnk;
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
底层驱动完成以后,我们需要对实际的芯片使用通讯协议来进行操作。
目前大多的情况下一般比较受欢迎的是AT24cxx 系列。
AT24Cxx系列主要有: 以下系列:

15f81a7008cb3dac46fc32b095e4e99c.png

以下仅以AT24C02为例来进行说明:
AT24C02芯片地址为:1010,其控制字格式如下:

8ea0fb3a1e5d00a8d7f9ac249bcd1f09.png


其中A2,A1,A0为可编程选择地址,此处A2,A1,A0均接地,即000,
因此发送写信号的寻址字节为:10100000,即0XA0,
因此发送读信号的寻址字节为:10100001,即0XA1,


下图为写一个字节的数据格式,有图可知道:向AT24C02中写入一个字节的时候,需要:
先发一个起始信号,再发一个字节的控制字,
在发送一个字节的控制字地址,都得到应答信号后,
再发送要存入的数据,最后发一个停止信号!
So,一个字节的数据已经写入AT24C02中,OK!下面是数据格式,如图:

5505b2d8860cf9c9ff4a57c7115ccf6a.png


程序如下:
-----------------------------------------------------------------------------------------------------------------------
//任意地址,写入数据
void Write_Add(uchar address,uchar date)
{
Start();
Write_Byte(0xA0);
Respons();
Write_Byte(address);
Respons();
Write_Byte(date);
Respons();
Stop
}
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
下图为读一个字节的数据格式,其读取一个字节的数据和写入时候差不多,此处不再累赘,读一字节数据格式如图:

32cbd2f098b1da14ac3659fe029eebfb.png

程序如下:
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
//任意地址,读出数据
void Read_Add(uchar address)
{
uchardate;
Start();
Write_Byte(0XA0);
Respons();
Write_Byte(address);
Respons();
Start();
Write_Byte(0XA1);
Respons();
date=Read_Byte();
Stop();
returnbyte;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值