Hallo
Ich würde gerne wissen wie man die Anzahl der Zyklen einer Schleife
berechnet.
Also wie man berechnet wie lange eine Schleife braucht.
Gelesen habe ich .....
fSchleife = ftakt/Zyklen
Die Zeit ist also abhängig von der Taktfrequenz des uC.
Jetzt würde ich gerne wissen wie man bei dem Bsp auf 19 Zyklen kommt.
Zählt man einfach alle Befehle die ausgeführt werden innerhalb der
Schleife ?
Haben die Befehle nicht unterschiedliche Ausführungszeiten ?
Ich nutze den Atmega32
Tim schrieb:> Hallo>> Ich würde gerne wissen wie man die Anzahl der Zyklen einer Schleife> berechnet.
In C gar nicht.
Du lässt den Compiler ein Assembler Listing File erzeugen, suchst dir
das, was vom C-Original übrig geblieben ist, zählst die Takte der
Anweisungen zusammen je nach Kontroll-Fluss durch den Schleifenkörper.
Alles andere ist sinnlos.
> Haben die Befehle nicht unterschiedliche Ausführungszeiten ?
Haben sie.
Und ein Neuling kommt selten in die Verlegenheit, dies überhaupt wissen
zu müssen. Ein mit 16Mhz getakteter µC führt (ein gesunder Mix an
Befehlen angenommen) so ca. 14 Millionen Befehle pro Sekunde aus. Ob
eine Schleife 56 oder 57 Millionstel Sekunden dauert, spielt meistens
keine Rolle. Und wenn es doch eine Rolle spiel, dann hast du deine
ersten 5000 Zeilen C-Code schon lange hinter dir.
Konzetrier dein Augenmerk lieber darauf les- und wartbaren Code zu
produzieren.
Problem der Grundgedanke ist nicht verkehrt
problem ist nur das c-befehle je nach compiler sehr wild umgesetzt
werden (nicht immer das optimum), präzise kann man es nur sagen wenn du
es assembler programmieren würdest, dann müsste man nur noch
herausfinden wie viele zyklen der µc pro befehl braucht und dann kann
man anfangen zu rechnen
wenn etwas sehr zeitkritisch (im sinne von sehr schnelle abfolge) ist
kann man es eigendlich nur in assembler programmieren, wenn es aber zu
einem fixen punkt wiederholt werden soll kann man am besten einen
interupt verwenden
Hallo
Danke für die Antworten.
Ich bastel gerade an einem DDS Frequenzgenerator , aus diesem Grund ist
es für mich auch als Neuling wichtig zu wissen wie lange die Schleife
braucht.
Ich würde gerne wissen wie lange meine Schleife braucht bzw würde das
gerne berechnen können wie viele Ticks/Zyklen diese braucht.
Das ganze ist wichtig da ich ja den Prozessortakt durch diese
Zeit/Zyklen teilen muss um das korrekten FCW ( Freq.Tuningword) zu
bestimmen.
In meinem Bsp spricht der Autor von 19 Zyklen , wie hat er diese
ermittelt ?
Tim schrieb:> In meinem Bsp spricht der Autor von 19 Zyklen , wie hat er diese> ermittelt ?
Er hats in Assembler geschrieben bzw. sich angesehen, was der Compiler
daraus gemacht hat.
>Ich bastel gerade an einem DDS Frequenzgenerator , aus diesem Grund ist>es für mich auch als Neuling wichtig zu wissen wie lange die Schleife>braucht.
Bei dem Mist den du da zusammengebaut hast kann das kein Mensch sagen.
Alleine dein setDisplay() wird schon einige 100 Cycles brauchen.
Der Beispiel Code ist nicht von mir , sonst würde ich ja wissen warum es
19 Zyklen sind !.
Was genau meinst du damit ?
Wie kann ich beim Assembler Code erkennen das die Schleife 19 Zyklen
brauchen ?
Hast du vieleicht einen Link zu diesem Thema für mich ?
Tim schrieb:> Der Beispiel Code ist nicht von mir , sonst würde ich ja wissen warum es> 19 Zyklen sind !.>> Was genau meinst du damit ?> Wie kann ich beim Assembler Code erkennen das die Schleife 19 Zyklen> brauchen ?
In der Instruction Summary vom Prozessor (eigenes Dokument von Atmel)
steh bei jedem Befehl dabei, wieviele Takte er braucht. Dieselbe Info
kriegt man auch im AVR-Studio, in der Hilfe zum Assembler. Auch dort ist
bei jedem Befehl vermerkt wieviele Takte er braucht. Und die meiste
Assembler Befehle kennt man eh auswendig, wenn man Assembler
programmiert.
Karl Heinz Buchegger schrieb:> In der Instruction Summary vom Prozessor (eigenes Dokument von Atmel)> steh bei jedem Befehl dabei, wieviele Takte er braucht.
Richtig. Das ist eines der wichtigsten Dokumente überhaupt. Gleich nach
dem Datenblatt des jeweils verwendeten Mikrocontrollers.
Hier der Link zur Befehlsübersicht:
http://www.atmel.com/Images/doc0856.pdf
Solch zeitkritische Sachen würde ich entweder rein oder zumindest in
wesentlichen Teilen in Assembler programmieren.
Am einfachsten nimmst Du Dir einen freien Port am Mikrocontroller, setzt
diesen Pin zu Anfang der Schleife, das Rücksetzen ist der erste Befehl
nach Durchlauf der Schleife, danach hängst Du ein Oszilloskop an den
Ausgang und triggerst auf die steigende Flanke ds Signals, dann kannst
Du es genau ausmessen.
Hallo
Danke für den Link !
Werde mich mal durch das PDF kämpfen !
Im Atmel Studio bekomme ich nach dem Debuggen auf der rechten Seite
einen " CycleCounter " angezeigt der allerdings immer auf 31 steht ,
egal welches Programm ich debugge bzw simuliere.Wie kann man sich den im
AtmelStudi die gesamten Cycles anzeigen lassen und/oder die Anzahl der
Cycles pro Schleife.Das muss doch möglich sein.
Gregor B. schrieb:> Am einfachsten nimmst Du Dir einen freien Port am Mikrocontroller, setzt> diesen Pin zu Anfang der Schleife, das Rücksetzen ist der erste Befehl> nach Durchlauf der Schleife, danach hängst Du ein Oszilloskop an den> Ausgang und triggerst auf die steigende Flanke ds Signals, dann kannst> Du es genau ausmessen.
Das muss doch auch ^weniger umständlich gehen.
Ich beiße mich gerade durchs PDF , ist aber gar nicht so leicht.
Falls jemand einen Tip hat wie es AtmelStudio geht wäre das super.
Vielleicht hat auch jemand einen Link zu einer Beschreibung der
generellen Vorgehensweise
Der Debugger ist nur bedingt geeignet, um C Code auf diesem Level zu
debuggen. Wirklich gut funktioniert er nur, wenn Du alle
Code-Optimierungen deaktivierst, dann gibt es für jeden C Befehl einen
oder mehrere Assember Befehle. Aber ohne die Optimierungen ist der
erzeugte Code auch viel größer und langsamer.
Mach das ompiler dabei auch ein Assembler-Listing ausgeben. Dann
addierst Du die Taktzyklen der ganzen befehle zusammen.
Tim schrieb:> Das muss doch auch ^weniger umständlich gehen.> Ich beiße mich gerade durchs PDF , ist aber gar nicht so leicht.
Du musst die PDF doch gar nicht komplett lesen?!
Mir fallen so auf Anhieb 3 Möglichkeiten ein.
1. Pin toggeln und mit dem Oszi anschauen -> Ist dir zu umständlich
2. JTAG -> Hast du vermutlich keins
3. Assembler-Listing anschauen
Zu 3.:
Du lässt AtmelStudio das Projekt übersetzen.
Dannach wechselst du in das entsprechende Projektverzeichnis und hälst
dort die Augen nach einer Datei mit der Endung ".lst" offen.
Dies ist das erzeugte Assembler-File und enthält deinen C-Code übersetzt
in ASM.
Du suchst die entsprechende Stelle für die Schleife - das ganze setzt
natürlich zumindest ein minimales Grundverständnis der Assembler-Sprache
voraus, sonst wird's schwierig :)
Jetzt schaust du welche Befehle in der Schleife stehen, suchst aus der
verlinkten PDF die Anzahl der benötigten Zyklen, addierst und fertig.
Zumindest in der Theorie :D
Zumindest im 4-er Studio hat man auch bei C-Programmierung die Assembler
Referenz greifbar.
Unter 'Help' / 'AVR Tools Users Guide'
gibt es den Eintrag 'Assembler'.
In dem findet sich wiederrum 'Instructions' und dort ist bei allen
Befehlen vermerkt, wieviele Takte (Cycles) sie benötigen.
Hat man ein Assembler Projekt, dann geht das noch einfacher, weil man
einfach den Cursor im Programmtext auf die Instruktion setzt, F1 drückt
und das Help-System sucht dann die Hilfe für diesen Befehl heraus.
Will man es sich also auf diesem Weg einfach machen, spricht auch nichts
dagegen, sich den bewussten Abschnitt aus dem Listing-File in ein
Assembler-Projekt zu kopieren (muss ja gar nicht übersetzbar sein) und
dann mit F1 die benötigten Takte festzustellen.
Noch einfacher ist es allerdings, wenn man im Simulator die Takte
mitzählt. Warum da bei dir immer 32 steht weiß ich nicht. Bei mir
funktioniert das, dass der Simulator die bisher simulierten Takte
mitzählt.
Tim schrieb:> Ich würde gerne wissen wie lange meine Schleife braucht bzw würde das> gerne berechnen können wie viele Ticks/Zyklen diese braucht.> Das ganze ist wichtig da ich ja den Prozessortakt durch diese> Zeit/Zyklen teilen muss um das korrekten FCW ( Freq.Tuningword) zu> bestimmen.
Aufgaben, die ein genaues Timing erfordern, macht man i.a.R. mit Hilfe
einer Hardwareressource wie Timer, Capture/Compare usw.
Ein genaues Timing mit einer Schleife (ohne Interrupts) mit haargenauer
Laufzeit ist bei sehr einfachen Programmen zwar möglich, aber aufwendig,
da Du für jeden möglichen Programmzweig die genau gleiche Laufzeit
erzeugen mußt.
In dem Augenblick, wo das Programm etwas aufwendiger wird und wenn
Interrupts ins Spiel kommen, funktioniert das ganze nicht mehr.
Beispiel:
1
if(bedingung)
2
{
3
dosomething();
4
}
Wenn "bedingung" wahr ist, hast Du mehr Laufzeit als wenn nicht.
Du müßtest also in diesem so etwas machen:
1
if(bedingung)
2
{
3
dosomething();
4
}
5
else
6
{
7
delay(GENAUSO_VIELE_TAKTE_WIE_DO_SOMETHING);
8
}
Und das müßtest Du ganz konsequent über alle Funktionen hinweg
ausbalancieren.
Hallo
Ich werde es parallel mal mit Timern ausprobieren.
Ich habe nun versucht anhand der Assembler Datei die benötigten Cyklen
zu berechnen.
Folgendes steht in der Datei !
Ich habe mal die relevanten Befehle zusammen geschrieben und die
benötigten Cycles für jeden Befehl.
subi r24, 0x00 ;1
sbci r25, 0x42 ;1
sbci r26, 0xFF ;1
sbci r27, 0xFF ;1
mov r30, r26 ;1
ldi r31, 0x00 ;1
subi r30, 0xAC ;1
sbci r31, 0xFF ;1
lpm r30,;3
out 0x12, r30 ;1
in r18, 0x13 ;1
cpi r18, 0x1F ;1
breq ; 2
Macht 16 Cycle !
Laut AtmelStudio stimmt das auch !
Jedesmal wenn die Schleife durchläuft springt die Anzeige
"CycleCounter" um 16 weiter.Was ich nun wiederum nicht verstehe ist
warum der Autor des Codes von 19 Cycle spricht und nicht von 16.
Es ist zumindest ein Schritt in die richtige Richtung und sich bischen
mit Assembler zu beschäftigen kann sicher nicht schaden.
Andere Compiler Version.
Und jetzt weißt du auch, warum die Sache als C Code nicht so sinnvoll
ist. Mit jeder Compiler Version kann sich die Anzahl ein wenig ändern.
Wenn man gesicherte Taktzahlen benötigt (und du benötigst die
tatsächlich), dann führt kein zuverlässiger Weg an Assembler vorbei. In
diesem Fall brauchst du die totale Kontrolle über die Maschine.