STM32 - Bit im Register setzen oder löschen

Gast #4066120
Lesenswert?

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
#4066862
Lesenswert?

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.
Gast #4066897
Lesenswert?

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
(Firma: TU Darmstadt) #4067945
Lesenswert?

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

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