Variable Zeitschleife

Gast #77642
Lesenswert?

Hi,

ich hab mir eine Variablezeitschleife geschrieben. Leider krieg ich
voellig falsche Wartezeiten (im Simulator Avr Studio). Ich wuerde mich
freuen wenn mir jemand da kurz helfen koennte.

warteschleife funktion

void delay_us(unsigned char us)
{
//unsigned char i;
temp = (((XTAL_CPU/1000000)*us)/8);
for (i=0;i<=temp;i++);
{
asm("nop");
}
return 0;
}


aufruf im main mit z.B. delay_us(10)

er wartet aber in diesen Fall 16 us also 6 us zuviel

Mfg

Dirk
Gast #77643
Lesenswert?

Hi,

habe es nun hinbekommen.

Mein Problem war das die Zeitschleife 12 Takte braucht und ich nur / 8
gerechnet habe.... habe ich die 8 auf >9 festgelegt hat er allein schon
zur berechnung 100 ms gebraucht.

Es wurde mir gesagt das Konstanten immer mit Int berechnet wird.

Deshalb habe ich es jetzt so gemacht und es funktioniert.

void delay_us(unsigned char us)
{
//unsigned char i;
temp = (((XTAL_CPU/1000000)*us)/8);
temp = temp /4;
for (i=0;i<=temp;i++);
{
asm("nop");
}
return 0;

}



Mfg

Dirk
Gast #77644
Lesenswert?

Hi,

ich nochmal: bei 4 Mhz funktioniert es wunderbar aber bei 8 mhz
funktioniert es nicht. Ich hoffe mir koennte da jemand mal unter die
arme greifen. Sollte ich die ganze Funktion lieber in asm schreiben?


Mfg

Dirk
Gast #77646
Lesenswert?

Hi,

diese Routinen errechnen aber nicht die Wartezeit in Abhaengigkeit der
AVR Quarzfrequenz.

In der delay.h bei mir steht folgender Text:

/* TODO: macros to allow specifying delays directly in microseconds
   (with MCU clock frequency defined by the user).  With constant
   delays, all floating point math would be done at compile time.  */

Ist meine Delay.h veraltet? Ich hab extra die neuste WinAvr Version
gesaugt. Jetzt wollte ich das in Angriff nehmen. Wo sollte ich den die
Berechnung machen? in der Routine zum Aufruf oder gleich nach dem
programmstart .... ?


Mfg

Dirk
Gast #77647
Lesenswert?

Du läßt sie den C-Präprozessor erledigen, so ungefähr:

#define SYSCLK 4000000L

...
  _delay_loop_2(100 /* µs */ * (1000000L / 4) / SYSCLK);

oder vielleicht auch

#define delay_us(us) _delay_loop_2(us * 250000L / SYSCLK)

...
  delay_us(100);

Irgendwas in dieser Art hat sich Marek Michalkiewicz wohl beim
Schreiben dieses Kommentars gedacht.  Ist aber bislang noch nicht drin
in diesem Header, aber so schwer war's doch auch nicht, oder?
Gast #77651
Lesenswert?

Hi,

wollte nur bescheid sagen das alles so funktioniert und ich sehr
zufrieden bin. Das mit dem Praeprozessor ist natuerlich eine feine
Sache.

>> Huch, so förmlich, bin ich Dir auf den Schlips getreten?

Noe, kritik muss jeder abkoennen.

Mfg

Dirk

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren