ATmega328P TWI/I²C PCF8574 Assembler

OP #7635669
Lesenswert?

Hallo, ich versuche, ein 2004 LCD mit einem PCF8574 über I²C in Assembler anzusteuern. Dazu habe ich folgende Quelle online gefunden: https://aylo6061.com/2014/04/23/atmega328p-assembly-i2c-transactions/ Mich verwirrt allerdings die Rolle vom "TWINT". So, wie ich es verstanden habe, wird dieses Flag immer gesetzt, wenn irgendwas auf dem I²C-Bus passiert ist, z.B, wenn die Start-Bedingung erfolgreich gesendet wurde. Anschließend, um fortzufahren, muss es, indem es auf "1" gesetzt wird, wieder zurückgesetzt werden. Wenn jetzt die Start-Bedingung gesendet wurde, müsste also TWINT "0" betragen. Im verlinkten Beispiel soll geprüft werden, ob die Start-Bedingung gesendet wurde:

1
WAIT_START:
2
lds          temp,TWCR
3
sbrs         temp,TWINT
4
rjmp         WAIT_START

Warum wird hier fortgefahren, wenn TWINT "1" ist? Müsste die Schleife nicht unterbrochen werden, wenn TWINT "0" ist? Danke schonmal!

#7635754
Lesenswert?

Leonardo schrieb:

Wastl schrieb:

Leonardo schrieb:

Also schreibe ich eine "1" und dann steht eine "0" in TWINT.

Ja. Und vielleicht solltest du endlich mal das Datenblatt des Controllers lesen, dort steht nämlich alles verbindlich drin.

Ist für mich widersprüchlich.

Wenn du das Datenblatt gelesen hättest, wüsstest du, daß das bei fast allen Interruptflags auf einem AVR so ist. Wenn dir nicht das gefällt, nimm einen anderen Prozessor.

Oliver

OP #7635763
Lesenswert?

Das hat nichts mit "gefallen" zu tun, sondern mit verstehen. Da ich es nicht verstanden habe, habe ich gefragt.

Ich möchte Dir nochmals versichern, dass ich zunächst alternative Quellen konsultiert habe. Dazu gehört auch das Datenblatt. Nach erheblichem Denken habe ich mich entschieden, meine Frage hier zu stellen.

Ich möchte Dich bitten, von guten Absichten und gutem Willen auszugehen. Sich in ein Thema einzuarbeiten benötigt viel Zeit und manchmal eben auch Hilfe. Ich denke, dass Du ähnliche Erfahrungen gemacht hast.

Vor diesem Hintergrund sind Versatzstücke, wie "Schau endlich ins Datenblatt." nicht hilfreich. Danke!

Gast #7635780
Lesenswert?

Leonardo schrieb:

Aber wozu löscht man es dann, indem man es auf "1" setzt?

Weil das bei den meisten Flags so ist. Und das wiederum ist notwendig, denn das TWCR Register liegt in einem Bereich, den man nicht Bitweise adressieren kann. Um das Flag zu löschen, müsste man ohne diese Sonderlocke das Register

1
1) lesen
2
2) Wert ändern
3
3) zurück schreiben

Dazwischen könnte ein Hardware-Ereignis auftreten, dass man dabei dann verpasst (Race condition).

Durch die Sonderregel braucht man nicht 3 Maschinen-Befehle sondern nur einen, um das Flag zu löschen.

  1. Flag löschen (= 0b10000000 schreiben)
(Firma: Jasinski) #7635805
Lesenswert?

Leonardo schrieb:

Aber wozu löscht man es dann, indem man es auf "1" setzt?

Warum es so ist, wurde oben schon erwähnt – hängt einfach mit der Integrität des Programmablaufs zusammen, die in bestimmten Situationen die oberste Priorität hat. Das ist übrigens nicht nur bei den AVRs so, sondern wird auch bei vielen anderen µControllern so gelöst und intensiv angewandt, insbesondere bei den STM32 – hier gibt es sogar eine Legende mit Schlüsselwörtern wie beispielsweise „rc_w1” oder „rc_w0”, die einem bei der Registerbetrachtung im Manual sofort auffallen und signalisieren sollen, was und wie genau bei einem Lese- oder Schreibzugriff passiert (im Anhang ein Screenshot). Wie man sehen kann, gibt es auch deutlich mehr Kombinationen und Ausnahmen, die für eine Verwirrung sorgen können – das bei den AVRs ist dagegen eher relativ einfach gestrickt und sehr überschaubar, aber selbstverständlich nicht für jemanden, der die Welt der merkwürdigen Bitsetzung oder -löschung gerade entdeckt und kennenlernen muss.

Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren