IIC是两根线,单总线,只有一根数据线,发送数据和读取收据都是一根线,像我们之前学的AD、DA都是许多线,许多线的话,这样做系统可以少浪费资源,少浪费控制IO口的资源,这种并行的处理速度快。所以线越多,速度越快。

我们用的较多的是SIP和IIC,单总线用得少,一般就BS18B20用。

这两条线可以接很多I²C设备,凡是具有I²C通信功能的设备都可以接在这总线上。要和哪个设备通信,先发送一个地址码给总线,总线全会响应这个地址码,这条总线上所有I²C芯片会检测这个地址,哪一个地址和它相符,就和主机建立通信,建立起后只有这个唯一的设备和总线通信。

I²C比较重要,不过也比较简单,实际上就是时序图。

凡是I²C总线设备必须接上拉电阻,Rp阻值一般为10K

先传送最高位记住。

随便两条线都可以模仿I²C总线


 

接下来说E²PROM(electronic erase program read only memory)电可擦除可编程只读存储器

其实就是Flash,例如U盘插上去,数据写完后拔走,就存在里面了。

这里第二条最高位错了,最高位不是不变,是补0.

这里用的其实是24C02

 A0~A2就是三位地址线,WP(write protect)写保护,U盘就有这功能,为1时不能写,不知道能不能读。

接下来看看datasheet

低电压和标准电压都支持,这里使用的是2.7~5.5V。

内部构造2K~16K。

两线接口。

施密特触发器、滤波用来抑制噪声。

双向数据传输协议。

电压越高传输速率越快(电压越高运行速度越快,越快功耗越高),1.8V->100kHz,5V->400kHz

2K一页,4K+是多页,C02一页的不用管。

最多可读写1Million次

数据保存时间100年。

NC是不连接的意思。

这里有四种封装

总线时序图

写:

数据有效性:

起始信号和停止信号:

应答信号:

地址:

写:

页写(不管)

当前地址读取(即已经知道了读取的地址):

随机读取:

顺序读取:


 现在写程序:

有起始信号,停止信号,应答信号,写一个字节,读一个字节,从任意字节读,向任意字节写,我们把这些都写成带参数的函数(例如write(地址变量,数据变量)),主函数直接调用就可以了,这就可以当成是一个I²C的模板。

 

  1 #include<reg51.h>
  2 
  3 #define uchar unsigned char
  4 #define uint unsigned int
  5 
  6 sbit SDA=P2^0;
  7 sbit SCL=P2^1;
  8 
  9 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
 10 //                    0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   无显示
 11 
 12 void Delay1ms();
 13 void delay1(int n);
 14 void delay();
 15 void start();
 16 void stop();
 17 void responds();
 18 void init();
 19 void write_byte(uchar date);
 20 uchar read_byte();
 21 
 22 void main()
 23 {
 24     init();
 25     start();
 26     write_byte(0xa0);
 27     responds();
 28     write_byte(0);
 29     responds();
 30     write_byte(0xfe);
 31     responds();
 32     stop();
 33     
 34     delay1(1000);//这里要有延时,停止后不能直接启动
 35     
 36     start();
 37     write_byte(0xa0);
 38     responds();
 39     write_byte(0);
 40     responds();
 41     start();
 42     write_byte(0xa1);
 43     responds();
 44     P1=read_byte();
 45     stop();
 46     while(1);
 47 }
 48 void write_byte(uchar date)
 49 {
 50     //写一个字节
 51     uchar i=0,temp;
 52     temp=date;
 53     SCL=0;
 54     delay();
 55     for(i=0;i<8;i++)
 56     {
 57         temp=temp<<1;
 58         SDA=CY;
 59         delay();
 60         SCL=1;
 61         delay();
 62         SCL=0;
 63         delay();
 64     }
 65     SDA=1;
 66     delay();
 67 }
 68 uchar read_byte()
 69 {
 70     //读一个字节
 71     uchar i,j,k;
 72     SCL=0;
 73     delay();
 74     SDA=1;
 75     delay();
 76     for(i=0;i<8;i++)
 77     {
 78         SCL=1;
 79         delay();
 80         j=SDA;
 81         k=(k<<1)|j;
 82         SCL=0;
 83         delay();
 84     }
 85     return k;
 86 }
 87 void init()
 88 {
 89     SDA=1;
 90     SCL=1;
 91 }
 92 void start()
 93 {
 94     //起始信号
 95     SDA=1;
 96     delay();
 97     SCL=1;
 98     delay();
 99     SDA=0;
100     delay();
101     
102 }
103 void stop()
104 {
105     //停止信号
106     SDA=0;
107     delay();
108     SCL=1;
109     delay();
110     SDA=1;
111     delay();
112 }
113 void responds()
114 {
115     //应答信号
116     uchar i=0;
117     SCL=1;
118     delay();
119     while((SDA==1)&&(i<250))
120     {
121         i++;
122     }
123     SCL=0;
124     delay();
125 }
126 void delay()
127 {
128     
129 }
130 void delay1(int n)
131 {
132     while(n--)
133     {
134         Delay1ms();
135     }
136 }
137 void Delay1ms()        //@12.000MHz
138 {
139     unsigned char i, j;
140 
141     i = 2;
142     j = 239;
143     do
144     {
145         while (--j);
146     } while (--i);
147 }

 

1.写入时间是在你传入EEPROM数据后才开始进行的,传送数据过程中,不能算写入时间,EEPROM在IIC在停止位后才开始写入动作,从这一刻开始至6MS之间算为写入时间;

(资料来源https://www.baidu.com/link?url=GmfN6JMOsWVFgIB6hDzhhJcKdWzwvsnfOB6IC8skYfUoabglVRyz1gaWIKND0Xha&wd=&eqid=f1e2a27a000817f9000000025cb9d508