Hallo! Versuche mich gerade nach dem AVR in die ARM-Welt einzuarbeiten. Habe mir dazu das günstige STM32F4-Discovery Board zugelegt. Hätte da jetzt mal zwei Fragen. 1. Kann man wie beim AVR Variablen(const) im FLASH ablegen und zur Laufzeit auslesen? Hintergrund ist es RAM zu sparen das ich für andere Zwecke bräuchte. 2. Bei der GPIO Konfiguration gibt es das "GPIO port bit set/reset register (GPIOx_BSRR)" und das "GPIO port output data register (GPIOx_ODR)". Eigentlich würde doch eins von den beiden reichen?! Gibt es ein Grund warum ST dort diese zwei Register "angelegt" hat? Viele Grüße Deepdiver99
deep diver99 schrieb: > Hallo! > > Versuche mich gerade nach dem AVR in die ARM-Welt einzuarbeiten. Habe > mir dazu das günstige STM32F4-Discovery Board zugelegt. Hätte da jetzt > mal zwei Fragen. > > 1. Kann man wie beim AVR Variablen(const) im FLASH ablegen und zur > Laufzeit auslesen? Hintergrund ist es RAM zu sparen das ich für andere > Zwecke bräuchte. Problemlos. > 2. Bei der GPIO Konfiguration gibt es das "GPIO port bit set/reset > register (GPIOx_BSRR)" und das "GPIO port output data register > (GPIOx_ODR)". Eigentlich würde doch eins von den beiden reichen?! Gibt > es ein Grund warum ST dort diese zwei Register "angelegt" hat? Atomic operation. Steht aber alles im RM
Und wie geht's mit dem dem Flash? Das "Note: For atomic bit set/reset, the ODR bits can be individually set and reset by writing to the GPIOx_BSRR register (x = A..I/)." hab ich gelesen. Trotzdem leuchtet mir nicht ein warum 2 Register dafür da sind, wenn man mit beiden das gleiche Ergebnis erreichen kann.
1) static const 2) Each I/O port bit is freely programmable, however the I/O port registers have to be accessed as 32-bit words, half-words or bytes. The purpose of the GPIOx_BSRR register is to allow atomic read/modify accesses to any of the GPIO registers. In this way, there is no risk of an IRQ occurring between the read and the modify access.
Also ist der Zugriff über das BSRR-Register Interruptsicher :-). Danke für deine Hilfe Norbert!
Noch ein Frage :-) Gibt es beim STM32F4 ein Input Capture Timer wie beim AVR mit dem ich die Takte zwischen zwei Signale einer externen Quelle messen kann? Bin aus dem ReferenzManual nicht so richtig schlau geworden.
deep diver99 schrieb: > Noch ein Frage :-) > > Gibt es beim STM32F4 ein Input Capture Timer wie beim AVR mit dem ich > die Takte zwischen zwei Signale einer externen Quelle messen kann? > Bin aus dem ReferenzManual nicht so richtig schlau geworden. Klar, gibt es... Sogar noch besser als beim AVR, der STM32F4 kann beim capture event einen DMA Request erzeugen und den Counter ohne CPU Intervention/Interrupt lesen und im Speicher ablegen. Und das kann er sauschnell mehrmals hintereinander. Hab's noch nicht gebraucht, aber mein Bauchgefühl sagt mir locker im zweistelligen MHz Bereich. vgl. RM0090 (Doc ID 018909 Rev 4) S.371ff - 14.3.6 Input capture mode
Geht es auch ohne DMA so wie beim AVR das der Zähler dann in ein extra Register(am besten 32Bit :-) ) geschrieben wird? Das mit DMA ist mir noch ne Nummer zu groß für den Anfang. Will jetzt erst mal eins zu eins das AVR Board auf das ARM übertragen.
Ja, geht wie beim AVR auch ohne DMA. Einfach nach dem capture event das Counter Register auslesen. Ist aber nur 16bit ohne Tricks. ;-)
So hatte ich das auch schon raus gelesen. Ist denn das Counter Register auch das Register was hoch gezählt wird? Das wäre nämlich ungünstig da ich dann ja nicht die genaue Taktanzahl bekomme durch den zeitlichen Versatz bei der Eventauslösung. Bei den 32Bit Timern geht das auch nicht? Und mit DMA? Würde mir gerne den Overflow Interrupt sparen :-).
Ne, hab' mich unpräzise ausgedrückt. Der jeweilige Zählerstand wird bei einem capture event in das entsprechende capture/compare Register transferiert und bleibt dort stehen bis zum nächsten capture event.
Ach so. Dann probiere ich mich heute Abend mal. Vielen Dank, würde mich gerne noch mal melden wenn ich nicht weiter komme :-)
deep diver99 (deepdiver99) > 2. Bei der GPIO Konfiguration gibt es das "GPIO port bit set/reset > register (GPIOx_BSRR)" und das "GPIO port output data register > (GPIOx_ODR)". Eigentlich würde doch eins von den beiden reichen?! Gibt > es ein Grund warum ST dort diese zwei Register "angelegt" hat? Sinngemäß würde ich sagen, daß es das gleiche ist; trotzdem macht sowas niemand ohne Grund. Vermutlich geht's wie üblich um den durch das Schreiben gelatchte Bit (GPIO port output data register) einerseits und um den echten Port-Zustand (GPIO port bit set/reset register (GPIOx_BSRR))andererseits. Manchmal ist der kognitive Zusammenhang den Chip-Designer im Kopf haben für SW-Schreiber nicht auf den ersten Blick sichtbar;-) Bin aber kein Experte für STM, ich kenn' nur AT91SAM.
deep diver99 schrieb: > 2. Bei der GPIO Konfiguration gibt es das "GPIO port bit set/reset > register (GPIOx_BSRR)" und das "GPIO port output data register > (GPIOx_ODR)". Eigentlich würde doch eins von den beiden reichen?! Gibt > es ein Grund warum ST dort diese zwei Register "angelegt" hat? Der Hauptgrund wird wohl sein dass du so echte "bit set" und "bit reset" Funktionen hast . Stell dir mal folgendes vor, an deinm Port sind 16 LEDs angeschlossen. Du willst nun LED0, LED1 ansteuern GPIOx_ODR = 0x0003; // Funktioniert wunder bar. Nun noch LED15 dazu... GPIOx_ODR = 0x8000; // Uupps nun leuchtet aber nur noch LED15 Also macht man üblicherweise: GPIOx_ODR |= 0x8000; // LED15 ansteurn, restliche LEDs belassen Dies wird "read modify write" "rmw" genannt und dauert aber länger da nun gelesen, verodert und geschrieben werden muss Hässlich wirds nun wenn dein TimerIrq regelmässig LED8 ansteuert und der IRq genau auftritt wenn der Read Part des "rmw" abgeschlossen ist. Das verodern bassiert dann auf alten Daten und die werden mit write geschrieben. Die LED8 aus dem Irq leuchtet also nicht. Die "rmw" sequenz ist also nicht "atomic". Desshalb wird folgendes häufig angewendet: Disable Irq GPIOx_ODR |= 0x8000; // LED15 ansteurn, restliche LEDs belassen Enable Irq Und nun wird das ganze nochmals länger und langsamer... Moderne uC wie die STM32 bieten aber bessere Möglichkeiten, es können einzelne bits an den outputports gesetzt/gelöscht werden ohne die anderen zu beinflussen! Du kannst also GPIOx_BSRR = 0x0003; // LED0, LED1 an GPIOx_BSRR = 0x8000; // LED15 noch dazu, LED0, LED1 beleiben an Dein TimerIrq würde GPIOx_BSRR = 0x0100; // LED8 an Löschen kannst du auf zwei verschiedne Arten GPIOx_BSRR = 0x00030000; // LED0, LED1 löschen, vorsicht muss im high word stenen GPIOx_BRR = 0x8000; // LED15 löschen Das geht aber auch kombiniert GPIOx_BSRR = 0x80000003; // LED15 löschen, LED0 LED1 an Fazit: Es gibt weniger Befehle und IO Operationen sind vereifacht. Die Cortex M3/4 können das auch für das RAM machen, nennt sich "bit banding". Es gibt eine "Bitband Are"im Adressraum, welche das ganze interne SRAM bitweise ansprechen lässt. Somit lassen sich bit set bzw. bit clear befehle auf alle Variablen anwenden. Cheers
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.