> Ist die von der Optimierungsstufe des Compilers abhängig?
Ja ist es. Und je nach Taktfrequenz musst du Wait States für den Flash
Speicher nutzen, daher geht es nicht ganz so einfach (die Taktfrequenz
durch x teilen).
> Wo finde ich Assembly in SW4STM (Eclipse) - damit ich mir die
> Cycles berechnen kann?
Ich bin unsicher, was du mit der Frage meinst. Wenn du sehen willst,
welchen Assembler-Code der Compiler erzeugt, dann trage in in das
Textfeld unter Properties/C/C++ Build/Settings/Tool Settings/MCU GCC
Linker/Miscellaneous/Linker Flags das ein:
-Wa,-adhlns="$(@:%.o=%.lst)"
Du findest dann für jede Quelll-Datei eine *.lst Datei im Verzeichnis
Debug oder Release.
> 34 Cycles hört sich ja im ersten Moment nicht "viel" an, macht aber
> in der Summe mehrere Mhz am gesamten Takt aus.
Ich gehe davon aus, dass nicht alle Counter so schnell hochzählen
müssen. Dann bietet sich folgendes Konstrukt an:
1 | void SysTick_Handler(void)
|
2 | {
|
3 | static uint8_t teiler=0;
|
4 |
|
5 | if (Delay != 0x00) Delay--;
|
6 | milli_seconds++;
|
7 |
|
8 | if (++teiler == 100)
|
9 | {
|
10 | teiler=0;
|
11 | cal_timer++;
|
12 | speed_timer++;
|
13 | watchdog_gps++;
|
14 | MPU_print++;
|
15 | timer_0++;
|
16 | mpu_timer++;
|
17 | Tx_timer++;
|
18 | }
|
19 | }
|
Das würde die CPU Last deutlich senken.
Eine andere Möglichkeit ist, nicht viele Variablen hochzuzählen, sondern
nur eine einzige. Vermutlich setzt dein Programm die vielen Zähler auf 0
und macht dann irgend etwas bis (oder wenn) sie einen gewissen Wert
erreicht haben. Das kann man auch anders machen:
1 | uint32_t milli_seconds;
|
2 |
|
3 | void SysTick_Handler(void)
|
4 | {
|
5 | milli_seconds++;
|
6 | }
|
7 |
|
8 | void delay_ms(uint32_t time)
|
9 | {
|
10 | uint32_t start=milli_seconds;
|
11 | while (milli_seconds-start <= time);
|
12 | }
|
13 |
|
14 | void measure_time()
|
15 | {
|
16 | uint32_t start=milli_seconds;
|
17 | // tu irgendwas hier
|
18 | uint32_t elapsed=milli_seconds-start;
|
19 | }
|
Der Trick hierbei liegt in der Subtraktion. Sie liefert sogar das
korrekte Ergebnis, wenn milli_seconds zwischendurch einmal übergelaufen
ist. Das Zurücksetzen auf 0 entfällt, und das wiederum ermöglicht es
Dir, den EINEN milli_seconds Counter in mehreren Threads parallel und
überlappend zu verwenden.
Du kannst damit Intervalle messen, die maximal 2x so lang sind, wie ein
kompletter Durchlauf. Also in diesem Fall maximal 98 Tage.
Von Delays halte ich übrigens nicht viel. In sehr einfachen Programmen
sind sie noch praktisch, doch für so einfache Programme würde keinen
"fetten" 32bit Controller verwenden. Früher oder später soll dein
Programm mehrere Threads parallel abarbeiten (lerne: Endlicher Automat)
und dann sind Delays praktisch verboten (außer im µS Bereich).