www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik EEPROM read, 16-Bit Adresse, TWI


Autor: Jürgen Hems (misteret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe einen EEPROM Baustein und versuche ihn mit dem ATmega16 zu 
beschreiben und auszulesen.

Es handelt sich um einen EEPROM von Microchip:
http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=A32...

Ich denke, das Beschreiben hat funktioniert. Jedenfalls bekam ich immer 
die korrekten Status Codes im TWSR Register.


Das Lesen bereitet mit noch Probleme.
Im datasheet des 24LC512 finde ich auf Seite 14 folgenes Schema fürs 
Auslesen:

Write Start Condition - ACK - Write ControlByte - Write HighByte_address 
- ACK - Write LowByte_address - ACK - Write Start Condition - ACK - 
Write Control Byte - ACK - READ data

So, nach dem Schreiben des LowBytes der Adresse steht in TWSR der Code 
$28. Jetzt sende ich erneut eine Start Conditon, das ist dann eine 
repeated Start conditon, also erwarte ich den Statuscode $10. Danach 
wird 0xA1 für Auslsen an TWDR gesendet, allerdings wird kein Wert dort 
reingeladen aus dem EEPROM. Ich kann euch ja mal einen Code schicken von 
meinem C-Quelltext.

Ich glaube, der ATmega16 erwartet nach dem SSchreiben der Adresse ein 
Auslesen des Bytes im EEPROM, und nicht eine erneute Start-Condition. So 
ist es auf Seite 190/191 des ATmega16 datasheets.

Autor: Jürgen Hems (misteret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define START     0x08
#define MT_SLAW_ACK  0x18
#define MT_DATA_ACK  0x28
#define MT_SLAR_ACK     0x40
#define RSTART    0x10

int TWI_send(void)
{
  
  // START
  TWI_start();
  // Warten, bis START-condition übermittelt ist
  if ( (TWSR & 0xF8) != START) return(0);    
    
  // Control-Code + Adresse + Schreibbit  
  TWDR = 0xA0;
  // Control-Code + Adresse des EEPROMS und Schreibbit
  // in Datenregister laden
  TWCR = (1<<TWINT) | (1<<TWEN);
  // senden
  while( !(TWCR&(1<<TWINT)) ){;}
  // warten auf ACK    

  if( (TWSR & 0xF8) != MT_SLAW_ACK ) 
  {
    TWI_stop();
    return 0;
  }

  
  
  // High-Byte der Adresse
  
  TWDR = 0x00;
  // High-Byte der Adresse in Datenregister laden
  TWCR = (1<<TWINT) | (1<<TWEN);
  // senden
  while( !(TWCR&(1<<TWINT)) ){;}
  // warten auf ACK 

  if( (TWSR & 0xF8) != MT_DATA_ACK ) return (0); 
  // Übermittlung prüfen

  // Low-Byte der Adresse
  TWDR = 0x0A;
  // Low-Byte der Adresse in Datenregister laden
  TWCR = (1<<TWINT) | (1<<TWEN);
  // senden
  while( !(TWCR&(1<<TWINT)) ){;}
  // warten auf ACK 

  if( (TWSR & 0xF8) != MT_DATA_ACK ) return(0);       
  // Übermittlung prüfen

  
  
  // Daten
    
  TWDR = 0x55;
  // 0x55 in Datenregister laden
  TWCR = (1<<TWINT) | (1<<TWEN);
  // senden
  while( !(TWCR&(1<<TWINT)) ){;}
  // warten auf ACK   


  if( (TWSR & 0xF8) != MT_DATA_ACK ) return(0); 
  // Übermittlung prüfen



  // STOP
  TWI_stop();
  return(1);
  
}

unsigned char TWI_read(void)
{
  unsigned char test = 0;
  // START
  TWI_start();
  if ( (TWSR & 0xF8) != START) return(0);
  // Prüfen, ob START korrekt übermittelt wurde


  
  // Control-Code + Adresse + Schreibbit
  TWDR = 0xA0;
  // Control-Code + Adresse des EEPROMS und Schreibbit
  // in Datenregister laden
  TWCR = (1<<TWINT) | (1<<TWEN);
  // senden
  while( !(TWCR&(1<<TWINT)) ){;}
  // warten auf ACK

  if( (TWSR & 0xF8) != MT_SLAW_ACK ) 
  {
    TWI_stop();  
    return(0); 
    // Übermittlung prüfen
  }

  
  
  // High-Byte der Adresse
  TWDR = 0x00;
  // High-Byte der Adresse in Datenregister laden
  TWCR = (1<<TWINT) | (1<<TWEN);
  // senden
  while( !(TWCR&(1<<TWINT)) ){;}
  // warten auf ACK
 
  if( (TWSR & 0xF8) != MT_DATA_ACK ) return(0); 
  // Übermittlung prüfen

  
  
  // Low-Byte der Adresse
  TWDR = 0x0A;
  // Low-Byte der Adresse in Datenregister laden
  TWCR = (1<<TWINT) | (1<<TWEN);
  // senden
  while( !(TWCR&(1<<TWINT)) ){;}
  // warten auf ACK 

  if( (TWSR & 0xF8) != MT_DATA_ACK ) return(0); 
  // Übermittlung prüfen

  
  
  // START
  TWI_start();
  if ( (TWSR & 0xF8) != RSTART) return(0);
  // Prüfen, ob START korrekt übermittelt wurde
  


  // Control-Code + Adresse + Lesebit
  TWDR = 0xA1;
  // Control-Code + Adresse des EEPROMS und Schreibbit
  // in Datenregister laden
  TWCR = (1<<TWINT) | (1<<TWEN);
  // senden
  while( !(TWCR&(1<<TWINT)) ){;}
    // warten auf ACK 

  if( (TWSR & 0xF8) != MT_SLAR_ACK ) return(0); 
  // Übermittlung prüfen

  
  
  // Auslesen
  test = TWDR;

  
  // STOP
  TWI_stop();
  // STOP-Condition

  return(test);

}

Autor: Jürgen Hems (misteret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok ich habs gefunden

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.