Wie funktioniert das BSRR-Register?

Auf den GPIOs einiger ARM-basierter Mikrocontroller erhalten Sie ein Register, in BSRRdas Sie schreiben können, um atomare Änderungen in einem Ausgangsregister eines Ports durchzuführen.

Um zum Beispiel Port A Bit 5auf a einzustellen, 1tun Sie es einfachGPIOA->BSRR = (1<<5)

Dadurch wird das Problem der Unteilbarkeit verringert, sodass Sie keine Lese-Änderungs-Schreib-Sequenz ausführen müssen. Ohne die BSRR müsstest du auskommen GPIOA->ODR |= (1<<5).

Wie funktioniert das BSRR-Register unter der Haube? Klärt es sich auf, dass beim nächsten Mal, wenn man ein Bit einstellen will, nicht das vorherige Bit noch herumliegt.

Wenn ich Bit 2 setzen und später Bit 6 setzen wollte, kann ich das zuerst tun GPIOA->BSRR = (1<<2)und dann später, GPIOA->BSRR = (1<<6)aber wird Bit 2 nicht immer noch von meinem vorherigen Anruf gesetzt?

GPIO (und was auch immer für IO) ist kein Teil der ARM-Architektur, sondern ein Teil des spezifischen Mikrocontrollers, der möglicherweise um den ARM-Kern herum aufgebaut ist.
@EugenSch. Aber alle modernen ARM-Kerne haben das BSRR-Register, daher ist es sinnvoller, nach dem ARM zu fragen
@Taako, das ist die Implementierung definiert. Die STM32-GPIOs haben ein BSRR-Register, die LPC4350-Reihe von Cortex M4s von NXP jedoch nicht. Der ARM ist nur die CPU, der Rest der peripheren Implementierung ist vom Hersteller definiert.

Antworten (1)

Es gibt eine Art Lesen-Ändern-Schreiben, aber es erfolgt in Logik/Hardware ohne Zeit zwischen dem Lesen und dem Schreiben. Die Aussage in Verilog wäre:

GPIOA <= GPIOA | cpu_write_data;

Dies erzeugt eine Logik, bei der sich vor dem Register ein ODER-Gatter befindet und die neuen Daten mit den alten Daten ODER-verknüpft und im Register gespeichert werden. Die Datenbits, die Sie schreiben und die SET (hoch) sind, erzeugen nur an diesen Stellen eine 1. Alle Bits, die Sie schreiben und die klar (niedrig) sind, bleiben unverändert. Wenn das Bit gesetzt war, bleibt es gesetzt, wenn das Bit gelöscht war, bleibt es gelöscht.

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Äquivalent können Sie Bits löschen, indem Sie Folgendes verwenden:

GPIOA <= GPIOA & ~cpu_write_data;

Die Datenbits, die Sie schreiben und die SET (hoch) sind, erzeugen nur an diesen Stellen eine 0. Alle anderen Bits bleiben unverändert.

Es wird etwas komplexer, all diese Bit-Set- und Bit-Clear-Operationen parallel auf demselben Register zu implementieren, aber das ist nur eine Frage von mehr Logik (Multiplexer, Adressdecoder usw.).

Macht viel Sinn! Aber bestätigt das Register nur 1einmal die Logik, damit das gesetzte / zurückgesetzte Bit nicht erhalten bleibt, nachdem es die Aktion ausgeführt hat?
Die Schaltung ist ein Beispiel. In Wirklichkeit hätten Sie entweder eine Freigabe im Register oder eine Gated Clock oder einen Feedback-MUX. In allen Fällen sind diese nur während des einen Taktzyklus aktiv, in dem die CPU die Daten in dieses Register schreibt. Somit bleibt das Register außerhalb dieser Zeit unverändert.