www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR I2C Master Receiver kein ACK


Autor: Raph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Ich versuche verzweifelt mit einem AVR im TWI MasterReceiver Mode Daten 
von einem Slave abzuholen.
Mit einem LA sehe ich, dass die Adresse + R an den Slave gesendet wird, 
dieser mit einem ACK Antwortet, die ersten 8 Datenbit ausgibt und 
daaaaannn, bestätigt mein lieber AVR den Empfang mit einem NACK womit 
der Slave natürlich abbricht zu senden.
Ich bin kurz davor durchzudrehen! Bekomme es einfach nicht hin, dass er 
mit ACK bestätigt.
Kann mir jemand helfen?

case 10: // Daten abholen
  chrPos++;      // Anzahl empfangener Daten erhöhen
  if (chrPos < chrLen)
  {  // Mehr Daten zum empfangen --> ACK
    TWCR = (1 << TWEA) | (1 << TWINT) | (1 << TWEN);
    chrState = 10;  // In diesem case bleiben
  }
  else
  {  // Keine weiteren Daten empfangen --> NACK
    TWCR = (1 << TWINT) | (1 << TWEN);
    chrState++;
  }
  // Auf Daten warten
  while (!(TWCR & (1 << TWINT))) { FALLOUT; }
  RESFALLOUT;
  *ptchrData++ = TWDR;  // Daten in Array ablegen, Adresse erhöhen
  break;

Viele Grüsse Raph

Autor: Raph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Gemeinde

Bin ich denn er einzige der andauernd Probleme mit diesem TWI Modul im 
AVR hat?
Hat niemand von euch schon einmal mehrere Daten von einem I2C Slave 
abgeholt?

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Bin ich denn er einzige der andauernd Probleme mit diesem TWI Modul im
>AVR hat?

Sicher nicht.

>Hat niemand von euch schon einmal mehrere Daten von einem I2C Slave
>abgeholt?

Denke mal das du dir das selbst beantworten kannst.

Vielleicht hättest du die komplette .c mal anhängen sollen.
Oder die PDF zu ende lesen sollen....

Status Code 0x10 alleine hilft nicht, da der nur 1x kommt:
Aus dem pdf: 'A repeated START condition has been transmitted'
Du braucht auch noch 0x50 und 0x58.

Ausserdem denke ich mal das dem "case 10:" noch ein 0x fehlt....

Autor: Raph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tim

Erstmal danke für die Antwort.

Am Anhang findes du das komplette .c-File. Die Funktion "I2C_Task()" 
wird zyklisch aufgerufen.
Ich verwende überigens ein ATMEGA88.

>Du braucht auch noch 0x50 und 0x58

0x10 = TWSTO: TWI STOP Condition Bit
0x50 = TWI Enable Acknowledge Bit & TWSTO: TWI STOP Condition Bit
0x58 = zusätzlich noch TWI Write Collision Flag?

Falls du die 0x50 und 0x58 von "Figure 21-14" hast, muss ich dir leider 
sagen, dass dies der Code im TWSR ist, welches nur gelesen werden kann.
Die ganze Steuerung findet ja mit dem TWCR statt und da habe ich TWEA 
gesetzt. Ich muss allerdings gestehen, dass ich nicht ganz verstanden 
habe was Atmel bei den 3 Bedingungen meint. Meiner Ansicht nach, sind 
das alles Dinge die mich nicht betreffen da ich im MasterReceiver Mode 
arbeite und nicht im Slave:

>The TWEA bit controls the generation of the acknowledge pulse.
>If the TWEA bit is written to one, the ACK pulse is generated on the TWI bus
>if the following conditions are met:
>1. The device’s own slave address has been received.
>2. A general call has been received, while the TWGCE bit in the TWAR is set.
>3. A data byte has been received in Master Receiver or Slave Receiver mode.
>By writing the TWEA bit to zero, the device can be virtually
>disconnected from the 2-wire Serial
>Bus temporarily. Address recognition can then be
>resumed by writing the TWEA bit to one again.

>Ausserdem denke ich mal das dem "case 10:" noch ein 0x fehlt....

Das ist korrekt so, ich habe die cases Dezimal nummeriert

Grüsse Raph

Autor: Raph (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier kommt noch der Anhang

Autor: Raph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Jetzt geht es.
Ich vermute, dass der Controller zu lange gewartet hat, bis er die Daten 
abgeholt hat. Weil dann das TWDR noch belegt war, wurde ein NACK 
zurückgegeben. Aber wie gesagt, ist nur eine Vermutung.

Grüsse Raph

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach so.... du verwendest
switch (chrState)
und Passt den wert von chrState entsprechend an.
Das war leider im 1. Post nicht ersichtlich.

Normalerweise bastelt man eine Interrupt rutiene die
vom TWI aufgerufen wird. Selbige entscheidet dann anhand
des Statuscodes aus TWSR was sie machen soll und
schreibt das jeweils gewollte in TWCR.
Man kann sich so eine schöne Ablaufsteuerung zusammenbauen,
da das TWI für jede mögliche Situation einen eigenen
Statuscode hat.
Deswegen der Hinweiss auf 0x.

In deinem Fall müstest du "nur" die Status Codes der Tabellen
21-2, 21-3 und 21-6 bearbeiten.
ggf ist noch ein Timeout sinnvoll.

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.