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)