Hallo, ich hab im Artikel "http://www.mikrocontroller.net/articles/LED-Fading" diese Funktion gefunden : void my_delay(uint16_t milliseconds) { for(; milliseconds>0; milliseconds--) _delay_ms(1); verstehe ich nicht. Wofür hat er dort my_delay angelegt??? man kann doch direkt _delay_ms(Zeit); benutzen ?!
Peter schrieb: > man kann doch direkt > _delay_ms(Zeit); benutzen ?! Nein, kann man nicht. Zumindest nicht sinnvoll.
Als Argument von _delay_ms() kann nicht jeder beliebige Wert angegeben werden, sondern es gibt eine Höchstgrenze, die von der CPU-Taktfrequenz abhängt. Mit der Funktion my_delay() wird diese Einschränkung beseitigt.
Edi schrieb: > Als Argument von _delay_ms() kann nicht jeder beliebige Wert angegeben > werden, sondern es gibt eine Höchstgrenze, die von der CPU-Taktfrequenz > abhängt. Das war mal und ist seit der 2008er Version anders (ok, das Beispielprogramm wird alt sein), aber es gibt noch einen anderen Grund: Für die Berechnung wird Fließkomma verwendet. Ist der Wert konstant, optimiert der Compiler die Berechnungen weg da er das Ergebnis direkt ausrechnet. Übergibt man _delay_ms dagegen eine Variable werden die Fließkommaoperationen zur Lauftzeit ausgeführt was viel Zeit und vor allem Speicher verbraucht.
Längere Wartezeiten müssen dann über einen mehrfachen Aufruf in einer Schleife gelöst werden. :-) alles klar. Sonst hat das keinen Grund? Interupts können auch bei _delay_ms(ZEIT); unterbrochen werden?
Wenn du mit WinAVR arbeitest bau mal folgendes zusammen: 1:
1 | #include <util/delay.h> |
2 | |
3 | int main (void) |
4 | {
|
5 | _delay_ms(5); |
6 | }
|
2:
1 | #include <util/delay.h> |
2 | |
3 | int main (void) |
4 | {
|
5 | int i=5; |
6 | _delay_ms(i); |
7 | }
|
Und guck dir dann die Belgung des Flash an (zeigt avrstudio am ende der Bauens (die Prozentzahlen)
... ... schrieb: > Und guck dir dann die Belgung des Flash an (zeigt avrstudio am ende der > Bauens (die Prozentzahlen) Never try using over-simplified test cases. Das bringt rein gar nichts. Bedingung für sinnvolle Benutzung von _delay_ms/_delay_us ist, dass die Optimierung aktiviert ist. Wenn aber die Optimierung aktiviert ist, dann wird sie deine völlig überflüssig angebrachte Variable i als Konstante erkennen und entsprechend eliminieren, womit du identischen Code zu Fall 1 bekommst. Nein, du musst das i schon zum Funktionsparameter machen und diese Funktion dann am besten in einer eigenen Datei separat compilieren:
1 | #define F_CPU 1E+6
|
2 | #include <util/delay.h> |
3 | |
4 | void
|
5 | delay_ms(uint8_t ms) |
6 | {
|
7 | do
|
8 | _delay_ms(1); |
9 | while (--ms != 0); |
10 | }
|
11 | |
12 | void
|
13 | delay_something(uint8_t ms) |
14 | {
|
15 | _delay_ms(ms); |
16 | }
|
Das Compilat wäre dann:
1 | .file "foo.c" |
2 | __SREG__ = 0x3f |
3 | __SP_H__ = 0x3e |
4 | __SP_L__ = 0x3d |
5 | __tmp_reg__ = 0 |
6 | __zero_reg__ = 1 |
7 | .global __do_copy_data |
8 | .global __do_clear_bss |
9 | .text |
10 | .global delay_something |
11 | .type delay_something, @function |
12 | delay_something: |
13 | /* prologue: frame size=0 */ |
14 | push r10 |
15 | push r11 |
16 | push r12 |
17 | push r13 |
18 | push r14 |
19 | push r15 |
20 | push r16 |
21 | push r17 |
22 | /* prologue end (size=8) */ |
23 | clr r25 |
24 | clr r26 |
25 | clr r27 |
26 | movw r22,r24 |
27 | movw r24,r26 |
28 | call __floatunsisf |
29 | movw r10,r22 |
30 | movw r12,r24 |
31 | ldi r18,lo8(0x437a0000) |
32 | ldi r19,hi8(0x437a0000) |
33 | ldi r20,hlo8(0x437a0000) |
34 | ldi r21,hhi8(0x437a0000) |
35 | call __mulsf3 |
36 | movw r14,r22 |
37 | movw r16,r24 |
38 | ldi r18,lo8(0x3f800000) |
39 | ldi r19,hi8(0x3f800000) |
40 | ldi r20,hlo8(0x3f800000) |
41 | ldi r21,hhi8(0x3f800000) |
42 | call __ltsf2 |
43 | tst r24 |
44 | brge .L2 |
45 | ldi r24,lo8(1) |
46 | ldi r25,hi8(1) |
47 | rjmp .L5 |
48 | .L2: |
49 | ldi r18,lo8(0x477fff00) |
50 | ldi r19,hi8(0x477fff00) |
51 | ldi r20,hlo8(0x477fff00) |
52 | ldi r21,hhi8(0x477fff00) |
53 | movw r24,r16 |
54 | movw r22,r14 |
55 | call __gtsf2 |
56 | cp __zero_reg__,r24 |
57 | brge .L6 |
58 | ldi r18,lo8(0x41200000) |
59 | ldi r19,hi8(0x41200000) |
60 | ldi r20,hlo8(0x41200000) |
61 | ldi r21,hhi8(0x41200000) |
62 | movw r24,r12 |
63 | movw r22,r10 |
64 | call __mulsf3 |
65 | call __fixunssfsi |
66 | rjmp .L9 |
67 | .L10: |
68 | ldi r24,lo8(25) |
69 | ldi r25,hi8(25) |
70 | /* #APP */ |
71 | 1: sbiw r24,1 |
72 | brne 1b |
73 | /* #NOAPP */ |
74 | subi r22,lo8(-(-1)) |
75 | sbci r23,hi8(-(-1)) |
76 | .L9: |
77 | cp r22,__zero_reg__ |
78 | cpc r23,__zero_reg__ |
79 | brne .L10 |
80 | rjmp .L12 |
81 | .L6: |
82 | movw r24,r16 |
83 | movw r22,r14 |
84 | call __fixunssfsi |
85 | movw r24,r22 |
86 | .L5: |
87 | /* #APP */ |
88 | 1: sbiw r24,1 |
89 | brne 1b |
90 | /* #NOAPP */ |
91 | .L12: |
92 | /* epilogue: frame size=0 */ |
93 | pop r17 |
94 | pop r16 |
95 | pop r15 |
96 | pop r14 |
97 | pop r13 |
98 | pop r12 |
99 | pop r11 |
100 | pop r10 |
101 | ret |
102 | /* epilogue end (size=9) */ |
103 | /* function delay_something size 89 (72) */ |
104 | .size delay_something, .-delay_something |
105 | .global delay_ms |
106 | .type delay_ms, @function |
107 | delay_ms: |
108 | /* prologue: frame size=0 */ |
109 | /* prologue end (size=0) */ |
110 | mov r18,r24 |
111 | .L15: |
112 | ldi r24,lo8(250) |
113 | ldi r25,hi8(250) |
114 | /* #APP */ |
115 | 1: sbiw r24,1 |
116 | brne 1b |
117 | /* #NOAPP */ |
118 | subi r18,lo8(-(-1)) |
119 | brne .L15 |
120 | /* epilogue: frame size=0 */ |
121 | ret |
122 | /* epilogue end (size=1) */ |
123 | /* function delay_ms size 11 (10) */ |
124 | .size delay_ms, .-delay_ms |
125 | /* File "foo.c": code 100 = 0x0064 ( 82), prologues 8, epilogues 10 */ |
Ich glaube, der Unterschied ist augenfällig...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.