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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Peter (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Löschen von BitNummer:
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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (mmvisual)


Bewertung
0 lesenswert
nicht 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 A. K. (prx)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Gutcoder schrieb:
> ...was niemand braucht ... :-[

... ausser beim genannten Bitbanding ...

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


Bewertung
0 lesenswert
nicht 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 A. K. (prx)


Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.