Forum: Mikrocontroller und Digitale Elektronik waitMs() wie funktionierts?


von Black-Devel (Gast)


Lesenswert?

ich habe in einer codesammlung das hier gefunden:
1
 void waitMs(uint16_t ms)
2
 {
3
   while(ms--)
4
   {{ \
5
  __asm__ __volatile__ ( \
6
    " ldi r24,%[lo]"     "\n\t" \
7
    " ldi r25,%[hi]"     "\n\t" \
8
    " waitMs2%=:"        "\n\t" \
9
    "  sbiw r24,1"       "\n\t" \
10
    " brne waitMs2%="    "\n\t" \
11
    : \
12
    : [lo] "M" (0xFF & (F_CPU/(1000*4))), [hi] "M" ((F_CPU/(1000*4))/0x100)  \
13
    : "r24","r25" \
14
  ); \
15
   }}
16
 }

ich weiß das diese wait-funktionen sowieso keine elegante lösung sind 
aber meine frage dreht sich auch eher um verständniss.

was passiert bei diesen ASM-code genau?
wieso bekomme ich probleme wenn ich bei einem F_CPU = 14745600 diese 
Funktion verwende?

thx
Black-Devel

von Krapao (Gast)


Lesenswert?

Die innerste Warteschleife in ASM für eine ms arbeitet nur mit dem 8-Bit 
(Register r24). Bei 14745600 Hz brauchst du aber zusätzlich Register 
r25. Das wird zwar berechnet und gefüllt, aber beim Däumchendrehen nicht 
berücksichtigt. Die max. F_CPU für diesen Code liegt bei knapp über 1 
Mhz.

Mit der avr-libc kannst du schreiben
1
#include <util/delay.h>
2
void waitMs(uint16_t ms)
3
{
4
   while(ms--)
5
     _delay_ms(1);
6
}

von Karl H. (kbuchegg)


Lesenswert?

Krapao schrieb:

> r25. Das wird zwar berechnet und gefüllt, aber beim Däumchendrehen nicht
> berücksichtigt.

Einspruch

  sbiw r24,1


SBI-W       Word
r24 und r25 werden verringert.

> wieso bekomme ich probleme

Um das zu beantowrten wäre es hilfreich zu wissen, was deine 'Probleme' 
sind bzw. sein sollen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Krapao schrieb:
> Das wird zwar berechnet und gefüllt, aber beim Däumchendrehen nicht
> berücksichtigt.

Nein.  "sbiw r24, 1" ist eine 16-bit-Operation.  (Der AVR-Studio-
Assembler würde "sbiw r24:r25, 1" geschrieben haben wollen.)

[Edit: Karl-Heinz hat mich überholt. ;-)]

Trotzdem gibt's natürlich keinen Grund, nicht stattdessen gleich
die Variante aus der avr-libc zu benutzen.

von Krapao (Gast)


Lesenswert?

Oh danke für die Korrektur.

von Black-Devel (Gast)


Lesenswert?

wofür steht denn das "M" in
 [lo] "M" (0xFF & (F_CPU/(1000*4))), [hi] "M" ((F_CPU/(1000*4))/0x100) 
\

??

von Krapao (Gast)


Lesenswert?


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.