mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Serielles EEPROM über I2C auslesen


Autor: C. B. (catwiesl1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Ich möchte ein serielles 256 Byte EEPROM über I2C per random read 
(beliebige Speicherzelle) mit dem ATMEGA8 auslesen. Das Schreiben 
funktioniert soweit.

Der Lesevorgang klappt allerdings nur ein einziges mal. Starte ich einen 
zweiten Lesevorgang, um ein weiteres Byte zu lesen, "hängt" der uC.

Soweit ich das beurteilen kann, müsste das Problem in der while-Schleife 
beim Senden der Start-Bedingung i2c_start() liegen. Stimmt das? Wie 
lässt sich das Problem lösen?


Im folgenden der Code:
void i2c_start(void)
{

  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
  while((TWCR & _BV(TWINT)) == 0);
}

void i2c_stop(void)
{
  TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
}


void i2c_send(uint8_t Data)
{
  TWDR = Data;
  TWCR = _BV(TWINT) | _BV(TWEN);
  while ((TWCR & _BV(TWINT)) == 0);
}

uint8_t i2c_receive(uint8_t ack)
{
  if(ack ==1)
    TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN);
  else
    TWCR = _BV(TWINT) | _BV(TWEN);
  while((TWCR & _BV(TWINT)) == 0);
  return TWDR;
}

//###################################################

uint8_t ReadRandomByte(uint16_t addr)
{
    PORTD |= (1 << DDD3);  //Status LED auf High
  uint8_t wert;
  i2c_start();
  i2c_send(BASEADR | TW_WRITE);
  i2c_send(addr);
  i2c_start();
  i2c_send(BASEADR | TW_READ);
  wert = i2c_receive(1);
  i2c_stop();
  PORTD &= ~(1 << DDD3);       //Status LED auf Low
  return wert;
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist aber nicht das ganze Programm, oder?

>· Bit 5 ­ TWSTA: TWI START Condition Bit
> The application writes the TWSTA bit to one when it desires to
> become a Master on the Two-wire Serial Bus. The TWI hardware
> checks if the bus is available, and generates a START condition
> on the bus if it is free. However, if the bus is not free, the
> TWI waits until a STOP condition is detected, and then generates
> a new START condition to claim the bus Master status.
> TWSTA must be cleared by software when the START condition
> has been transmitted.

Löschst du TWSTA irgendwo auch wieder?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Abgesehen davon bin ich mir auch nicht sicher, ob du überhaupt richtig 
liest.

Lt. Datenblatt zum AT24C01A etc. sieht random read so aus:
RANDOM READ: A random read requires a "dummy" byte write sequence to load in the data
word address. Once the device address word and data word address are clocked in and
acknowledged by the EEPROM, the microcontroller must generate another start condition.
The microcontroller now initiates a current address read by sending a device address with the
read/write select bit high. The EEPROM acknowledges the device address and serially clocks
out the data word. The microcontroller does not respond with a zero but does generate a fol-
lowing stop condition (see Figure 11 on page 12).

Das kann ich in deiner Leserei nicht wiederfinden.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das letzte Byte muss mit einem "NAK" gelesen werden, also
wert = i2c_receive(0);

Autor: ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das letzte Byte muss mit einem "NAK" gelesen werden

Richtig, steht in den meisten Datenblättern so drin, hab ich aber nie 
gemacht und hat mit den meisten (24c02, 24x04 und 24c16) auch so 
funktioniert, nach der Stopbedingung setzt sich die EEPROM-interne Logik 
wohl auch so zurück.
mfG ingo

Autor: C. B. (catwiesl1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So funktioniert es:

Detlev T. schrieb:
> Das letzte Byte muss mit einem "NAK" gelesen werden, also
> wert = i2c_receive(0);


Danke für die Antworten!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.