Forum: Mikrocontroller und Digitale Elektronik Probleme beim auslesen vom AT24C512B


von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute bin seit Tagen am probieren vom AT24C512B zu lesen bzw zu 
schreiben. Im anhang hab ich ein Testprogram was mir einen Wert in den 
EEPROM schreiben soll, wieder auslesen und per UART an den PC schicken 
soll. bekomm aber immer nur 255 gesendet. WP ist auf GND Adresse ist 1 
eingstellt. Hab schon wie oft im Datenblatt gesucht aber nichts 
gesonderes gefunden. Vll überseh ich auch was. Kann jemand mir 
weiterhelfen

von Oliver J. (skriptkiddy)


Lesenswert?

Wenn man vom Master zum Slave ein Byte schreibt, dann gibt der Slave ein 
ACK nicht der Master.

Gruß Oliver

von Peter (Gast)


Lesenswert?

Also hab mal alle auf 0 geschrieben ausser beim Readbyte. Jetzt sendet 
er noch nicht einmal.

von Oliver J. (skriptkiddy)


Lesenswert?

Schau dir am besten mal die I2C-Routinen von Peter Fleury an. Die 
funktionieren 100-prozentig.

http://homepage.hispeed.ch/peterfleury/avr-software.html

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Also habe es mal mit der anderen Routine Probiert aber klappt immer noch 
nicht. Noch eine Idee?

von Peter D. (peda)


Lesenswert?

Peter schrieb:
> bekomm aber immer nur 255 gesendet

Dein Read schreibt ja auch wieder 255 rein.

Zum Lesen mußt Du Repeat-Start + Leseadresse senden.
Genau so, wies im Datenblatt des 24C512 steht.

Und nach dem Schreiben entweder Adreß-ACK-Polling oder 10ms warten.


Peter

von Peter (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Dein Read schreibt ja auch wieder 255 rein.

Beim aktuellen Code?

von Peter D. (peda)


Lesenswert?

Peter schrieb:
> Peter Dannegger schrieb:
>> Dein Read schreibt ja auch wieder 255 rein.
>
> Beim aktuellen Code?

Ja natürlich.

Die Richtung kann man nur mit dem I2C-Adreßbyte umschalten. Dein
1
input = i2c_readAck();
macht daher ein I2C-Write mit 0xFF.

Du solltest endlich mal ins 24C512 Datenblatt schauen. Da ist alles 
ausführlich dargestellt.


Peter

von Peter (Gast)


Lesenswert?

Ich hab doch hier das Bit 0 (R/W Bit) in der xyz Variable auf 1 gesetzt. 
Damit maskiere ich meine Adresse zum senden an das EEPROM.
1
    xyz|=0b10100001;
2
    addressout=addressout<<1;
3
    xyz|=addressout;

von Peter (Gast)


Lesenswert?

Mit der Variable adressout will ich flexibel bleiben um auch mehrere 
EEPROM im System beschreiben zu können.

von Oliver J. (skriptkiddy)


Lesenswert?

Versuchs mal so:
1
unsigned char eeprom_readbyte (unsigned char addressout, uint16_t eepromaddress){    
2
    addressout = addressout<<1;
3
    i2c_init();
4
    i2c_start_wait(0b10100000|addressout);
5
    i2c_write((eepromaddress>>8)&0xFF);
6
    i2c_write(eepromaddress&0xFF);
7
    i2c_start_rep(0b10100001|addressout);
8
    unsigned char input = i2c_readAck();
9
    i2c_stop();
10
    return input;
11
}

PS: RTFM. Da sieht man schön unter "Random Read", was man machen muss.

Gruß Oliver

von Peter (Gast)


Lesenswert?

Hi sorry habs jetzt auch gesehen. Werde es nach der Arbeit mal 
ausprobieren. Schonmal vielen dank für die Hilfe!

von Peter (Gast)


Lesenswert?

So hier mal die getesteten Programme. Hat also am auslesen gelegen. auch 
bei dem hier zuletzt geposteten Programm ist noch der Fehler das auf ein 
ACK gewartet wird. Beim lesen muss aber ohne ACK gelesen werden.
1
void eeprom_writebyte (unsigned char addressout, uint16_t eepromaddress ,unsigned char data)
2
{
3
    addressout = addressout<<1;
4
    i2c_init();
5
    i2c_start_wait(0b10100000|addressout);
6
    i2c_write ((eepromaddress>>8)&0xFF);
7
    i2c_write (eepromaddress&0xFF);
8
    i2c_write (data);
9
    i2c_stop ();
10
}
11
12
unsigned char eeprom_readbyte (unsigned char addressout, uint16_t eepromaddress)
13
{    
14
    addressout = addressout<<1;
15
    i2c_init();
16
    i2c_start_wait(0b10100000|addressout);
17
    i2c_write((eepromaddress>>8)&0xFF);
18
    i2c_write(eepromaddress&0xFF);
19
    i2c_start_wait(0b10100001|addressout);
20
    unsigned char input = i2c_readNak();
21
    i2c_stop();
22
    return input;
23
}

von Oliver J. (skriptkiddy)


Lesenswert?

Peter schrieb:
> auch
> bei dem hier zuletzt geposteten Programm ist noch der Fehler das auf ein
> ACK gewartet wird.

Genau genommen wird beim Lesen nicht auf ein ACK gewartet, sondern eines 
gesendet. Das aber nur, wenn man noch ein weiteres Bytes lesen möchte.

Das i2c_read_ack ist natürlich deplatziert, wenn man nur ein Byte 
lesen will.

Gruß Oliver

von Peter (Gast)


Lesenswert?

Hallo zusammen,

macht das hier sind oder gibt es eine besser/schnellere alternative ein 
Pagewrite/read durchzuführen. Habe keine richtige AT24C512 lib in C 
gefunden.
1
void at24c512_pagewrite(unsigned char addressout, uint16_t eepromaddress , uint8_t &ee_data, uint8_t len)  //Maximal len=128
2
{
3
    addressout = addressout<<1;
4
    i2c_init();
5
    i2c_start_wait(0b10100000|addressout);
6
    i2c_write ((eepromaddress>>8)&0xFF);
7
    i2c_write (eepromaddress&0xFF);
8
  for(uint8_t i=0; i<len; i++)
9
  {
10
    i2c_write (ee_data);
11
    &ee_data++;
12
  }
13
    i2c_stop ();
14
}
15
16
void at24c512_pageread(unsigned char addressout, uint16_t eepromaddress, uint8_t &ee_data, uint8_t len)  //Maximal len=128
17
{    
18
    addressout = addressout<<1;
19
    i2c_init();
20
    i2c_start_wait(0b10100000|addressout);
21
    i2c_write((eepromaddress>>8)&0xFF);
22
    i2c_write(eepromaddress&0xFF);
23
    i2c_start_wait(0b10100001|addressout);
24
  for(uint8_t i=0; i<(len-1); i++)
25
  {
26
    *ee_data=i2c_readAck(ee_data);
27
    &ee_data++;
28
  }
29
    *ee_data=i2c_readNak();
30
    i2c_stop();
31
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter schrieb:
> Hallo zusammen,

Für Deine Frage solltest Du einen neuen Thread eröffnen, statt einen nur 
vage mit Deinem Thema verwandten aus der fünfjährigen Versenkung zu 
holen.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.