Forum: Mikrocontroller und Digitale Elektronik Frage zu i2c NOT ACK bei ATMega328P


von i2c twi (Gast)


Lesenswert?

Das ist meine erstes i2c-Übung mit Interrupts: Ich möchte den 
Hardware-i2c benutzen, um mit einem Chip zu kommunizieren (ATMega328P 
ist Master) und dabei den i2c-Interrupt benutzen.

Dieses funktioniert schon:

1) ich setze das TWCR auf (hex)A5 so und starte damit die 
i2c-Kommunikation:

  '1         delete int flag and so start twi action
  ' 0        no acknowledge generation
  '  1       TWSTA - generate start condition
  '   0      TWSTO - no stop condition
  '    0     no write collision
  '     1    TWEN - enable twi action
  '      0   not used
  '       1  enable interrupt

Die erste Frage wäre, ob ich die Bits richtig verstanden habe (siehe 
Kommentare) - aber ich hoffe schon.

2) ich warte auf den i2c-Interrupt und lese das Statusregister ohne die 
unteren 3 bits - es steht (hex)08 drin, was bedeutet, dass das 
Start-Signal gesendet wurde.

3) Ich schreibe die Adresse (hex)40 (Schreibzugriff) ins TWDR 
(Datenregister) und setze das TWCR auf (hex)85 - wie bei 1), nur ohne 
einen Start zu generieren.

4) Ich warte wieder auf den Interrupt. Hier würde ich (hex)18 
zurückerwarten (Schreibadresse ACK), bekomme aber hex(20) 
(=Schreibadresse not ACK), was ich so interpretiere, dass der Slave kein 
ACK gesendet hat.

Heißt das jetzt - der Slave ist noch nicht soweit? Oder hat er ein ACK 
gesendet, aber verzögert? Und wie bekomme ich mit, wenn er dann fertig 
ist / wir müsste ich die i2c-Hardware abfragen, ohne schon ein neues 
Byte zu senden?

Ich find das alles noch etwas schwer zu verstehen in der Abfolge..

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

i2c twi schrieb:
> 4) Ich warte wieder auf den Interrupt. Hier würde ich (hex)18
> zurückerwarten (Schreibadresse ACK), bekomme aber hex(20)
> (=Schreibadresse not ACK), was ich so interpretiere, dass der Slave kein
> ACK gesendet hat.

 Oder da ist kein Slave auf dem Bus oder die Slaveadresse ist falsch...


> Heißt das jetzt - der Slave ist noch nicht soweit? Oder hat er ein ACK
> gesendet, aber verzögert?

 Wenn alles andere stimmt, heißt NACK, daß der Slave noch nicht bereit
 ist. Und verzögertes ACK gibt es nicht - entweder ist ACK zeitlich
 richtig gesendet oder er wird als NACK gedeutet.

> Und wie bekomme ich mit, wenn er dann fertig
> ist / wir müsste ich die i2c-Hardware abfragen, ohne schon ein neues
> Byte zu senden?

 Nur neues START + Slaveadresse, anders geht es nicht.

von Jobst M. (jobstens-de)


Lesenswert?

i2c twi schrieb:
> Das ist meine erstes i2c-Übung mit Interrupts

D.h. ohne hast Du es schon zum laufen bekommen?

i2c twi schrieb:
> Die erste Frage wäre, ob ich die Bits richtig verstanden habe

Passt.

i2c twi schrieb:
> was ich so interpretiere, dass der Slave kein
> ACK gesendet hat.

Jo.

i2c twi schrieb:
> Heißt das jetzt - der Slave ist noch nicht soweit?

Wie reagiert er denn ohne IRQ?

> Oder hat er ein ACK gesendet, aber verzögert?

Nein, vermutlich nicht.
Was ist denn Dein Slave?


Gruß

Jobst

von i2c twi (Gast)


Lesenswert?

Marc V. schrieb:
> Oder da ist kein Slave auf dem Bus oder die Slaveadresse ist falsch...

Ah ok.. ich habe vermutet, dass die (hex)08, die ich beim ersten 
Interrupt kriege, schon irgendeine Reaktion vom Slave ist.. Aber das ist 
sie wohl gar nicht..

Ist dann aber auch komisch - wie sollte ich da eine andere Statusinfo 
als (hex)08 bekommen, wenn es vom Slave gar nicht abhängt??

von i2c twi (Gast)


Lesenswert?

Jobst M. schrieb:
>> Das ist meine erstes i2c-Übung mit Interrupts
>
> D.h. ohne hast Du es schon zum laufen bekommen?

Nein, die Betonung liegt auf "erste i2c-Übung". Die Interrupts selbst 
kommen zuverlässig nach jeder Aktion, wo ich das unterste und oberste 
Bit setze, damit hab ich kein Problem.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

i2c twi schrieb:
> Ist dann aber auch komisch - wie sollte ich da eine andere Statusinfo
> als (hex)08 bekommen, wenn es vom Slave gar nicht abhängt??

 Du kannst vorerst alle ungeraden Adressen abfragen, wenn ACK kommt,
 Slave ist vorhanden und bereit.

 Dauert gerade mal 20ms mit START und STOP...

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Marc V. schrieb:
> Wenn alles andere stimmt, heißt NACK, daß der Slave noch nicht bereit
>  ist. Und verzögertes ACK gibt es nicht - entweder ist ACK zeitlich
>  richtig gesendet oder er wird als NACK gedeutet.

das ist falsch!

Wenn mehr als ein Byte zurückerwartet wird wartet man auf ACK, auf das 
letzte Byte oder einzige Byte wird auf NACK erwartet!

Marc V. schrieb:
> Und verzögertes ACK gibt es nicht

das stimmt, aber es gibt clock stretching, die AVR Routinen behandeln 
das oft nicht, das könnte man mit Timer und Portabfrage wenigstens 
begrenzen damit bei SCL Dauerlow der nicht steht und endlos wartet, es 
müsste eine timeout Routine programmiert werden, hatte aber noch nie das 
Problem.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Joachim B. schrieb:
> Marc V. schrieb:
>> Wenn alles andere stimmt, heißt NACK, daß der Slave noch nicht bereit
>>  ist. Und verzögertes ACK gibt es nicht - entweder ist ACK zeitlich
>>  richtig gesendet oder er wird als NACK gedeutet.
>
> das ist falsch!
>
> Wenn mehr als ein Byte zurückerwartet wird wartet man auf ACK, auf das
> letzte Byte oder einzige Byte wird auf NACK erwartet!


 Immer noch nichts gelernt ?
 Und warum schreist du schon wieder ?

 Beim senden der Adresse erwartet man weder 1 Byte zurück, noch
 mehrere - es wird nur auf ACK oder NACK geprüft...

von Jobst M. (jobstens-de)


Lesenswert?

Joachim B. schrieb:
> das ist falsch!
>
> Wenn mehr als ein Byte zurückerwartet wird wartet man auf ACK, auf das
> letzte Byte oder einzige Byte wird auf NACK erwartet!

Das ist auch etwas undeutlich.

Bei der Adressierung antwortet der Slave immer mit ACK.

Beim schreiben antwortet der Slave immer mit ACK und der Master kann die 
Übertragung jederzeit mit STO beenden.

Beim lesen sendet der Master nach jedem empfangenem Datenbyte ein ACK, 
wenn er noch ein weiteres Byte haben möchte. Sonst ein NACK. Wird ACK 
gesendet, geht der Slave von einer weiteren Übertragung aus und klemmt 
SDA möglicherweise auf Low fest (er wartet ja auf den nächsten Takt für 
das nächste Bit) in diesem Zustand ist es dem Master nicht möglich STO 
zu senden, da STA nicht auf High geht.


Gruß

Jobst

von Jobst M. (jobstens-de)


Lesenswert?

Marc V. schrieb:
> Beim senden der Adresse erwartet man weder 1 Byte zurück, noch
>  mehrere - es wird nur auf ACK oder NACK geprüft...

Nein, beim lesen musst Du mindestens ein Byte abnehmen. Denn das erste 
ACK kommt vom Slave.


Gruß

Jobst

von i2c twi (Gast)


Lesenswert?

Marc V. schrieb:
> Du kannst vorerst alle ungeraden Adressen abfragen, wenn ACK kommt,
>  Slave ist vorhanden und bereit.

Hab ich probiert - jetzt kommt (hex)48 zurück - also auch kein Ack beim 
lesen.

Da werd ich mal später die verkabelung und Adressierung durchmessen - 
danke Euch erstmal!

von Joachim B. (jar)


Lesenswert?

Marc V. schrieb:
> Und warum schreist du schon wieder ?

du bist doch derjenige der seine eigenen Regeln aufstellt

JETZT SCHREIE ICH nur um das mal klarzustellen

schau dir mal die Fleury LIB an
http://homepage.hispeed.ch/peterfleury/avr-software.html
1
        i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode
2
        i2c_write(0x05);                        // write address = 5
3
        i2c_rep_start(Dev24C02+I2C_READ);       // set device address and read mode
4
        ret = i2c_readNak();                    // read one byte
5
        i2c_stop();                              // set stop condition = release bus
1
        /* write ok, read value back from eeprom address 0..3 (Sequencial Read),
2
           wait until the device is no longer busy from the previous write operation */
3
        i2c_start_wait(Dev24C02+I2C_WRITE);      // set device address and write mode
4
        i2c_write(0x00);                         // write address = 0
5
        i2c_rep_start(Dev24C02+I2C_READ);        // set device address and read mode
6
        ret = i2c_readAck();                       // read one byte form address 0
7
        ret = i2c_readAck();                       //  "    "    "    "     "    1
8
        ret = i2c_readAck();                       //  "    "    "    "     "    2
9
        ret = i2c_readNak();                       //  "    "    "    "     "    3
10
        i2c_stop();                              // set stop condition = release bus

von Joachim B. (jar)


Lesenswert?

Jobst M. schrieb:
> Das ist auch etwas undeutlich.

OK sehe ich ein!

deswegen habe ich mal den Link auf die Fleury LIB gesetzt!

von i2c twi (Gast)


Lesenswert?

Ach ja und auf ein "clock stretching" könnte ich nicht reagieren: Ich 
will ja so arbeiten, dass ich immer ein Byte sende oder empfange, und 
dann nach jedem Byte einen Interrupt erwarte, wo ich dann das Ergebnis 
auswerte und die nächste Aktion starte.

Also entweder reagiert die i2c-Hardware auf das Clock stretching und 
löst den Interrupt entsprechend später aus, oder ich bekomme es nicht 
mit.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Jobst M. schrieb:
> Marc V. schrieb:
>> Beim senden der Adresse erwartet man weder 1 Byte zurück, noch
>>  mehrere - es wird nur auf ACK oder NACK geprüft...
>
> Nein, beim lesen musst Du mindestens ein Byte abnehmen. Denn das erste
> ACK kommt vom Slave.

 Wenn man Slave adressiert, muss genau gar nichts abgenommen werden.
 Wird nur auf ACK oder NACK geprüft.
 Falls ACK kommt, geht es weiter, wenn kein ACK (was gleichzusetzen
 ist mit NACK) kommt, wird überhaupt nicht weiter gesendet.

von Jobst M. (jobstens-de)


Lesenswert?

Marc V. schrieb:
> Falls ACK kommt, geht es weiter, wenn kein ACK (was gleichzusetzen
>  ist mit NACK) kommt, wird überhaupt nicht weiter gesendet.

Ich gehe natürlich von dem Fall aus, dass ein Slave adressiert wird und 
auch antwortet und die Kommunikation klappt. Wie es NICHT funktioniert, 
beschreibe ich nicht.


Gruß

Jobst

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Jobst M. schrieb:
> Ich gehe natürlich von dem Fall aus, dass ein Slave adressiert wird und
> auch antwortet und die Kommunikation klappt.

 Wenn es so wäre, hätte der TO gar nicht erst den Thread eröffnet.

> Wie es NICHT funktioniert, beschreibe ich nicht.

 Es geht darum, dem TO zu helfen weil es NICHT funktioniert.
 Ratschläge wie es geht wenn es geht, braucht er nicht, er versteht
 schon genug von I2C um es alleine zu schaffen.

von Jobst M. (jobstens-de)


Lesenswert?

Marc V. schrieb:
> Wenn es so wäre, hätte der TO gar nicht erst den Thread eröffnet.

Richtig.

Marc V. schrieb:
> Es geht darum, dem TO zu helfen weil es NICHT funktioniert.

Und dazu muss er wissen, wie es RICHTIG funktioniert.
NICHT funktioniert es ja schon, dafür benötigt er keine Anleitung.


Aber das Ganze ist auch nicht sein Problem. Das Problem ist eine 
Streiterei zwischen Joachim B. und Dir gewesen. Offensichtlich streitest 
Du nun mit mir ...

Dem TO ist klar, dass er ein NACK bekommt. Das hat nichts mit dem darauf 
folgendem Byte zu tun. Die Frage ist, wieso er ein NACK bekommt.
 Falsche Adresse? (Ich fragte nach dem Slave)
 Falscher Anschluss?
 Baustein defekt?


Gruß

Jobst

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Jobst M. schrieb:
> Dem TO ist klar, dass er ein NACK bekommt. Das hat nichts mit dem darauf
> folgendem Byte zu tun. Die Frage ist, wieso er ein NACK bekommt.
>  Falsche Adresse? (Ich fragte nach dem Slave)
>  Falscher Anschluss?
>  Baustein defekt?

 Muss er selber prüfen, da kann ihm keiner helfen.

 Hardware ist es auf jeden Fall, vorausgestzt er hat alle Adressen
 durchgesendet und Geschwindigkeit ist auch passend (<=100KHz).

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Marc V. schrieb:
> Es geht darum, dem TO zu helfen weil es NICHT funktioniert.

aha und wo ist deine Hilfe für den TO ausser mich andauernd anzugiften?

Ich weiss wie es mit der Fleury LIB funktioniert, nutze das seit Jahren, 
aber noch nie auf IRQ Basis auch hatte ich den Fall mit dem SCL 
Stretching noch nicht oder nur indirekt, beim Arduino und I2C EEPROM 
vielleicht, statt busy o.ä. frage ich einfach ab wann das I2C EEPROM 
wieder bereit ist und da ohne Probleme, logisch könnte man auch einen 
Timeout setzen wenn die Routinen nie passend zurückkommen.

: Bearbeitet durch User
von i2c twi (Gast)


Lesenswert?

Marc V. schrieb:
> Es geht darum, dem TO zu helfen weil es NICHT funktioniert.
>  Ratschläge wie es geht wenn es geht, braucht er nicht, er versteht
>  schon genug von I2C um es alleine zu schaffen.

Danke für die Blumen.. :-) Wie oben schon erwähnt - ich muss nochmal die 
Hardware durchmessen (Widerstände, Adress-pins etc.)

Wenn ich den Fehler gefunden habe schreib ich nochmal. Kein Grund zu 
streiten.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb im Beitrag #4631122:
> Marc V. schrieb:
>> aber du hast keine Ahnung  warum und wie es funktioniert.
> noch so''n blöder Schnack von dir, große Klappe nix dahinter?
Könntet ihr beiden euch per PN weiterstreiten. Und wenn ihr euch dann 
einig seid, wer Recht hat, dann gebt ihr bitte das Ergebnis und die 
Lösung bekannt.

von Joachim B. (jar)


Lesenswert?

Lothar M. schrieb:
> Könntet ihr beiden euch per PN weiterstreiten.

ich will mich nicht streiten, aber ich will auch nicht blöd angemacht 
werden, ich weiss was ich kann und wenn ich was nicht kann lerne ich 
gerne hier!

von i2c twi (Gast)


Lesenswert?

Leider noch kein Erfolg - ich probiere es jetzt erstmal einfacher / ohne 
Interrupt, hab dafür einen extra-Thread aufgemacht (weil andere 
Vorgehensweise):

Beitrag "bitte um Hilfe zum I2c debuggen INA219-Modul"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.