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!
Das Datenblatt habe ich an den betreffenden Stellen als Referenz genutzt. Daher ist deine Unterstellung unzutreffend.
Empfindest du es als störend, wenn unerfahrene Personen sich bei erfahrenen Personen nach Hilfe umsehen?
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.
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!
Vor diesem Hintergrund sind Versatzstücke, wie "Schau endlich ins
Datenblatt." nicht hilfreich.
Um zu beweisen dass du "versucht" hast das Datenblatt zu lesen
und zu verstehen hättest du ja mal einen Auszug davon hier
zitieren können und darauf bezogen gefragt was du nicht
verstehst.
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.
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.