Moin, Ich würde gerne mit dem bereits vorhandenen Codemöglichkeiten eine Sleepfunktion basteln. In diesem Forum habe ich dazu die funktion _delay_ms(msec); gefunden. Diese Funktion hat jedoch ein Maximum von 262.14 msec bei 1MHz CPU-Frequenz. Ist die Frequenz 8 mal so hoch ist der maximalwert für die Millisekunden 8 mal kleiner so weit ich das bislang verstehe. Deshalb habe ich mir die funktion sleep (siehe weiter unten) ausgedacht. Das Problem war nun eine Warning. In der Hauptdatei.c des ganzen Programms hatte ich oben # define F_CPU 8000000UL geschrieben und bekam die Meldung F_CPU sei redefiniert. Also habe ich es weggelassen und bin davon ausgegangen, dass der Standard 1MHz ist. Bei folgendem Code ist das ganze aber trotzdem viel zu schnell (bzw die Zeitspanne zu kurz): #include <util/delay.h> #define CPUFREQUENCY 8 // 8 MHz int sleep(uint32_t msec) { //repeat_nothing(msec*240); double max_delay = 262.14 / CPUFREQUENCY; msec = msec * CPUFREQUENCY; if (msec > max_delay) { msec = msec - max_delay; _delay_ms(max_delay); } else { _delay_ms(msec); }; }; int main (void) { DDRD = 0xff; //Datenrichtung sleep(1000); PORTD |= (1<<PD4); sleep(1000); PORTD |= (1<<PD3); sleep(1000); PORTD |= (1<<PD2); sleep(1000); PORTD |= (1<<PD1); sleep(1000); PORTD |= (1<<PD0); Hat jemand eine Idee, wie man das vernünftig macht ohne einen Timer zu benutzen? Ich benötige alle Timer für was anderes und dann wird mir das alles zu kompliziert, wenn man dann auch noch Timer aufteilen muss.
Die Antwort hat Dir der (pre)compiler schon gegeben: F_CPU ist schon definiert. Guck mal ins makefile, da sollte man dann die richtige frequenz einstellen. Die _delay.... Routinen verwenden auch den Wert F_CPU. Aber was ganz anders: Werden derartig lange Pausen benötigt, deutet das auf ein nicht richtig gutes Softwaredesign hin. Stefan
@Stefan: kommt immer drauf an. Wenn nur ein Ding gleichzeitig passiert wäre es doch recht blöd wenn man den Timer einschaltet. (Außer stromsparen usw....) Wenn man allerdings noch irgend eine andere Schnittstelle usw. bedienen muss dann geht das nicht und du hast völlig recht. dann sollte man sein softwaredesign verändern.
verdammt... ich hatte die Whileschleife vergessen... int sleep(int32_t msec) { //repeat_nothing(msec*240); double max_delay = 262.14 / CPUFREQUENCY; msec = msec * CPUFREQUENCY; while (msec>0) { if (msec > max_delay) { msec = msec - max_delay; _delay_ms(max_delay); } else { msec = msec - max_delay; _delay_ms(msec); }; }; }; so gehts einwandfrei ^^ BTW: Kann man hier abgegebene Beiträge wieder löschen? ;)
_delay_ms() und _delay_us() sollten ausschließlich Argumente übergeben bekommen, die bereits zur Compilezeit konstant sind, ansonsten kann der Overhead u. U. erheblich werden, die Startwerte für die Zählschleife zu berechnen. Das hängt damit zusammen, dass sie alles im Gleitkommabereich rechnen, damit die Benutzung möglichs bequem für den Anwender wird, es lässt sich also sowas machen wie
1 | #define MHz * 1e6
|
2 | #define F_CPU 3.8684 MHz
|
3 | |
4 | #include <util/delay.h> |
5 | |
6 | void
|
7 | delay_355ms(void) |
8 | {
|
9 | uint8_t i; |
10 | |
11 | for (i = 0; i < 100; i++) |
12 | _delay_ms(3.55); |
13 | }
|
Sofern die Optimierungen eingeschaltet sind, werden all die aufwändigen Gleitkomma-Rechnungen vom Compiler erledigt, der Code enthält dann:
1 | ldi r18,lo8(0) |
2 | ldi r30,lo8(3433) |
3 | ldi r31,hi8(3433) |
4 | .L2: |
5 | movw r24,r30 |
6 | /* #APP */ |
7 | 1: sbiw r24,1 |
8 | brne 1b |
9 | /* #NOAPP */ |
10 | subi r18,lo8(-(1)) |
11 | cpi r18,lo8(100) |
12 | brne .L2 |
Für längere Zeiten nimmt man sowieso besser einen Timer. Diese Funktionen sind wirklich nur für kurze Intervalle sinnvoll, bei denen es sich nicht lohnen würde, erst einen Timer anzuwerfen.
>Hat jemand eine Idee, wie man das vernünftig macht ohne einen Timer zu >benutzen? Ich nicht. Es gibt nichts Vernünftigeres als Timer zu benutzen, und nichts Unvernünftigeres als mit Delay-Schleifen zu arbeiten. >Ich benötige alle Timer für was anderes Das glaubst Du. Ich vermute, Du kämst bestens mit einem einzigen Timer aus, wenn Du Dein Proggi entsprechend richtig aufbauen würdest. >und dann wird mir das alles zu kompliziert, wenn man dann auch noch Timer >aufteilen muss. Der Grund für "Alles wird in Nullkommanix kompliziert" ist immer derselbe, nämlich ein schlechtes Softwaredesign.
>nämlich ein schlechtes Softwaredesign.
Mancheiner sollte seine beiden Brötchen mal wieder etwas anfeuchten...
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.