Liebes Forum,
ich habe ein STM32F407V Discovery Board und möchte an einen Ausgangspin
möglichst schnell togglen. An sich kein großes Ding; gibt ja haufenweise
Anleitungen im Internet. Doch bei mir will die Frequenz am Ausgang nicht
ansatzweise an die theoretischen 100MHz herankommen. Hier mein minimaler
Code:
1
#define HSE_VALUE ((uint32_t)8000000) //externer kristall mit 8MHz
Ich habe zuvor folgende Schritte (
http://clockspeeds.blogspot.de/2013/01/stm32f4-discovery-clock-frequency.html
) durchgeführt. Denn viele Seiten empfehlen ja, den HSE-Wert uÄ. zu
ändern um tatsächlich 168MHz zu erreichen...
Das Signal am Ausgangspin ist zwar da, allerdings mit lächerlichen
768kHz. Was mache ich falsch?
Vielen lieben Dank für eure Hilfe!
Sebastian
Also 168 MHz erreichst du nie an normalen IOs. Es geht glaube ich bei
einem speziellen, den man so einstellen kann dass er die CPU-Clock
ausgibt.
Die anderen sind limitiert auf die APB-Bus Geschwindigkeit, die ist
abhängig vom Code bzw. der Clock-System konfiguration.
Man muss halt mal schauen, was da an Assembler-Code für die Schleife
ausgespuckt wird. Dann wird man recht schnell einsehen, dass da nix
schnelles bei rauskommt...
Der AHB läuft maximal mit 168 MHz, eine Store-Operation braucht 2 Takte,
also kann man maximal mit 84 MHz Togglen, bzw Frequenzen mit 42MHz
ausgeben. Alle soundsoviel Zyklen brauchts aber 1 Takt mehr, denn
irgendwann muss man ja einen Schleifen-Rücksprung haben.
So etwas erreicht man aber nicht mit der Funktion GPIO_ToggleBits,
sondern da muss man schön von Hand Assembler schreiben.
Sinnvoll ist das natürlich nicht, wenn man Daten seriell rausgeben will
verwendet man die SPI/USART/I²C/... Peripherie, wenn man Signalformen
machen will die Timer (+ DMA).
Vielen Dank für die vielen schnellen Antworten. :) Ich weiß schon, dass
ich keine 168MHz am Ausgang kriegen werde... Es geht mir nur um die
Größenordnung.
Ein Wert im zweistelligen Megahertz-Bereich sollte schon möglich sein,
aber davon bin ich aus einem Grund (den ich nicht kenne) weit entfernt
und ich dachte jemand sieht vielleicht am Code meinen Fehler.
Bin weiterhin für alle Tipps dankbar
Sebastian Adler schrieb:> und ich dachte jemand sieht vielleicht am Code meinen Fehler.
Wie gesagt, ein C-Funktionsaufruf + Bitoperationen in der Funktion pro
Bit-Toggle senkt die Frequenz drastisch. Versuch direkte
Register-Zugriffe oder gleich Assembler.
>So etwas erreicht man aber nicht mit der Funktion GPIO_ToggleBits,
Du könntest SPI1 mit DMA betreiben. Die Clockleitung
gibt dir dann theoretisch 42MHz.
ollib. schrieb:> Achso STM32F4 hängen die IOs am AHB nicht am APB aber dennoch sind> niemals 168 MHz drin. Mehr als 800kHz sollten es aber doch sein denke> ich.
Und ich sehe eben nicht, wo bei mir der Fehler sitzt. Ich habe ab den
ganzen Header Dateien bis auf die wenigen Zeilen (siehe Link) nichts
verändert.
>Und ich sehe eben nicht, wo bei mir der Fehler sitzt.
Du hast eine Funktion aufgerufen: GPIO_ToggleBits
Die hat auch noch Parameter die übergeben werden müssen.
In der Funktion wird noch rumgehühnert......
Das alles kostet CPU Takte. Das ist dein Fehler.
/* Set PG6 and PG8 */
GPIOD->BSRRL = GPIO_Pin_14 | GPIO_Pin_15;
/* Reset PG6 and PG8 */
GPIOD->BSRRH = GPIO_Pin_14 | GPIO_Pin_15;
So geht es schneller.
Den Code von Holger anstatt des ToggleBit-Krempels da einsetzen. Am
besten, gleich zehn mal hintereinander als manuelles loop unrolling; so
sollte der Rücksprung an den Schleifenanfang sich mit vielleicht 5%
Geschwindigkeitsverlust begnügen.
Gegebenenfalls noch an den Compiler-Flags schrauben und anstatt -O0 auf
-O2 setzen; wahrscheinliche wirft das aber die schön selber entrollten
Toggles raus. Auf jeden Fall sollte da die Frequenz drastisch raufgehen.
Dirk K. schrieb:> Den Code von Holger anstatt des ToggleBit-Krempels da einsetzen. Am> besten, gleich zehn mal hintereinander als manuelles loop unrolling; so> sollte der Rücksprung an den Schleifenanfang sich mit vielleicht 5%> Geschwindigkeitsverlust begnügen.> Gegebenenfalls noch an den Compiler-Flags schrauben und anstatt -O0 auf> -O2 setzen; wahrscheinliche wirft das aber die schön selber entrollten> Toggles raus. Auf jeden Fall sollte da die Frequenz drastisch raufgehen.
So ist es. Vielen Dank für eure Hilfe (insbesondere Dirk und Holger)!
Noch kurz für die Nachwelt: Statt der Toggle-Bit-Funktion direkt die
Pins zu ändern bringt einen Steigerung der Frequenz um den Faktor 5. Das
Optimierungs-Flag bringt noch zusätzlich eine Steigerung ums 5-fache.
Also sind aus den knapp 1MHz immerhin 24MHz geworden.
Das Optimierungs-Flag alleine ohne den direkten Zugriff auf die Pins
bringt nur einen Faktor 2.
Danke!