HI! Der folgende Programmabschnitt sollte eigentlich 1 - 20 Minuten warten und mir dann zwei kurze "Pulse" ausgeben. Ich habe schon ewig nicht mehr C Programmiert und bin gerade am Anfang vom Microcontroller programmieren. Wo liegt der Fehler? Habe es auf einen ATmega168 programmiert und an die STK500 Dioden gehängt. Die blinken aber leider ohne die 1- 20 Minuten, die sie meiner Meinung nach durchgehend leuchten sollten. int i; long j; i = rand() % 20; // Generierung der "Pulsbreite" j = rand() % 20; // Generierung der Zeit zwischen zwei Pulsen j = j * 60000; // Umrechnung in Millisekunden _delay_ms(j); // Verzögerungszeit zwischen zwei Pulsen PORTB |= (1<<PB0); // PB0 auf high _delay_ms(i); // PB0 für 1-20 ms auf high PORTB &= ~ (1<<PB0); // PB0 wieder auf low PORTB |= (1<<PB1); // PB1 auf high _delay_ms(10); // PB1 immer für 10 ms auf high PORTB &= ~ (1<<PB1); // PB1 wieder auf low
Ach ja das ganze liegt natürlich in einer Schleife, die immer wieder den Code durchläuft...
@ghost >Der folgende Programmabschnitt sollte eigentlich 1 - 20 Minuten warten >und mir dann zwei kurze "Pulse" ausgeben. >Ich habe schon ewig nicht mehr C Programmiert und bin gerade am Anfang >vom Microcontroller programmieren. Wo liegt der Fehler? Habe es auf >einen ATmega168 programmiert und an die STK500 Dioden gehängt. Die >blinken aber leider ohne die 1- 20 Minuten, die sie meiner Meinung nach >durchgehend leuchten sollten. > int i; > long j; > i = rand() % 20; // Generierung der "Pulsbreite" > j = rand() % 20; // Generierung der Zeit zwischen zwei Pulsen > j = j * 60000; // Umrechnung in Millisekunden > _delay_ms(j); // Verzögerungszeit zwischen zwei Pulsen Das geht schief. Das Makro verträgt max. 260 ms bei 1 MHz Prozessortakt. Bei 10 MHz entsprechd nur 26 ms. Das musst du als Schleife programmieren. Siehe Doku der libc. Und nicht das vergessen #define F_CPU 1000000UL Logischerweise mit der richtigem Freqeunz in Hertz. MfG Falk
Ach ja, das Macro _delay_ms() sollte man auch nur mit Konstanten verwenden, denn es verlangt als Parameter einen double. Bei Variablen wird die Berechnung dann zur Laufzeit gemacht, was natürlich massiv Zeit und Programmspeicher kostet. Ein weiterer Gund, variable Verzögerungen übern ne Schleife zu programmieren. MFG Falk
Zitat aus der libc-Doku: "When using _delay_us() and _delay_ms(), the expressions passed as arguments to these functions shall be compile-time constants, otherwise the floating-point calculations to setup the loops will be done at run-time, thereby drastically increasing both the resulting code size, as well as the time required to setup the loops." Mit anderen (deutschen) Worten: Grundsätzlich nur Konstanten verwenden, die zur compile-Zeit bekannt sind. Und wie Falk auch schon andeutete: In der Doku steht auch drin, welche maximalen Verzögerungen möglich sind (abhängig von der Taktfrequenz des Controllers). Zusätzlich muss dem Compiler natürlich bekanntgegeben werden (entweder im Makefile oder im AVRStudio unter Configuration Options) welche CPU-Frequenz verwendet wird.
Also nehm ich am besten nen Timer direkt vom Microcontroller und lass den die Verzögerung ausführen? Geht dann aber nichts mehr mit Zufall oder?
@ ghost >Also nehm ich am besten nen Timer direkt vom Microcontroller und lass >den die Verzögerung ausführen? Ja, z.B. mit 10 ms. >Geht dann aber nichts mehr mit Zufall oder? DOCH! Einfach per rand() eine Zahl ermitteln und im Timerinterrupt runterzählen lassen. MFG Falk
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.