IIC,AT24C02

IIC总线工作原理

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

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

数据传送格式(1)字节传送与应答

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

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

任意地址写入数据格式 任意地址读取数据格式

  1 #include <reg52.h>
  2 #include <intrins.h>
  3 
  4 #define uint8 unsigned char
  5 #define uint16 unsigned int
  6 
  7 #define NOP() _nop_()
  8 
  9 #define DELAY5US() do{NOP();NOP();NOP();NOP();}while(0)
 10 struct Addr
 11 {
 12     uint8 devAddr;
 13     uint8 wordAddr;
 14 };
 15 
 16 struct Buff
 17 {
 18     uint8 *buff;
 19     uint8 length;
 20 };
 21 uint8 idata sendBuf[8] = {1,2,3,4,5,6,7,8};
 22 uint8 idata recvBuf[8];
 23 
 24 sbit SDA = P2^0;
 25 sbit SCL = P2^1;
 26 
 27 void start();
 28 void stop();
 29 void ACK();
 30 void NACK();
 31 void checkACK();
 32 /**************c51通用寄存器 只有两个,a、b因此函数中参数的个数最多2个***********/
 33 void writeByte(uint8 dat);
 34 void writeSlot(uint8 *addr, uint8 dat);//addr 指向一个数组,这个数组中包含设备地址,与数据地址
 35 void writeSlot1(struct Addr address, struct Buff sendBuff);
 36 void writeSeq(struct Addr address, struct Buff buff);
 37 
 38 uint8 readByte();
 39 uint8 readSlot(uint8 *addr);
 40 void readSeq(struct Addr address, struct Buff buff);
 41 void delay()
 42 {
 43     uint8 i, j;
 44     for(i = 0; i<100;i++)
 45         for(j = 0; j<100; j++);
 46 }
 47 
 48 
 49 void main()
 50 {
 51     uint8 addr[] = {0xa0, 2};
 52     struct Addr sendAddr;
 53     struct Addr recvAddr;
 54 
 55     struct Buff sendBuff;
 56     struct Buff recvBuff;
 57     
 58     sendAddr.devAddr = 0xa0;
 59     sendAddr.wordAddr = 0x00;
 60     
 61     recvAddr.devAddr = 0xa0;
 62     recvAddr.wordAddr = 0x00;
 63 
 64     sendBuff.buff = sendBuf;
 65     sendBuff.length = 8;
 66     
 67     recvBuff.buff = recvBuf;
 68     recvBuff.length = 8;
 69      
 70 //    writeSlot1(sendAddr, sendBuff);
 71 //    writeSlot(addr, 0x01);
 72     writeSeq(sendAddr, sendBuff);
 73 
 74     delay(); //在读和写之间 需要一个短暂的停顿
 75 
 76     readSeq(recvAddr, recvBuff);
 77     P1 = recvBuf[3];
 78 //    P1 = readSlot(addr);
 79     while(1);
 80 }
 81 void start()
 82 {
 83     SDA = 1;
 84     SCL = 1;
 85     DELAY5US();
 86     SDA = 0;
 87     DELAY5US();
 88     SCL = 0;
 89     SDA = 1;    
 90 }
 91 
 92 void stop()
 93 {
 94     SDA = 0;
 95     SCL = 1;
 96     DELAY5US();
 97     SDA = 1;
 98     DELAY5US();
 99     SCL = 0;
100 }
101 
102 void ACK()
103 {
104     SDA = 0;
105     SCL = 1;
106     DELAY5US();
107 /****************强烈要求注意下面这两句话的顺序***************/
108 /*    SDA = 1*/
109 /*  SCL = 0*/
110 /*上面的操作时序是错误的,在SCL = 1的时候将SDA拉高,这样会形成停止信号*/
111 /*写时序的时候切忌啊*/    
112     SCL = 0;
113     SDA = 1;//将SDA 拉高,是为了释放数据总线
114 }
115 
116 void NACK()
117 {
118     SDA = 1;
119     SCL = 1;
120     DELAY5US();
121 
122     SCL = 0;
123 //    SDA = 0;
124 }
125 
126 void checkACK()
127 {
128     SDA = 1;//释放总线
129     SCL = 1;
130     F0 =0;
131     if(SDA == 1)
132         F0 = 1;
133     SCL = 0;
134 }
135 
136 void writeByte(uint8 dat)
137 {
138     uint8 i = 8;
139     uint8 temp;
140     temp = dat;
141     for(i; i>0; i--)
142     {        
143         SDA = ((dat & 0x80) >> 7);
144         SCL = 1;
145         DELAY5US();
146         SCL = 0;
147         DELAY5US();
148         dat = dat<<1;
149     }
150        SCL = 0;
151     SDA = 1;
152 }
153 void writeSlot(uint8 *addr, uint8 dat)
154 {
155     start();
156     writeByte(addr[0]);
157     checkACK();
158     if(F0 == 1)
159         return;
160     writeByte(addr[1]);
161     checkACK();
162     if(F0 == 1)
163         return;
164     writeByte(dat);
165     checkACK();
166     if(F0 == 1)
167         return;
168     stop();
169 }
170 void writeSlot1(struct Addr address, struct Buff sendBuff)
171 {
172     start();
173     writeByte(address.devAddr);
174     checkACK();
175     if(F0 == 1)
176         return;
177     writeByte(address.wordAddr);
178     checkACK();
179     if(F0 == 1)
180         return;
181     writeByte(*sendBuff.buff);
182     checkACK();
183     if(F0 == 1)
184         return;
185     stop();    
186 }
187 void writeSeq(struct Addr addr, struct Buff sendBuff)
188 {
189     uint8 i;
190     start();
191     writeByte(addr.devAddr);
192     checkACK();
193     if(F0 == 1)
194         return;
195     writeByte(addr.wordAddr);
196     checkACK();
197     if(F0 == 1)
198         return;
199     for(i=sendBuff.length; i>0; i--)
200     {
201         writeByte(*sendBuff.buff);
202         checkACK();
203         if(F0 == 1)
204             return;
205         sendBuff.buff++;
206     }
207     stop();
208 }
209 
210 uint8 readByte()
211 {
212     uint8 temp = 0;
213     uint8 i;
214 //    SDA = 1;//这句话是为了释放数据总线
215     for(i=0; i<8; i++)
216     {    
217         temp <<=1;
218         SCL = 0;
219         DELAY5US();
220         SCL = 1;
221         temp = temp | SDA;        
222         DELAY5US();
223         SCL = 0;
224         /*SCL = 1;
225         temp = temp<<1;
226         temp = temp | (uint8)SDA;
227         SCL = 0;*/
228     }
229     return temp;    
230 }
231 
232 uint8 readSlot(uint8 *addr)
233 {
234     uint8 date;
235     start();
236     writeByte(addr[0]);
237     checkACK();
238     writeByte(addr[1]);
239     checkACK();
240     start();
241     writeByte(addr[0] | 1);
242     checkACK();
243     date = readByte();
244     stop();
245     return date;
246 }
247 void readSeq(struct Addr address, struct Buff recvBuff)
248 {
249     uint8 i;
250     start();
251     writeByte(address.devAddr);
252     checkACK();
253     if(F0 == 1)
254         return;
255     writeByte(address.wordAddr);
256     checkACK();
257     if(F0 == 1)
258         return;
259     start();
260     writeByte(address.devAddr | 1);
261     checkACK();
262     if(F0 == 1)
263         return;
264     for(i = 0; i<recvBuff.length; i++)
265     {
266         recvBuff.buff[i] =readByte(); //readByte();
267         ACK();
268         NOP();
269     }
270     NACK();
271     stop();
272 }

 

posted on 2012-11-23 14:54  WithYouTh  阅读(373)  评论(0编辑  收藏  举报