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!
Leonardo schrieb:> Also beträgt TWINT "1", wenn START gesendet wurde.
Ja
> Aber wozu> löscht man> es dann, indem man es auf "1" setzt?
Damit es von der nächsten Aktion wieder gesetzt werden kann.
> Bzw, wann beträgt es "0"?
Nachdem man es gelöscht hat.
Oliver
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.
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?
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.
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
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!
Leonardo schrieb:> 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.
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)
Leonardo schrieb:> Also schreibe ich eine "1" und dann steht eine "0" in TWINT.
TWINT ist kein Register-Bit, was geschrieben wird. Vielmehr muss man es
als RS-Flipflop sehen und das Schreiben der "1" betätigt dessen
Reset-Eingang.
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.