PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Warum stimmt mein berechneter time-delay so nicht?



ricola
18.10.2005, 12:20
Hallo,
ich benutze folgende Funktion um eine Zeit herunterzuzählen:

// delay function
// with external clock = 12.0 MHz
void delay_ms(uint16_t ms) {

uint16_t downtimer;

while (ms) {
downtimer = 12000;
while (downtimer) {
downtimer--;
}
ms--;
}
}

Ich benutze eine 12.0 MHz external Clock am ATMEGA16,
ist auch bei den fuse-bits korrekt eingestellt.
Wenn ich nun aufrufe:
delay_ms(500);
Dann dauert es aber ca. 2 Sekunden, statt 1/2 Sekunde. Warum?
Habe ich etwas falsch parametriert?

Gruß
RICOLA

kater
18.10.2005, 12:32
Das Programm scheint richtig zu sein. Bedenke nur das while() auch ein paar Take an Zeit braucht.
Wenn die Schleifen nicht duch ein Interrupt unterbrochen werden, muss was mit dem ext. Quarz oder den FuseBits nicht stimmen.

PicNick
18.10.2005, 14:00
Deine Rechnung ist etwas optimistisch. Der Mega macht zwar zwölf Cycles in jeder MikroSekunde, aber die kriegst du nicht netto für brutto.
Abgesehen vom Schleifen-Drumherum, das ja der Kater schon erwähnt hat:
Um von 16 Bit eins abzuziehen, braucht er mindestens 2 Cycles
Also 6000 statt 12000 ist schon mal sicher.
Schauen, ob es null ist und ggf. wiederholen: nochmals 2 Cycles
Also 3000 statt 12000 ist noch besser
Um es genau zu machen, musst du die Assembler-Liste (.LSS) genau anschauen, welche maschinen-Cycles verbraten werden.

SprinterSB
18.10.2005, 15:19
Ich vermute mal, du verwendest gcc und Optimierst. Dann macht deine ganze Funktion delay_ms() einfach *nichts*, denn die Ergebnisse von deinem Runterzählen etc werden nicht verwendet. Daher wird ein optimierender Compiler das Zeug in die Tonne kloppen, wie es sich auch gehört. Oder sonstige Optimierungen werden vorgenommen, so daß das ganze fixer läuft. Falls du nicht optimierst, dann brauchst du pro Durchlauf länger als gedacht.
Wenn du nicht über Timer als Zeitbasis gehen willst und von C aus genau kontrollieren willst, welche asm-Befehle erzeugt werden, dann ist inline Assembler dein Freund.

ricola
23.10.2005, 18:32
Hallo,
also mit den zweimal halbieren komme ich ziemlich genau auf
die richtige Zeit. Danke, ist ja eigentlich auch ganz logisch.

Ich werde aber demnächst auf den Timer umstellen.


THX
Ricola