Forum: Mikrocontroller und Digitale Elektronik Microchip Studio: Delay hat die falsche Länge


von Matthias X. (current_user)


Lesenswert?

Ich programmiere gerade einen ATSAM Prozessor mit dem aktuellen 
Microchip Studio. Jetzt ist mir aufgefallen, dass die delay_us() und 
delay_ms() funktionen jeweils zu lang sind. der Fehler beträgt jeweils 
den Faktor 2,3.
Ich habe schon meine Taktquelle geprüft, aber die ist korrekt. Das sehe 
ich anhand eines Timers und PWM. Das define CONF_CPU_FREQUENCY habe ich 
auch auf 48MHz gesetzt.

An was könnte es noch liegen?

von Rainer W. (rawi)


Lesenswert?

Matthias X. schrieb:
> An was könnte es noch liegen?

Das könnte daran liegen, dass der Prozessor mit einer anderen Frequenz 
als den von dir eingegebenen 48MHz läuft.

von Wastl (hartundweichware)


Lesenswert?

Matthias X. schrieb:
> einen ATSAM Prozessor

Und der genaue Typ ist geheim?

Erstmal ein nachvollziehbares Minimal-Programm hier posten.
Am besten ein ganzes Projekt, damit keine Unwägbarkeiten drin
stecken können.

von Bruno V. (bruno_v)


Lesenswert?

Matthias X. schrieb:
> dass die delay_us() und delay_ms() funktionen jeweils zu lang sind. der Fehler 
beträgt jeweils den Faktor 2,3.

Rufst Du die auch mit Werten von 100 oder mehr auf? Sonst wirken sich 
Nebeneffekte stärker aus.

Also delay_us(1000) wartet 2300µs, während delay_us(100) 230 wartet?

Das wären also ~ 20 MHz statt 48 MHz.

Manchmal gibt es unterschiedliche Quellen (Clock-Source)s für 
unterschiedliche Aufgaben.

von Wastl (hartundweichware)


Lesenswert?

Rainer W. schrieb:
> Das könnte daran liegen, dass der Prozessor mit einer anderen Frequenz
> als den von dir eingegebenen 48MHz läuft.

Matthias X. schrieb:
> Ich habe schon meine Taktquelle geprüft, aber die ist korrekt. Das sehe
> ich anhand eines Timers und PWM. Das define CONF_CPU_FREQUENCY habe ich
> auch auf 48MHz gesetzt.

Die Aussage könnte allerdings auch so interpretiert werden:
"Einen Fehler bei mir kann ich ausschliessen"

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Matthias X. schrieb:
> Ich habe schon meine Taktquelle geprüft, aber die ist korrekt.

Es kann an den Optinierungseinstellungen liegen.

von Matthias X. (current_user)


Lesenswert?

Danke für die Antworten bisher.

Es handelt sich um einen ATSAM51J20A.
Ich nutze für die gesamte Peripherie und die CPU jeweils die GLCK1 als 
Quelle. Diese wird so erzeugt:
16MHZ Quartz->FDPLL0 (durch 6)(mal 18) = 48MHz GLCK->CPU

Wobei ich gerade gesehen habe, dass die FDPLL folgende Bedinungen hat:
96 MHz to 200 MHz output frequency from a 32 kHz to 3.2 MHz reference 
clock

Ich gehe zwar mit (16/6)MHz in die PPL. Aber ich will ja nur 48MHz am 
Ausgang haben. Eventuell läuft diese dann nicht stabil?

Komisch, dass trotzdem meine ganzen Timer korrekt mit 48MHz laufen, aber 
die CPU nicht?
Ich werde das prüfen.

Mein zweiter Ansatz:
Intern werden die Zyklenschleifen berechnet für die Delayroutine.
Die eigentliche Delayrouting besteht nur aus diesen beiden ASM-Befehlen:

000021D8   subs  r1, #1
000021DA   bhi  #-6

Wieviele Takte sollten die benötigen? Wenn ich das weis, dann kann ich 
prüfen ob die Berechnung der Schleifendurchgänge zu lange dauert oder 
die Taktfrequenz falsch ist.

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Angehängte Dateien:

Lesenswert?

> Wobei ich gerade gesehen habe, dass die FDPLL folgende Bedinungen hat:
> 96 MHz to 200 MHz output frequency from a 32 kHz to 3.2 MHz reference
> clock

> Komisch, dass trotzdem meine ganzen Timer korrekt mit 48MHz laufen, aber
> die CPU nicht?

Core (CPU) und Peripherals können mit unterschiedlichen Takten laufen.

https://next-hack.com/index.php/2020/02/12/overclocking-an-arduino-zero-or-any-atsamd21/

: Bearbeitet durch User
von Matthias X. (current_user)


Angehängte Dateien:

Lesenswert?

Ich verwendet sowohl niedrige, als auch höhere Zahlen, z.B.
delay_ms(10);
delay_us(1000);
...

Eigentlich sollte alles an der selben Taktquelle hängen. Siehe Bild. Es 
ist nur GLCK0 eingerichtet, diese bedient ja auch die CPU. Die gesamte 
Peropherie greift auf diese GLCK0 zu.


Edit 1:
um die PPL auszuschließen habe ich die GLCK auf die interne 48MHz 
Taktquelle geschalten. Das Verhalten bleibt aber gleich.

Edit 2:
Bei Delay_ms(10) will er die oberen ASM Befehle 160000 mal durchlaufen. 
Das wären korrekt wenn die Schleife 3 Takte benötigt.
Also entweder sie benötigt in Wirklichkeit 7 Takte, oder es stimmt 
weiterhin etwas mit der Frequenz nicht.

Wie kann ich die benötigten Takte prüfen? Könnte ein Befehl länger 
dauern wegen einer Pipeline, Compilereinstellungen, o.ä.?

von Matthias X. (current_user)


Lesenswert?

Bruno V. schrieb:
> Also delay_us(1000) wartet 2300µs, während delay_us(100) 230 wartet?

Korrekt

Wastl schrieb:
> Die Aussage könnte allerdings auch so interpretiert werden:
> "Einen Fehler bei mir kann ich ausschliessen"

Das wollte ich damit nicht sagen. Ich wollte nur zum Ausdruck bringen, 
dass ich schon in diese Richtung gedacht habe, es geprüft habe und die 
Taktfrequent "eigentlich" stimmen sollte. Wie gesagt, eigentlich;)

Arduino F. schrieb:
> Es kann an den Optinierungseinstellungen liegen.

Das war auch meine erste Vermutung. Ist aber bei DEBUG und RELEASE 
gleich. Wie gesagt, es sind nur die beiden genannten ASM Zeilen und die 
sind in beiden Einstellungen gleich.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Matthias X. schrieb:

> An was könnte es noch liegen?

_delay()-Zeugs basiert darauf, eine berechnete Zahl Taktzyklen sinnlos 
zu verheizen, indem halt die entsprechende Zahl Instruktionen ausgeführt 
werden.

So weit, so gut.

Während der Laufzeit diese Instruktionen sind Interrupts und DMA aber 
nicht gesperrt.

Die können also zur Laufzeit der _delay-Routine weitere Laufzeit 
hinzufügen. Für Interrupts ist das natürlich sofort klar: die arbeiten 
ja schließlich ebenfalls Instruktionen ab. Bei DMA ist das vielleicht 
nicht sofort klar, aber die kann u.U. auch (direkt oder über Umwege) 
reingrätschen. Die Stelle zur Beeinflussung der Delay-Routine ist hier 
die Busbandbreite.

Nur dann, wenn es einen L1-Codecache gibt und dieser auch aktiviert ist, 
kann man mit einiger Sicherheit davon ausgehen, dass zumindest DMA den 
Delay nicht störend verlängert.

Die Interrupts aber bleiben. Deren Einfluß wird mit aktivem Code-Cache 
sogar größer, weil natürlich bei jeder ISR-Instanz dieser Cache gecleart 
und neu geladen werden muss.

von Rainer W. (rawi)


Lesenswert?

Matthias X. schrieb:
> um die PPL auszuschließen ...

Die was?
https://de.wikipedia.org/wiki/PPL

von Wastl (hartundweichware)


Lesenswert?

Rainer W. schrieb:
> Die was?

Bei Atmel heisst das halt ein bisschen anders ;-)

von Matthias X. (current_user)


Lesenswert?

Ups, ich meinte natürlich PLL. (Oder wie Atmel es genannt hat)

@ Ob S.
Danke. Aber es werden weder Interrupts, noch DMA verwendet.

Ich werde als nächstes mal versuchen einen Timer mit CPU-Takt zu starten 
um zu prüfen wie wieviele Takte die ASM Befehle benötigen.

Im zweiten Schritt werde ich mein Programm auf das Minimum reduzieren, 
schauen ob das verhalten noch so ist und anschließend hier 
veröffentlichen.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Matthias X. schrieb:

> @ Ob S.
> Danke. Aber es werden weder Interrupts, noch DMA verwendet.

Warum nicht? Damit könnte man das sinnlose Delay wahrscheinlich komplett 
vermeiden...

von Andreas M. (amesser)


Lesenswert?

Auf Cortex-M benutzt man für solche Delays eigentlich den Systick 
Counter, den jeder Cortex-M hat. Wenn der schon verwendet wird, dann 
irgend einen anderen Hardwaretimer. Instruktionen auf einem Cortex M4 
zählen zu wollen ist hoffnungslos, der hat eine Pipeline und muss auch 
ab und an mal auf die Busports warten. Das funktioniert nicht so simpel 
wie bei einem AVR8 oder PIC.

von Rainer W. (rawi)


Lesenswert?

Matthias X. schrieb:
> Ups, ich meinte natürlich PLL. (Oder wie Atmel es genannt hat)

Mit Atmel hat das nichts zu tun, genauso wenig wie "clock" eine 
Wortschöpfung von Atmel ist ;-)
Als die Bezeichnung eingeführt wurde, hat an Atmel noch keiner gedacht. 
Die wurden erst 64 Jahre später aus der Taufe gehoben.
https://en.wikipedia.org/wiki/Phase-locked_loop

: Bearbeitet durch User
von Wastl (hartundweichware)


Lesenswert?

Rainer W. schrieb:
> Mit Atmel hat das nichts zu tun, ......

Ach! Echt jetzt?

von Jens G. (jensig)


Lesenswert?

Wastl schrieb:
> Rainer W. schrieb:
>> Mit Atmel hat das nichts zu tun, ......
>
> Ach! Echt jetzt?

Ja, ganz echt ...

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
Noch kein Account? Hier anmelden.