Chinaunix首页 | 论坛 | 博客
  • 博客访问: 225649
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 781
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-08 10:41
个人简介

爱莉清

文章分类

全部博文(80)

文章存档

2018年(1)

2017年(18)

2016年(49)

2015年(7)

2014年(5)

我的朋友

分类: 嵌入式

2016-08-01 15:11:33

IIC总线
一般串行数据通讯都有时钟和数据之分,有异步和同步之别.
有单线,双线和三线等
.

I2C
肯定是2线的(不算地线
).

I2C
协议确实很科学,3/4线的SPI要好,当然线多通讯速率相对就快了
.

I2C
的原则是
:

SCL=1(高电平),SDA千万别忽悠
!!!

否则,SDA下跳则"判罚""起始信号S",SDA上跳则"判罚""停止信号
P".

SCL=0(低电平),SDA随便忽悠!!!(可别忽悠过火到SCL跳高
)

每个字节后应该由对方回送一个应答信号ACK做为对方在线的标志
.

非应答信号一般在所有字节的最后一个字节后.一般要由双方协议签定
.

SCL
必须由主机发送,否则天下大乱
.

首字节是"片选信号",7位从机地址加1位方向(读写)控制
.

从机收到(听到)自己的地址才能发送应答信号(必须应答!!!)表示自己在线
.

其他地址的从机不允许忽悠!!!(当然群呼可以忽悠但只能听不许说话
)

读写是站在主机的立场上定义的
.

"
"是主机接收从机数据,""是主机发送数据给从机
.

重复位主要用于主机从发送模式到接收模式的转换"信号",由于只有2线
,

所以收发转换肯定要比SPI复杂,因为SPI可用不同的边沿来收发数据,I2C不行
.

在硬件I2C模块,特别是MCU/ARM/DSP等每个阶段都会得到一个准确的状态码
,

根据这个状态码可以很容易知道现在在什么状态和什么出错信息
.

7
I2C总线可以挂接127个不同地址的I2C设备,0"设备"作为群呼地址
.

10
I2C总线可以挂接更多的10I2C设备
.

总之,只要掌握I2C的忽悠记,一般很容易掌控...  第一个字节(slave address)7位地址和一位R/W读写位组成的,这字节是个器件地址。

首先,你要知道:常用IIC接口通用器件的器件地址是由种类型号,及寻址码组成的,共7位。
如格式如下: 
  D7 D6 D5 D4 D3 D2 D1 D0
1-
器件类型由:D7-D4 4位决定的。这是由半导公司生产时就已固定此类型的了,也就是说这4位已是固定的。


2-
用户自定义地址码:D3-D13位。这是由用户自己设置的,通常的作法如EEPROM这些器件是由外部IC3个引脚所组合电平决定的(用常用的名字如A0,A1,A2)。这也就是寻址码。
所以为什么同一IIC总线上同一型号的IC只能最多共挂8片同种类芯片的原因了。

3-
最低一位就是R/W位。这位不用我多说了。
   
在现代电子系统中,有为数众多的IC需要进行相互之间以及与外界的通信。为了提供硬件的效率和简化电路的设计,PHILIPS开发了一种用于内部IC控制的简单的双向两线串行总线I2CI2C总线支持任何一种IC制造工艺,并且PHILIPS和其他厂商提供了种类非常丰富的I2C兼容芯片。作为一个专利的控制总线,I2C已经成为世界性的工业标准。

 I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。

 


图片一


               

起始和终止信号 SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。

数据传送格式

1)字节传送与应答

每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。如果一段时间内没有收到从机的应答信号,则自动认为从机已正确接收到数据。



     AT24C02的芯片地址如下图,1010为固定,A0A1A2正好与芯片的123引角对应,为当前电路中的地址选择线,三根线可选择8个芯片同时连接在电路中,当要与哪个芯片通信时传送相应的地址即可与该芯片建立连接,TX-1B实验板上三根地址线都为0。最后一位R/W为告诉从机下一字节数据是要读还是写,0为写入,1为读出。


 


 


 


 

 

任一地址读取数据格式


点击(此处)折叠或打开

  1. void init() //初始化
  2. {
  3.        SCL=1;
  4.        delay();
  5.        SDA=1;
  6.        delay();
  7. }
  8. void start() //启动信号
  9. {
  10.        SDA=1;
  11.        delay();
  12.        SCL=1;
  13.        delay();
  14.        SDA=0;
  15.        delay();
  16. }
  17. void stop() //停止信号
  18. {
  19.        SDA=0;
  20.        delay();
  21.        SCL=1;
  22.        delay();
  23.        SDA=1;
  24.        delay();
  25. }
  26.  
  27. void respons() //回应信号
  28. {
  29.        uchar i=0;SCL=1;delay();
  30. while((SDA==1)&&(i<255))
  31. i++;
  32.        SCL=0;
  33. delay();
  34. }
  35. void writebyte(uchar date)// 写一个字节
  36. {
  37.        uchar i,temp;
  38.        temp=date;
  39.        for(i=0;i<8;i++)
  40.        {
  41.               temp=temp<<1;
  42.               SCL=0;
  43.               delay();
  44.               SDA=CY;
  45.               delay();
  46.               SCL=1;
  47.               delay();
  48.        }
  49.        SCL=0;
  50.        delay();
  51.        SDA=1;
  52.        delay();
  53. }

任一地址写入数据格式


点击(此处)折叠或打开

  1. uchar readbyte()
  2. //读一个字节
  3. {
  4.        uchar i,j,k;
  5.        SCL=0;
  6.        delay();
  7.        SDA=1;
  8.        for(i=0;i<8;i++)
  9.        {
  10.               SCL=1;
  11.               delay();
  12.               if(SDA==1)
  13.                 j=1;
  14.               else
  15.                 j=0;
  16.               k=(k<<1)|j;
  17.               SCL=0;
  18.               delay();
  19.        }
  20.        delay();
  21.        return k;
  22. }
  23. Void write_add(uchar address,
  24. uchar info)
  25. //指定地址写一个字节数据
  26. {
  27.        start();
  28.        writebyte(0xa0);
  29.        respons();
  30.        writebyte(address);
  31.        respons();
  32.        writebyte(info);
  33.        respons();
  34.        stop();
  35. }
  36. uchar read_add(uchar address)
  37. //指定地址读一个字节数据
  38. {
  39.        uchar dd;
  40.        start();
  41.        writebyte(0xa0);
  42.        respons();
  43.        writebyte(address);
  44.        respons();
  45.        start();
  46.        writebyte(0xa1);
  47.        respons();
  48.        dd=readbyte();
  49.        stop();
  50.        return dd;
  51. }

阅读(1415) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~