hi,
als Einsteiger beschäftige ich mich gerade mit den GPIOs.
Dazu habe ich folgende Frage:
Um einen Pin zu setzen oder zu löschen gibts ja 3 Möglichkeiten:
1. Berechnung der Bit-Band Adresse des entsprechenden Pins und diesen
direkt setzen (soll am schnellsten gehen)
2. Per Befehl GPIOx->ODR = 00001000;
3. Per BSRR Register
Welche Unterschiede haben die Möglichkeiten 2 und 3....??
Beide greifen auf das ODR zu und setzen / löschen den Pin.
Warum nutzt man nicht immer den Bit-Band Zugriff?
Da der Compiler ja die meiste Arbeit übernimmt ist das zeit- und
codemäßig die schnellste und effektivste Lösung!
Und wofür benötige ich eigentlich 3 Register, um einen vordefinierten
PortPin zu setzen, zu lesen, zu löschen?? Ja ich weiß, dass hat ST so
gemacht, aber ich erkenne keinen Sinn dabei.
Ein normales PortDataRegister hätte doch ausgereicht, um auch
verschiedenste Einstellungen (Input, Output OD, PP) an einem Port zu
realisieren.
Vielen Dank für eure Hilfe.
Heiko
@Moderator: habe den beitrag mit einem anderen Betreff nochmal
eingestellt, war so per Suchen in Betreff nicht auffindbar.
Wenn dann bitte den Beitrag mit "STM32L1xx, ..." löschen und nicht
diesen hier
Wenn man ein einzelnes Bit im ODR setzen will, ohne die anderen zu
verändern dann ist der Zugriff langsam, da man erst das ODR lesen
müsste, den gelesenen Wert ver-odern, dann wieder schreiben müsste.
Deshalb hat ST das BSRR/BRR eingebaut - hier kann das Bit verändert
werden, ohne dass man vorher lesen muss.
Den gleichen Effekt hat auch das Bitbanding, eigentlich bräuchte man
daher das BSRR/BRR nicht. Ich meine aber irgendwo gelesen zu haben, dass
Bitbanding einen Tick langsamer ist, ich selbst benutze immer den
Zugriff über BSRR/BRR.
Ausserdem könnte es auch sein, dass ST einfach die GPIOs vom STM8
übernommen hat und da war das halt damals so realisiert...
> Warum nutzt man nicht immer den Bit-Band Zugriff?
Weil auch der intern einen load-modify-store Zyklus über den Bus fahren
muss. Bei BSRR/BRR brauchts nur einen store-Zyklus auf dem Bus.
Außerdem kann man mit Bit-Band nicht mehrere Bits auf einmal
setzen/löschen.
Heikon schrieb:> hi,> Welche Unterschiede haben die Möglichkeiten 2 und 3....??> Beide greifen auf das ODR zu und setzen / löschen den Pin.>> Warum nutzt man nicht immer den Bit-Band Zugriff?> Da der Compiler ja die meiste Arbeit übernimmt ist das zeit- und> codemäßig die schnellste und effektivste Lösung!>
Der Compiler tut da gar nix, das ist alles hardwaremässig verdrahtet.
> Und wofür benötige ich eigentlich 3 Register, um einen vordefinierten> PortPin zu setzen, zu lesen, zu löschen?? Ja ich weiß, dass hat ST so> gemacht, aber ich erkenne keinen Sinn dabei.
Doch, der Sinn ist der dass wir hier miteinenander sprechen ;-).
> Ein normales PortDataRegister hätte doch ausgereicht, um auch> verschiedenste Einstellungen (Input, Output OD, PP) an einem Port zu> realisieren.>
Stimmt. Aber die verschiedenen Möglichkeiten haben schon ihren Sinn.
Die Unterschiede hat vorher auch schon jemand erklärt.
In den meisten Fällen wird ein Halbleiterhersteller die Periperhieblöcke
einfach von einer Vorgängergeneration oder von einem anderen Typ
übernehmen, was äusserst sinnvoll ist, auch speziell für die Anwender,
die bereits Software für einen verwandten Controller haben und sich eher
an einer bugfreien Hardware freuen dürfen, als wenn immer
alles neu wiedererfunden würde.
Bit-banding ist eine Spezialität des M3. Kann Vor- und Nachteile
bez. Portabilität haben. Ich würde es eher nicht verwenden,
da man mit Verwendung der Register eher im "Kontext" bleibt, d.h
für die Initialisierung des betreffenden I/O Blocks muss man
sowieso die Register beschreiben, warum dann nicht auch für die
Ein/Ausgabe selbst. Mit BB würde ich sagen, kommt man eher
durch den Hintereingang. Aber letztlich ist das Ganze Geschmackssache.
Nachteil ist halt, das es für Neulinge jetzt halt 10-mal solange
dauert, die verschiedenen Möglichkeiten zu erfassen.
ZiZi
> Vielen Dank für eure Hilfe.>> Heiko>> @Moderator: habe den beitrag mit einem anderen Betreff nochmal> eingestellt, war so per Suchen in Betreff nicht auffindbar.> Wenn dann bitte den Beitrag mit "STM32L1xx, ..." löschen und nicht> diesen hier
ZiZi schrieb:> Bit-banding ist eine Spezialität des M3. Kann Vor- und Nachteile> bez. Portabilität haben. Ich würde es eher nicht verwenden,> da man mit Verwendung der Register eher im "Kontext" bleibt,
Bei I/O-Portbits ist es unnötig, dank BSRR/BRR.
In anderen Fällen kann BB als ununterbrechbare Bitmanipulation einen
entscheidenden Vorteil gegenüber explizitem read-modify-write haben.
Beispielsweise wenn ein Register im Hauptprogramm und in einem
Interrupt-Handler manipuliert wird.
Hannes S. schrieb:> Den gleichen Effekt hat auch das Bitbanding, eigentlich bräuchte man> daher das BSRR/BRR nicht. Ich meine aber irgendwo gelesen zu haben, dass> Bitbanding einen Tick langsamer ist, ich selbst benutze immer den> Zugriff über BSRR/BRR.
Man kann aber über Bitbanding gleichzeitg setzen und löschen, z.B. die 4
IO-Pins für den Datenbus zum LCD.
Mit BSRR/BRR muß man erst die 0- und 1-Bits separieren und die 0-Bits
invertieren.
Peter
Neben den Gründen, die hier schon genannt wurden gibt es noch weitere,
deren Existenzberechtigung im Anwendungsbereich des CortexM3 liegt.
Es ist eine CPU, die speziell für machine-control geschaffen wurde.
So bietet das BSRR die Möglichkeit, dass man zuerst einmal in mehreren
Zyklen eine neue Konfiguration eines GPIO Ports zusammen stellt, in dem
man die zu setzenden und zu löschenden Bits in der entsprechenden Hälfte
dieses Registers vorbereitet. Dann schreibt man das BSRR Register und
alle bits werden sychron umgeschaltet. Das ist gerade dann interessant,
wenn man andere Hardware ansprechen oder irgend einen Bus emulieren
will.
Eine Frage war noch, warum ein GPIO für ein Signal verschieden Bits hat,
die seinen Zustand repräsentieren. Es gibt einmal ein Register ODR, das
sagt, wie ein Pin gesetzt ist, also wie die Software ihn per Zugriff auf
ODR,BSRR,BRR eingestellt hat. Dann gibt es noch das INR, dass den
tatsächlichen Zustand des Signals wiedergibt. Das hat durchaus Sinn,
denn man kann einen Pin auch als OD (open Drain) konfigurieren, also so,
dass er nuch aktiv nach GND ziehen kann, aber nicht nach VCC. Damit kann
man den Pin auf 1 setzen, aber eine angeschlossene Peripherie darf ihn
auf 0 halten, z.B. bis sie so weit ist, weitere Daten zu verarbeiten.
I2C ist ein Bus der auf diesem Prinzip basiert.
Oft ist es nicht der komplette Zugriff auf einen GPIO, der von einem
Interrupt so gestört werden könnte, dass etwas daran angeschlossenes
nicht mehr zuverlässig funktioniert, sondern das Timing beim Zugriff
selbst. Es ist, dank BSRR nicht mehr erforderlich extra die Interrupts
zu sperren um eine synchrone Änderung des GPIO zu erreichen.
Gruß, Ulrich
Peter Dannegger schrieb:> Man kann aber über Bitbanding gleichzeitg setzen und löschen, z.B. die 4> IO-Pins für den Datenbus zum LCD.
Nur Bit für Bit einzeln.
> Mit BSRR/BRR muß man erst die 0- und 1-Bits separieren und die 0-Bits> invertieren.
Das BSRR kann Bits sowohl setzen als auch löschen, wobei setzen gewinnt
wenn beides für das gleiche Bit verlangt wird. Damit lassen sich über
port->BSRR = 0x000F0000 | data;
alle 4 Datenbits auf den Portbits 0..3 gleichzeitig setzen.
wenn ich aber zwei BSRR befehle mache, einen für GPIOE_Pin1 und danach
ein BSRR auf GPIOE_Pin2
dann leuchten keine der beiden LED's
wenn ich aber nur einen mache dann leuchte die entsprechende LED.
woran liegt das ?