Forum: Mikrocontroller und Digitale Elektronik _delay_ms() bleibt einfach hängen


von Der G. (jonnyk)


Lesenswert?

Hallo Leute,

Habe jetzt hier folgendes problem vieleicht hat jemand ne erklärung 
dafür.

Ich verwende einen mega 256 mit 16 MHz.

habe eine delay schleife in meinem programm:

void long_delay(uint16_t ms)
{
  SREG &= ~(1<<WDIF);//Globale interrupts sperren

      for(; ms>0; ms--) _delay_ms(1);

  SREG |= (1<<WDIF);  //Globale interrupts erlauben
  return;
}

wenn ich Sie jetzt aufgerufen habe mit z.b.

long_delay(5000);

lief alles klar.

jetzt brauchte ich aber noch einen timer
da habe ich den timer0 genommen und folgender massen initialisiert

//Timer setzen für die daten aktualisierung
  TCCR0B |= (1<<CS01);
  TCCR0B &= ~(1<<CS00)|(1<<CS02); //Prescaller auf F_CPU/8
  TIMSK0 |= (1<<TOIE0); //Timer 0 overflow interrupt erlauben

seit dem geht mein long delay nicht mehr das Programm bleibt einfach 
hängen. und nach dem ich die initialisierung und die interrupt routine 
rausgenomen habe geht es immer noch nicht.

hat jemand damit schon mal probleme gehabt? kann mir jemand helfen?

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Poste den gesamten Programmtext als Anhang, sonst kann keiner helfen.

von Peter D. (peda)


Lesenswert?

Der Grosse wrote:

> void long_delay(uint16_t ms)
> {
>   SREG &= ~(1<<WDIF);//Globale interrupts sperren
>
>       for(; ms>0; ms--) _delay_ms(1);
>
>   SREG |= (1<<WDIF);  //Globale interrupts erlauben
>   return;
> }

Ich weiß ja nicht, was der Schmarren soll, aber so wirst Du nie 
vernünftig nen Interrupt programmieren können, die werden Dir 
millionenfach verloren gehen.

Für >1000 Zyklen Interrupts zu sperren ist das absolute NoGo!

Macht man nicht, gehört sich nicht, braucht man nicht und wird streng 
bestraft (durch nicht funktionierende Programme).

Delays sind nur für Minimal-Zeiten da (d.h. Verlängerung stört nicht).
Für präzise Zeiten haben die MC-Entwickler ja extra für Dich den Timer 
eingebaut.


>   TIMSK0 |= (1<<TOIE0); //Timer 0 overflow interrupt erlauben

Meine Kristallkugel sagt: Du hast dafür keinen Handler aufgesetzt.


Peter

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


Lesenswert?

Der Grosse wrote:

>   SREG &= ~(1<<WDIF);//Globale interrupts sperren

Es ist übrigens eher Zufall, dass WDIF auf den Controllern, die dieses
Register besitzen, den gleichen Wert 7 hat wie das I-Flag selbst
(das im AVR-GCC SREG_I heißt).  Zum Manipulieren des globalen
Interrupt-Flags gibt es cli() und sei().

von Der G. (jonnyk)


Lesenswert?

Jörg Wunsch wrote:
> Der Grosse wrote:
>
>>   SREG &= ~(1<<WDIF);//Globale interrupts sperren
>
> Es ist übrigens eher Zufall, dass WDIF auf den Controllern, die dieses
> Register besitzen, den gleichen Wert 7 hat wie das I-Flag selbst
> (das im AVR-GCC SREG_I heißt).  Zum Manipulieren des globalen
> Interrupt-Flags gibt es cli() und sei().

Richtig deswegen gibt es ja auch das datenblat und die standart 
biblioteken vom AVR studio. :-)

hat sich übrigens alles erledigt. läuft jetzt falsch kompiliert oder so. 
der Prozessor sprang durch die gegend...

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.