Hallo, ich arbeite mich gerade etwas in den USB eines STM32 ein. Dabei sind auch Interrupt Register zu bearbeiten. Folgendes sagt das Datenblatt dazu: >>To avoid spurious clearing of some bits, it is recommended to clear them >>with a load instruction where all bits which must not be altered are >>written with 1, and all bits to be cleared are written with ‘0 (these bits >>can only be cleared by software). Read-modify-write cycles should be >>avoided because between the read and the write operations another bit >>could be set by the hardware and the next write will clear it before the >>microprocessor has the time to serve the event. Wie muss ich das nun konkret machen, dass hier keine Bits verloren gehen? Gruß Peter
Löschen von BitNummer:
1 | USB_REGISTER_x = ~(1UL << BitNummer); |
Das erzeugt für alle anderen Bits die geforderte "1", was offenbar "don't change" bedeutet. Cleverere Implementationen nehmen nicht die "0" sondern die "1" Bits zum Löschen eines Registers, aber da hat der Implementer wohl gepennt.
Vielen Dank für Deinen Hinweis! Das hat mich auf die richtige Fährte geführt. Die ganzen Bits im Interrupt Register sind als rc_w0 definiert: >>read/clear (rc_w0) Software can read as well as clear this bit by writing >>0. Writing ‘1’ has no effect on the bit value. D.h., das Schreiben einer 1 ändert den Wert nicht. Wenn der Interrupt also zuvor schon nicht gesetzt war, dann bleibt das auch so. Genau was Du gesagt hast. Gruß Peter
Jim Meba schrieb: > (1UL << BitNummer) Achtung, diesen Shift Schei... macht nur Atmel! Alle anderen machen es vernünftig und definieren richtige Werte: 0x00000001, 0x00000002, 0x00000004, ... An der Schreibweise erkennt man die avr Jünger. :-D
Lese mal hier im Artikel ARM Bitbanding Der ARM kann einzelne Bits eines Registers direkt lesen und schreiben indem spezielle Adressen genutzt werden.
Gutcoder schrieb: > An der Schreibweise erkennt man die avr Jünger. :-D Und jene, die verstanden haben, dass es wesentlich einfacher ist, aus einer Bitnummer die Maske zu machen, als aus einer Bitmaske die Nummer.
A. K. schrieb: > Und jene, die verstanden haben, dass es wesentlich einfacher ist, aus > einer Bitnummer die Maske zu machen, als aus einer Bitmaske die Nummer. ...was niemand braucht ... :-[
Gutcoder schrieb: > ...was niemand braucht ... :-[ ... ausser beim genannten Bitbanding ...
:
Bearbeitet durch User
A. K. schrieb: > Gutcoder schrieb: >> An der Schreibweise erkennt man die avr Jünger. :-D > > Und jene, die verstanden haben, dass es wesentlich einfacher ist, aus > einer Bitnummer die Maske zu machen, als aus einer Bitmaske die Nummer. Was ist an folgenden Makros kompliziert? /*! * \brief Get the Bit position index of the highest bit from a bit value * */ #define _BI2(arg) (((arg) & 0x00000002) ? 1: 0) #define _BI4(arg) (((arg) & 0x0000000c) ? ( _BI2(arg>> 2) + 2) : _BI2(arg)) #define _BI8(arg) (((arg) & 0x000000f0) ? ( _BI4(arg>> 4) + 4) : _BI4(arg)) #define _BI16(arg) (((arg) & 0x0000ff00) ? ( _BI8(arg>> 8) + 8) : _BI8(arg)) #if defined __builtin_clz #define _BI32(arg) (31 - __builtin_clz(arg)) #else #define _BI32(arg) (((arg) & 0xffff0000) ? (_BI16(arg>>16) + 16) : _BI16(arg)) #endif
Uwe Bonnes schrieb: > Was ist an folgenden Makros kompliziert? Abgesehen von der GCC-spezifischen CLZ-Variante würde ich die schon rein optisch als etwas komplizierter einschätzen als (1<<n). Insbesondere wenn es keine Konstante ist (z.B. als Parameter).
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.