Forum: Mikrocontroller und Digitale Elektronik STM32 - Bit im Register setzen oder löschen


von Peter (Gast)


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

von Jim M. (turboj)


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.

von Peter (Gast)


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

von Gutcoder (Gast)


Lesenswert?

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

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Lese mal hier im Artikel ARM Bitbanding

Der ARM kann einzelne Bits eines Registers direkt lesen und schreiben 
indem spezielle Adressen genutzt werden.

von (prx) A. K. (prx)


Lesenswert?

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.

von Gutcoder (Gast)


Lesenswert?

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 ... :-[

von (prx) A. K. (prx)


Lesenswert?

Gutcoder schrieb:
> ...was niemand braucht ... :-[

... ausser beim genannten Bitbanding ...

: Bearbeitet durch User
von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


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

von (prx) A. K. (prx)


Lesenswert?

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
Noch kein Account? Hier anmelden.