dieses querdenken scheint bei den avrs üblich zu sein. gelegentlich lieest man was im datenbaltt und denkt nur "wtf?" aber dann wenn mans brraucht scheint es plötzlich ne echt gute sache zu sein
Whow (oder so ähnlich),
dann macht ja auch der von damaltor (extra für mich ) übersetzte Text tatsächlich Sinn bei dieser Sorte von Registern, sie wirklich mit = zu 'überschreiben' so wie radbruch es sagt.
(Ganz schönes Querdenken!)
Lieber Asuro programieren als arbeiten gehen.
dieses querdenken scheint bei den avrs üblich zu sein. gelegentlich lieest man was im datenbaltt und denkt nur "wtf?" aber dann wenn mans brraucht scheint es plötzlich ne echt gute sache zu sein
Hallo
Das habe ich bei meinem Einstieg in die echte AVR-Programmierung gelernt. Natürlich hier im RN-Forum:
https://www.roboternetz.de/phpBB2/ze...=295989#295989
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Es geht eben nichts über diese Forum.
Lieber Asuro programieren als arbeiten gehen.
Hi Sternthaler,
Tolllll!ja, ich traue mich noch ...
Danke für die Rückmeldung! Aber Ihr wisst ja, so'n Newby weiß 'halt noch nicht alles ... !Auch ich konnte aus beiden Beiträgen downloaden.
Nun, zu mehr Erstem:
Zu *1*:Note:
3. Some of the Status Flags are cleared by writing a logical one to them. *1*
Note that the CBI and SBI instructions will operate on all bits in the I/O Register,
writing a one back into any flag read as set, thus clearing the flag. *2*
The CBI and SBI instructions work with registers 0x00 to 0x1F only.
---------
Hier hört mein Englisch tatsächlich auf. Die weitere Erklärung von CBI und SBI mit 'read as set' kann ich tatsächlich nicht mehr umsetzen.
Verstehe ICH so: Normal ist, dass "Clear" *zurücksetzen auf Null bedeutet*, aber es gibt auch
den Fall, dass "Zurücksetzen" einfach *Schreiben einer Eins* bedeutet! (Die Du dann auch als solche lesen kannst: 'read as set'!)
Zu *2*:
CBI und SBI sind Maschinesprache-Befehle Clear - bzw. Set Bit im unteren Bereich (0x00 to 0x1F only) der IO-Register!
Zu *1* habe ich mein kleines Prog. ergänzt und lese das IO-Register "UCSRB" vor und nach dem "Clearen" aus! (Es muss natürlich heißen: "sollte", da ich das Prog. noch nicht testen kann!)
cu HelmutCode:... void b2h(byte d) { byte h=(d/16)+0x30; if(h>0x39) h+=7; SerWrite(h); h=(d & 0x0f)+0x30; if(h>0x39) h+=7; SerWrite(h); } .... b2h(UCSRA); SerWrite(' '); UCSRA |= 0x40; // 'clear' transmitter flag Sleep(0xFF); b2h(UCSRA); ....
Nachtrag:
Sorry, ich habe das Forum nicht besucht und dann gepostet, sondern verkehrt herum! !
So muss ich doch noch "nachtarocken"!
zu @damaltor:
hi damaltor,
Du hast das *1* "fast" besser beschrieben, als ich!
Das mit dem gelöschten Flag, wusste ich leider (noch!) nicht!
Aber mein kleines Prog. müsste das ja auch zeigen! (Ich will's morgen testen!)
zu @radbruch:
hi mic,
Deine Behauptung mit "=" kann ICH _nicht_teilen_: !
Wenn Du mit "=" eine Zuweisung machst, so wird die Variable mit diesem Wert belegt!
(Außer bei CBI, ..., also den Bit-Operatoren! Aber das schreibst man je in Assambler anders!)
Wenn man nun "|=" meint, so heißt das, dass die (vordere) Variable mit dem hinteren Wert
"geodert wird". Und wenn da nur ein Bit gesetzt ist, dann wird nur an _dieser_Stelle_ ein
Bit gesetzt! (Bei mehreren natürlich eben diese.)
"&= ~" ist das Gegentum dazu: hier löscht Du das im hinteren Teil als "Eins" gesetzte Bit,
bzw. mehrere!
cu Helmut
PS: bei b2h() (also Byte/Char to hex) sollte/könnte man noch "0x" davor senden.
geclearte bits sind null, ich habe es versucht an der USART auszulesen. eins geschrieben, nul,l gelesen.
das READ AS SET hat ne andere bedeutung (die eigentlich verdammt wichtig ist:
benutzt man CBI oder SBI, muss man sehr vorsichtig sein. diese befehle setzen nämlich nicht wirklih nur das eine bit, sondern:
lesen das register
verknüpfen es mit ODER mit dem bit
schreiben das register zurück
dadurch werden die interrupt-flags gelöscht!!!
"Note that the CBI and SBI instructions will operate on all bits in the I/O Register, " -> beachten sie, dass CBI und SBI auf alle bits des registers wirken.
"writing a one back" -> schreiben eine 1 zurück
"into any flag read as set" -> in jedes flag, das als gesetzt gelesen wurde
"thus, clearing the flag" -> und dadurch wird das flag gelöscht
das = ist schon richtig. sagen wir mal, wir haben ein status register, in dem 8 interrupt-flags drin sind:
0b00110101
4 flags sind aktiviert. wir wollen jetzt das bit 4, also die zweite eins von links löschen.
möglichkeit 1:
REG |= 0x10;
was ja das gelice bedeutet wie
REG = REG | 0x10;
also REG = 0b00110101 | 0b00010000
also REG = 0b00110101
jetzt werden 4 einsen geschrieben. und da eine 1 ja zum löschen den interrupt-flags verwendet wird, werden alle 4 interrupt-flags gelöscht, obwohl wir nur eines wollten...
zweite möglichkeit:
REG = 0x10;
also
REG = 0b00010000;
es wird nur eine 1 geschrieben. das bit wird gelöscht, alle anderen bits bleiben unverändert.
Hi damaltor,
danke für Deine prompte Antwort!
Allerdings redet (fast) jeder von was anderem; Gott-sei-Dank habe _ich's_jetzt_ kapiert!!
Manchmal ist halt so'ne Leitung ziemlich lang!!
1. Das, was ich gepostet habe, bezieht sich ALLGEMEIN auf "|=", "=" und "&= ~", also auf ganz normale Variable!
2. Das was Du und wahrscheinlich auch mic weiter oben meintet, geht in Richtung "IRQ-Flags"! (Denn nur die kann man mit 'ner Eins zurücksetzen! Allerdings ist bei uns hier von ISR sowohl beim Senden, als auch beim Empfangen (noch!?) keine Anwendung da, oder? Folglich dient die Abfrage nur beim Pollen der Antwort auf "ist TX fertig? ja oder nein". Es ist meiner Meinung nach völlig wurscht, ob wir das Flag am Anfang oder am Ende der Funktion "Senden" löschen; und zwar so wie DU richtig geschrieben hast: durch Schreiben einer Eins z.Bsp. mit "="! *)
Wenn wir den Sender wieder ausschalten wollen, dann ist empfehlenswert (übrigens so, wie von mir vorgeschlagen! ! ) TXC am Anfang sicherheitshalber zu löschen und am Ende nachgucken, ob TXC gesetzt ist und dann erst den Sender aus-/abschalten!
*) Allerdings NUR im Falle, wenn mindestens ein Bit in UCSRA der Nummer 1 und/oder #0 (=U2X, MPCM) gesetzt wäre, ist Dein Vorschlag mit "=" falsch, denn dann setzt Du diese Bits AUCH auf Null!
So jetzt zum Fall UCSRA (= USART Control and Status Register A):
Auf Seite 154 steht, dass nur das Flag TXC (=USART Transmit Complete, Bit #6) von den anwesenden IRQ-Flags les- UND schreibbar ist! (D.h., dass man die anderen {IRQ-}Bits #7, 5 - 2!) durch Schreiben NICHT verändern kann!
==>> Dem zur Folge ist HIER "UCSRA |= 0x40;" bzw. "UCSRA |= (1<<TXC);" AUCH richtig!!
Ob der Maschinenbefehl "CBI" hier geht, weiß ich nicht, da ich bisher noch nicht herausgebracht habe, an welcher Position im IO-Bereich sich "UCSRA" befindet, da wie Du ja richtig geschrieben hast, das nur in der unteren Hälfte geht!
So jetzt zur Initialisierung von TX:
Auf Seite 139 ist ÜBERHAUPT KEINE Rede von TXC! (Also weder 'ne Null noch 'ne Eins werden da "offiziell als Bsp." gesetzt! Allerdings steht auf Seite 154, dass man - m.M. nach! - TXC trotzdem _sicherheitshalber_ clearen kann! (Was wir ja machen und was jetzt _neu_ _zum_Ausschalten_ wirklich nötig ist! Früher musste/brauchte man da auf TXC nicht warten! Wenn man's trotzdem gemacht hat, war es sicher nicht FALSCH, jedoch UNNÖTIG!)
... nun zu Deinem Statement von CBI:
Lt. schlauer Beschreibung "Instruction Set" steht auf Seite 48: "Clears an specified bit in an IO Register. ..." Das mit "geODERt" gilt hier nicht!
Du / Ihr habt das möglicherweise mit CBR verbuxelt! Denn da wird - allerdings nur in einem Rd-Register, also noch weiter vorne in dem Speicher als bei IO-Regs! - mit dem Kehrwert "geUNDet"!
So, jetzt habe ich (und hoffentlich auch alle anderen Leser!) wieder 'mal was gelernt!
cu Helmut
wenn man den sender abschaltet, wird...
zuerst das noch zu sendende zeichen abgeschickt
dann das zeichen was gerade im UDR ist, eingeschobden und auch noch abgeschickt, falls vorhanden
und dann erst der sender abgeschaltet. ist also recht risikofrei.
txc ist zum ersten dazu da um zu prüfen, ob der transfer fertig ist. deshalb sollte man es besser VOR der übertragung löschen =)
ausserdem wird, wenn dieses bit UND das interrut bit aktiv sind, der TX_READY interrupt ausgelöst.
das mit CBI und SBI habe ich auch gelesen, ich habe nur den text übersetzt wie er da steht. und da steht, dass man aufpassen soll da alle bits des registers mit ihrem eigenen wert beschrieben werden - und dadurch IRQ-flags gelöscht werden. hier nochmal:
"Note that the CBI and SBI instructions will operate on all bits in the I/O Register, " -> beachten sie, dass CBI und SBI auf alle bits des registers wirken.
"writing a one back" -> schreiben eine 1 zurück
"into any flag read as set" -> in jedes flag, das als gesetzt gelesen wurde
"thus, clearing the flag" -> und dadurch wird das flag gelöscht
Hallo zusammen.
Zum Thema mit dem TXC-Bit bzw. mit der Form vom clearen.
Ich hatte am Sonntag einen Kumpel gefragt, der in seiner Abteilung genau mit diesen AVR's beruflich schon seit Jahren arbeitet. (Was man nicht alles so erfährt bei 2 bis 15 Bier!)
Heute morgen hatte er mal kurz angerufen und mir mitgeteilt, dass es tatsächlich so ist, wenn eine *1* auf das Bit geschrieben wird, dass dieses Bit auf *0* gesetzt wird, und so gelesen wird.
damaltor's Antwort zu diesem Thema wird durch 'Profis' (Siemens) bestätigt.
@damaltor
Woher hast du die Info, dass der Sender auf alle Fälle noch die Bytes aus dem internen Schieberegister UND aus dem UDE noch sendet?
Bleibt die CPU dann an dieser Stelle "UCSRB = Nicht mehr senden" stehen, bis alles gesendet wurde?
Lieber Asuro programieren als arbeiten gehen.
nein, der prozessor arbeitet weiter. das bit wird bei nächster gelegenheit im hintergrund gecleared.
Datenblatt Seite 142:
"The disabling of the Transmitter (setting the TXEN to zero) will not become effective
until ongoing and pending transmissions are completed (i.e., when the Transmit Shift
Register and Transmit Buffer Register do not contain data to be transmitted). When dis-
abled, the Transmitter will no longer override the TxD pin.
"
Lesezeichen