Hi, I'm having some problems using i2c to write to an eeprom, a 24lc515. Sometimes it'll write to it without any problems, and sometimes it won't write at all. The code I am using is this: void EE_wr_byte(int EE_address, char data) { unsigned char transfer; unsigned int temp; unsigned char control = 0xA0; P4OUT |= SDA + SCL; //Stop P4DIR |= SDA + SCL; //Port as output P4OUT &= ~SDA; //Start EE_ser_out(control); //Control-byte temp = (EE_address >> 8); //High byte to send transfer = temp; EE_ser_out(transfer); transfer = EE_address; EE_ser_out(transfer); EE_ser_out(data); P4OUT |= SCL; //Stop P4OUT |= SDA; } void EE_ser_out(char data) { unsigned int a; P4OUT &= ~SCL; //SCL = 0 for(a=0;a<8;a++) { if(data & BIT7) { P4OUT |= SDA; } else { P4OUT &= ~SDA; } P4OUT |= SCL; P4OUT &= ~SCL; data = data << 1; } P4DIR &= ~SDA; P4OUT |= SCL; //Clock-pulse P4OUT &= ~SCL; P4DIR |= SDA; } and my main had this short int ffft; char fffv; int abcd; for ( ffft = 0; ffft<25; ffft++) { fffv = ffft+8; EE_wr_byte(ffft, fffv); abcd = EE_rd_byte(ffft); } however, it will only write on the even numbers of the memory. I changed my code to this: EE_wr_int(ffft, 1764); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 2640); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 0); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 0); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 0); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 0); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 1); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 1); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 1); abcd = EE_rd_int(ffft); ffft+=1; EE_wr_int(ffft, 1); abcd = EE_rd_int(ffft); ffft+=1; and it will stop writing after the first " EE_wr_int(ffft, 1); abcd = EE_rd_int(ffft);" I really don't understand what I'm doing wrong. At first I thought it was a delay issue, so I added some delays between the write and read cycles, however this does not change anything. Any help would be appreciated
problems with I2c
Started by ●November 25, 2006
Reply by ●November 27, 20062006-11-27
On 25 Nov 2006 12:21:23 -0800, ddshore@gmail.com wrote:>Hi, > >I'm having some problems using i2c to write to an eeprom, a 24lc515. >Sometimes it'll write to it without any problems, and sometimes it >won't write at all. >The code I am using is this: > >void EE_wr_byte(int EE_address, char data) >{<snip>> >I really don't understand what I'm doing wrong. At first I thought it >was a delay issue, so I added some delays between the write and read >cycles, however this does not change anything. > >Any help would be appreciatedIt is probably a delay issue. Writing 1 bytes takes like 10 msec because it has to do some erasing internally. Writing multiple bytes in the same page also takes 10 msec. Read the part about aknowledge polling in the datasheet. If you want to verify this is your problem, add like 10 or 20 msec of delay after writing 1 byte. Patrick
Reply by ●November 27, 20062006-11-27
> > transfer = EE_address; > EE_ser_out(transfer); > EE_ser_out(data); > > P4OUT |= SCL; //Stop > P4OUT |= SDA;It seems that EE_ser_out leaves the SDA line high or low depending on the last bit sent i.e. LSB. That's why you can only make a valid STOP when the previous byte's LSB was a 0.
Reply by ●November 29, 20062006-11-29
Viktor wrote:> > > > transfer = EE_address; > > EE_ser_out(transfer); > > EE_ser_out(data); > > > > P4OUT |= SCL; //Stop > > P4OUT |= SDA; > > It seems that EE_ser_out leaves the SDA line high or low depending on > the last bit sent i.e. LSB. That's why you can only make a valid STOP > when the previous byte's LSB was a 0.Thanks a lot, that was it!
Reply by ●November 29, 20062006-11-29
On Nov 29, 2:25 pm, ddsh...@gmail.com wrote:> Viktor wrote: > > > > transfer = EE_address; > > > EE_ser_out(transfer); > > > EE_ser_out(data); > > > > P4OUT |= SCL; //Stop > > > P4OUT |= SDA; > > > It seems that EE_ser_out leaves the SDA line high or low depending on > > the last bit sent i.e. LSB. That's why you can only make a valid STOP > > when the previous byte's LSB was a 0.Thanks a lot, that was it!Glad to help. I'd just like to add that that when I see bit-banging code (like yours is) written in C, not assembler, I get an urge to bite through my mouse cord. Try doing it in asm, then link it in as a C function. It'll be easier to write, read and debug. Viktor