Im Moment bin ich unangenehm vom STM32F103 überrascht. Für bestimmte Projekte (bspw. das Anbinden von parallelen Displays dessen Anschluesse quer Beet über 3 Ports verteilt sind - nein, das kann ich nicht ändern, weil das Board vorgegeben ist) möchte ich das Bitwackeln so schnell als möglich erledigen. Leider kann ich nicht alle Pins mittels DMA (bspw. über einen SPI) ansprechen, deshalb: Bitwackeln. Mein Problem (oder besser mein Ärgernis) ist folgendes: Coretakt: 72MHz Library: libopencm3 Während das Setzen und wieder Löschen eines GPIO's bei 160 ns liegt, benötigt das Löschen und wieder Setzen "satte" 430 ns (was mehr als das Doppelte ist). Weshalb ist das so? Mein Testprogramm ist im Anhang, Systemtimertakt ist ausgeschaltet. Verrückt ist, dass das bei einem STM32F030 so nicht auftritt, da benötigt da beträgt das Pause-Puls Verhältnis ca. 220 ns : 220 ns Selbst bei einem ATmega328p erreiche ich Zeiten um 280 ns (bei 16 MHz Takt). Die Fragen also: Warum sind die Zeiten unterschiedlich ? Welche Methode kann ich noch verwenden (ausser über BSRR) um evtl. schnellere Schaltzeiten zu erreichen ? Gruß, JJ
Mist, vor lauter "Ärgernis" vergessen den Code anzuhängen...
Lasse den Code zumindestens im RAM laufen. Oder besser, lade die Basisadresse des GPIO Block in ein Register und toggle durch setzen der entsprechenden BSSR Bits mit Codeausfuehrung aus dem RAM
Uwe B. schrieb: > Lasse den Code zumindestens im RAM laufen. Oder besser, lade die > Basisadresse des GPIO Block in ein Register und toggle durch setzen der > entsprechenden BSSR Bits mit Codeausfuehrung aus dem RAM Puuuuuh... aus dem RAM laufen lassen ... erfordert für mein Setup grundsätzliche Änderungen (weil bisher nicht vorgesehen und bisher auch nicht notwendig war). Okay, wollte ich irgendwann sowieso einmal machen. Beim Togglen bin ich gerade dabei (allerdings mit Code aus dem Flash) und das schaut nicht wirklich besser aus. Kann sein, dass mit der Codeausführung aus dem RAM das besser wird, es erklärt aber nicht, warum die Pausezeit länger ist.
Ralph S. schrieb: > Welche Methode kann ich noch verwenden (ausser über BSRR) um evtl. > schnellere Schaltzeiten zu erreichen ? Es ist nicht klar, wie schnell nun die APB2 Clock ist. Zumindest sieht es so aus, als würdest du die 72MHz gleich wieder durch 8 teilen (als AHB Clock) und damit auch die APB2 Clock darauf begrenzen. die verbleibenden 9 Mhz sind dann wirklich langsamer als ein AVR bei 16MHz. Das muss aber nicht sein, denn die AHB Clock kann ruhig 72Mhz sein und ebenso APB2. Siehe dazu im RM0008 Reference Manual den Clocktree auf Seite 90. Nur APB1 muss per Vorteiler auf 36Mhz und weniger begrenzt werden. Poste mal dein startup File.
Wenn du dieses systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); durch 8 teilen meinst, das geschieht ja nur in oid systick_setup(void) und ist in der sys_init auskommentiert und wird nicht aufgerufen (weil ich ja wirklich alles ausschalten wollte). Ein herkömmliches Startup-File gibt es bei libopencm3 nicht, es werden mit vector.c und nvic.c die Interruptvektoren festgelegt. Takteinstellungen geschehen innerhalb eines Projektes. Mit dem Einstellen des Taktes wie oben im Anhang (und einem aufgesetzten UART) zeigt mit das Programm für die Systemeinstellung das hier an:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
(und ich habe was weiß ich wie oft AHB, APB1 und APB2 überprüft). Ein Indiz dafür, dass das mit voller Geschwindigkeit läuft ist auch, dass ich wesentlich höhere Taktraten erreiche, wenn ich ein einzelnes Bit über DMA und SPI befeuere. Aaaaaber, ich werde mal die HAL installieren und sehen, wie es sich da verhält (für den Fall, dass im Setup der libopencm3 etwas nicht stimmt).
Das hier ist der Code für die Takteinstellung:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
Wobei das hier:
1 | |
2 | |
3 | |
4 | |
für mich unauffällig ausschaut.
Ich persönlich weiss jetzt nicht, wie die Funktionien nun ausgeführt werden, ich kenne das von anderen startup files so, das man direkt sieht, welche Register mit welchen Werten gefüllt werden, also mit deutlich weniger Abstraktion als deine Lib. Allerdings kann es beim Porthandling sinnvoll sein, statt der Shifterei zum Resetten eines Bits einfach das GPIO->BR Register zu benutzen. Besser, du suchst mal andere Benutzer der libopencm3, ich bin da erstmal raus.
Gast
#6149311
Mit Optimierung kompiliert? Zeig mal das Disassembly der main.
Matthias S. schrieb: > GPIO->BR Wird auch GPIO->BRR genannt.
Gast
#6149317
Matthias S. schrieb: > Matthias S. schrieb: > GPIO->BR > > Wird auch GPIO->BRR genannt. Wird doch im Code sogar schon benutzt, in den IOPIN_SET und IOPIN_CLR Makros.
Das kann ich nicht sehen. Ich lese da:
1 | |
2 | |
mit BRR sähe das so aus:
1 | |
Gast
#6149349
Stimmt, es ist BSRR und nicht BRR. Der einzige Unterschied ist, dass 0x100 und nicht 0x1 geladen werden muss. Das dürfte geschwindigkeitstechnisch kein Unterschied sein.
Programmierer schrieb: > Das dürfte > geschwindigkeitstechnisch kein Unterschied sein. Immerhin muss was gemodelt werden. Wie das gemacht wird, hängt vom Compiler ab und könnte man im Kompilat mal untersuchen. Da der TE aber die max. Geschwindigkeit rausholen möchte, sollte man meine Variante zumindest mal ausprobieren, denn selbst wenn ein schlauer Compiler ein SWAP oder so benutzt, kostet es Zeit und würde die längere Zeit beim Resetten erklären (siehe Threadtitel).
Nee, das ist Quatsch meinerseits - das sind ja alles Konstanten.
Gast
#6149562
Programmierer schrieb: > Stimmt, es ist BSRR und nicht BRR. Der einzige Unterschied ist, dass > 0x100 und nicht 0x1 geladen werden muss. Das dürfte > geschwindigkeitstechnisch kein Unterschied sein. Klar macht das einen RIESENunterschied. movs geht nur für 8-Bit Konstanten. Je nachdem, wie der Compiler das macht (einmal vor der Schleife bei Konstanten in verschiedene Register laden oder jedesmal die Konstanten nei laden) ... Ohne Assembler-Output ist das alles Kaffeesatzleserei.
Gast
#6149566
A. B. schrieb: > Klar macht das einen RIESENunterschied. movs geht nur für 8-Bit > Konstanten. Ja, das andere mov welches 0x100 kann ist eine 32bit Instruktion. Die braucht aber auch nur 1 Takt.
so, nachdem Karneval vorbei ist, habe ich mich meinem "Problem" wieder gewidmet und aufgrund eines anderen Threads Beitrag "STM32F103C8T6 - Fälschung von ST bestätigt" habe ich mir den Chip angesehen und siehe da, es ist auch einer mit der Bezeichnung MYS807 und den beiden "zusätzlichen" Vertiefungen. Danach habe ich mein Testprogramm auf meiner eigenen Platine und einem Nucleoboard getestet und siehe da: Die Pausezeit ist nicht mehr heftig länger !!! Bei den "Erkenntnissen" zur Fälschung wurde auch etwas über den ACK bei I2C gesagt: Prompt funktionieren meine I2C Routinen auch nicht ! Somit hat sich mein Problem erledigt. Vielen Dank für die Gedanken aus dem Forum
Gast
#6160993
> Leider kann ich nicht alle Pins mittels DMA
Natürlich. Man kann alle Ports per DMA ansprechen. Egal ob es normale
GPIOs sind.
Gast
#6160997
Nachtrag: Ich habe das mal genutzt, um per DMA sehr viele PWMs zu erzeugen (auf allen Pins) ohne das der Prozessor dabei etwas tun müsste.
Gast
#6161698
Habs nochmal nachgestellt und die Ergebnisse im Anhang erhalten Hier der verwendete Code (O3 Speed Optimierung)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
Gast
#6161705
also Ergebnis ist: Setzen und wieder Löschen: 150ns Löschen und wieder Setzen: 125ns
Gast
#6161708
Achso vergessen: Der Takt ist 72MHz und das Board ein Bluepill mit einem STM32F103C8T6.
Gast
#6161711
ach und die loop braucht 0 ns ? Probier mal folgendes:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
Gast
#6161712
NichtWichtig schrieb: > ach und die loop braucht 0 ns ? Man stimmt! Ich bin echt ein Schlauberger. Ich probiere es nochmal...
Gast
#6161717
So also nun ergeben sich diese Werte: 125ns für "ein aus" und "aus ein".
Um die Veroder- und Verunderei auszuschliessen, kannste auch mal, wie o.a., die GPIO->BSRR und GPIO->BRR Register schreiben.
Gast
#6161737
Matthias S. schrieb: > Um die Veroder- und Verunderei auszuschliessen, kannste auch mal, wie > o.a., die GPIO->BSRR und GPIO->BRR Register schreiben. Damit erreiche ich Zyklus-Zeiten von ca 55nsec, 25nsec high und 30nsec low (abstrahiert von der zusätzlichen Zeit für die Schleife), bei einer Optimierungsstufe des Compilers von -O3.
Gast
#6161889
STM Apprentice schrieb: > Damit erreiche ich Zyklus-Zeiten von ca 55nsec, 25nsec high und > 30nsec low (abstrahiert von der zusätzlichen Zeit für die Schleife), > bei einer Optimierungsstufe des Compilers von -O3. Kann ich bestätigen. Habs grade nochmal getestet und komme ebenfalls auf etwa 25/30ns.
Das sieht also nach einer zuverlässigen Methode aus, um Fake und Original zu unterscheiden.
Gast
#6161930
Matthias S. schrieb: > Das sieht also nach einer zuverlässigen Methode aus, um Fake und > Original zu unterscheiden. Das geht für mich aus dem Thread nicht hervor. Welche Methode? Bitte erkläre das genauer.
Gast
#6162142
Ich glaube ehrlich gesagt nicht an diese Fake-Geschichte. Ich vermute eher, dass der TO den uc falsch programmiert hat. Wenn er sich nochmal meldet, kann ich ihm ein entsprechendes HEX-File zukommen lassen. Wenn er ein Bluepill-Board nutzt, kann ich ihm das geben, was auch ich hier getestet habe. Erst dann lasse ich mich überzeugen.
Gast
#6162145
blu schrieb: > Erst dann lasse ich mich überzeugen. Yes Sir!
Lest dieses Posting des TE: Beitrag "Re: STM32F103: Unterschiedliche Puls-Pausezeiten, Pausezeiten länger"
Bei Bedarf könnte ich ein Bildchen des Dies machen. ...muss heute diesbezüglich auch noch was hochladen... Spoiler: Es gibt STM32, die einen CKS32 enthalten. :)
... ich bin m Moment nicht zu Hause. Ob du das mit dem Fake glaubst oder nicht ist unintetessant. Es ist sogar uninteressant ob ichs falsch programmiert habe oder nicht. Interessant isr, dass ich auf einem neueren BluePill Board (welches ein Testprogramm als Fake ausgewiesen hat) und ein anderes Board (welches lt. Testprogramm kein Fake ist) mit ein und derselben Firmware unterschiedliche Laufzeiten generiert. Das Testprogramm auf Fake oder nicht Fake ist hier zu finden: Beitrag "Re: STM32F103C8T6 - Fälschung von ST bestätigt"
Gast
#6163202
Wie unterschiedlich sind die Laufzeiten in etwa? Hier konnte ich ca 15% langsamer für den Fake-Chip ermitteln bei harmlosen GPIO-Spielchen, also nix mit DMA, ADC oder IRQs UART zum PC paßte allerdings oder der PC war gutmütig genug das Signal noch zu akzeptieren.
NichtWichtig schrieb: > Wie unterschiedlich sind die Laufzeiten in etwa? Ich habe nicht weiter nachgeforscht, nachdem das, was ich machen wollte auf einem originalen STM lief. Ich für mich weiß noch nicht, was ich mit den Fake-Chips machen werde. Die meisten Programme laufen auf den Fake-Chips. Ich muß nur wissen, dass eben nicht alles auf den Chips läuft.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.

