PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : delay Fct erzeugen



amal
18.07.2011, 14:32
hallo Leute:
wie kann ich eine Warteschleife mit 1s Wartezeit erzeugen.
der Takt freq = 3686400hz

void pause(unsigned int D)
{
for(unsigned int i=0;i<D;i++)
asm volatile ("nop");
}
wie groß soll der D sein?
danke

BMS
18.07.2011, 14:39
Hallo,
das müssen schon 2 ineinander verschachtelte Schleifen werden ;)
Für 16Mhz sieht das bei mir so aus:

void sleep(unsigned int sec)
{
for (unsigned int s=0; s<sec; s++) {
for (long int i=0; i<2000000; i++) {
asm volatile("nop");
}
}
}
Für deine Taktfrequenz wären das wohl

void sleep(unsigned int sec)
{
for (unsigned int s=0; s<sec; s++) {
for (long int i=0; i<460800; i++) {
asm volatile("nop");
}
}
}
probier's mal aus ;)
Die Wartezeit hängt auch ziemlich stark vom verwendeten Datentyp ab.
Je nach Breite der Zahlen in Bit sind mehr oder weniger Schreib-/Lese-
zugriffe dann notwendig.
Grüße,
Bernhard

btw: juhu, mein 400. Beitrag ^^

Ceos
18.07.2011, 14:56
ich würde einen Timer nehmen, den so einstellen, dass er jede mS überläuft und dann im Interrupt einen Counter dekrementieren bis er 0 erreicht, in der Warte-Funktion würde ich dann einfach solange if(counter>0); schleifen bis der COunter halt auf 0 ist. Wenn man jetzt weiterdenkt, könnte man nämlich während er wartet noch andere Dinge tun!

Also quasi eine große Schleife, die neben der Bedingung "counter == 0" noch prüft obe es andere Arbeit gibt!

alternativ kannst du auch einfach die <utils/delay.h> includen und _delay_ms(int) oder wenns kürzer sein soll _delay_us(int) verwenden (Achtung F_CPU makro mit frequenz muss definiert sein) dann sparst du dir es das Rad neu zu erfinden

amal
18.07.2011, 17:34
danke, wie geht es mit dem Timer(CTC Modus)?
LG
Amal

Ceos
19.07.2011, 00:16
zum beispiel im CTC ...

ich löse es vielleicht etwas unelegenat, indem ich eine zustandsautomaten programmiere, ich habe verschiedene variablen die die zustände der einzelnen zu bearbeitenden aufgaben darstellen, wenn ich jetzt den zustand des wartens erreiche, hab ich halt ne methode z.B. waitfortermination() die dafür sorgt dass mein programm quasi wartet dass entweder etwas abgeschlossen wird ODER ein timer abläuft, in der methode mache ich nichts anderes als den status auf waiting zu setzen (irgend ein bestimmter zahlenwert oder enum) und gleichzeitig den counter auf einen bestimmten wert zu setzen, in der mainschleife habe ich halt immer einen relativ dicken brocken if-abfragen der dann realisiert dass im falle eines timeout z.B. der "prozess" abgewürgt wird, oder dass ich vll. eine neue aufgabe starte

EDIT: tschuldigung ist zu spät zum schreiben ^^
der timer dekrementiert die counter dann solange bis sie wieder 0 erreicht hat, wenn es zu viele counter werden verliert man aber eventuell ein paar takte, man sollte also sparsam mit den countern umgehen, oder den timer entsprecchend langsamer (und damit gröber machen)

amal
19.07.2011, 09:34
Hallo,
das müssen schon 2 ineinander verschachtelte Schleifen werden ;)
Für 16Mhz sieht das bei mir so aus:

void sleep(unsigned int sec)
{
for (unsigned int s=0; s<sec; s++) {
for (long int i=0; i<2000000; i++) {
asm volatile("nop");
}
}
}
Für deine Taktfrequenz wären das wohl

void sleep(unsigned int sec)
{
for (unsigned int s=0; s<sec; s++) {
for (long int i=0; i<460800; i++) {
asm volatile("nop");
}
}
}
probier's mal aus ;)
Die Wartezeit hängt auch ziemlich stark vom verwendeten Datentyp ab.
Je nach Breite der Zahlen in Bit sind mehr oder weniger Schreib-/Lese-
zugriffe dann notwendig.
Grüße,
Bernhard

btw: juhu, mein 400. Beitrag ^^
moin,
und im Bereich ms sieht es so aus?


void sleep_ms(unsigned int ms)
{
for (unsigned int s=0; s<ms; s++) {
for (unsigned int i=0; i<461; i++) {
asm volatile("nop");
}
}
}

sternst
19.07.2011, 09:47
Welcher Compiler wird denn überhaupt verwendet? AVR-GCC etwa?

#include <util/delay.h>

void sleep_ms (unsigned int ms) {

while (ms--) {
_delay_ms(1);
}

}

amal
19.07.2011, 12:30
Welcher Compiler wird denn überhaupt verwendet? AVR-GCC etwa?

#include <util/delay.h>

void sleep_ms (unsigned int ms) {

while (ms--) {
_delay_ms(1);
}

}

ja AVR-GCC

amal
19.07.2011, 14:26
ich habe jetzt den Timer1 benutzt, und so sieht es aus:
void T1Delay(unsigned int ms)
{
TCNT1=10000-((ms*1e3)/Tcyc);
TCCR1A= 0x00;
TCCR1B= 0x01;

while((TIFR1&(0x1<<TOV1))==0);
TCCR1B=0;
TIFR1= 0x1<<TOV1;

}
int main(void)

{




DDRC|=(1<<PC0); // PC0 als Ausgang


while(1) //Endlosschleife
{
PORTC=PORTC^(1<<PC0); Toggle Pc0
T1Delay(1); // 1ms warten
}

return 0;
}

Ceos
20.07.2011, 09:17
ich hab die timerflags jetzt nicht auf Richtigkeit geprüft, vom Prinzip her okay, aber noch besser wäre es in dem speziellen Falle, in der main Schleife eine

if(delaytimer == 0) Bedingung einzubauen, bei der du dann den delaytimer neu setzt und den pin toggelst

so kannst du in der Zeit wo dein delaytimer mit " if ( delaytimer > 0 ) delaytimer--; " in der ISR dekrementiert wird noch in der main andere sinnvolle dinge tun, wie ankommende bytes aus SPI/UART auszuwerten