www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Verzögerungsfunktion


Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Wollte eine kleine Verzögerung zwecks Schalter-Entprellung
einbauen...aber hab so den eindruck als würde es nicht unbedingt
(richtig) funktioneren!

Vielleicht kanns sich ja wer kurz zeit nehmen und sich den code gach
anschaun!

===== Anfang =====

#define F_CPU 4000000
#define USART_BAUD_RATE 19200  // 19200
#define USART_BAUD_SELECT ((F_CPU/(USART_BAUD_RATE*16l))-1)

SIGNAL(SIG_INTERRUPT0) {
 delay_ms(50);      // Verzögerung von 500ms
 USART_transmit('x');
}

void InitSFRs(void)
{
  //Timer0 initialization:
  // Clock source: System Clock
  TCCR0=0x04; //  set prescaler to 1:256 (bei 4MHz, 10ms step)
  TCNT0=0x62;  //  Preload Timer0 value for 10ms steps (0x62 = 98)
  TIMSK=0x00;  //  disables timer0 overflow bit (T0IE0=1)

  // External Interrupt initialization:
  // INT0: ON
  MCUCR=0x0F;  // Rising Edge of INT0 + INT1 generates an
                // interrupt  request
  GICR=0x40;  // enables External Interrupt Request of INT0
}

void delay_ms (unsigned short x) {
  int c=0;
  TCNT0=0x62;  //  Preload Timer0 value for 10ms steps (0x62 = 98)
  TIFR &=  ~(1<<TOV0);    //Lösche Timer Overflow Flag in TIFR
                          //(Timer Interrupt Flag Register)
  while (c < x) {
   if (TIFR & (1<<TOV0)) {    //Kontrolliere, ob TOV0-Bit in TIFR
                              //gesetzt ist
  c++;
  TIFR &=  ~(1<<TOV0);
    }
  }
}

===== Ende =====

Falls ich net irgendwo einen Fehler gemacht haben sollte, müsste doch
alle 10ms das Overflow Flag gesetzt werden -> das heisst in diesem Fall
- beim ext. Interrupt ergibt sich doch eine Verzögerungszeit von 500ms,
oder?


gruß,
semo

Autor: Fritz Ganter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TIMSK=0x00;  //  disables timer0 overflow bit (T0IE0=1)

Und wo enabled du den interrupt?

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das mach ich erst später, nach einer abfrage (wenn ich was bestimmtes
empfangen habe...hab den code net vollständig gepostet).

Aber eigentlich brauch ich doch im moment dieses overflow bit nicht für
die "verzögerung", oder!? (mit dem aktiviere ich ja nur den
enstprechenden interrupt nach einem overflow - wenns stimmt...)

gruß,
semo

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> SIGNAL(SIG_INTERRUPT0) {
>  delay_ms(50);      // Verzögerung von 500ms


Oh, oh, oh, ganz, ganz böses Foul !
In einem Interrupt warten ist streng verboten, erst recht nicht für
jahrelange 500ms !

Es sieht ja vielleicht aus, als obs nicht schadet, aber sobald Dein
Programm etwas mehr machen soll, krachts.
Z.B. wenn über die UART was empfangen werden soll, gehen Dir bei jedem
Tastendruck haufenweise Zeichen verloren.


Ich weiß nicht, warum Tastenabfragen immer so kompliziert und
Ressourcen verschlingend gemacht werden müssen.

In meinen diversen Beispielen in der Codesammlung verwende ich eine
super einfache Tastenroutine für bis zu 8 Tasten, die so ganz nebenbei
im Timerinterrupt mit ausgeführt wird.

Dazu werden im Interrupt nur etwa 10µs benötigt und keine 500000µs !


Peter

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hör auf Peter!
Auf den Anwender zu warten ist wie mit einer Schnecke spazierengehen zu
wollen.

Stefan

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter
dachte es wäre net so schlimm da der tastendruck nicht oft verwendet
wird und erst danch (wenns abgeschlossen ist)soll UART was empfangen!
danke für den hinweis...!

gruß,
semo

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ähm, hätte da noch eine ("blöde") frage bzw. weiss net obs net auch
verboten is..
Wäre zum Beispiel folgendes möglich (auch wenns keine "elgante"
lösung ist):

SIGNAL(SIG_INTERRUPT0) {
  GICR=0x00;  // disables External Interrupt Request of INT0
  <"wait 4ms">
  GICR=0x40;  // enables External Interrupt Request of INT0
  <"weiter im programm">
  USART_transmit('x');
}


gruß,
semo

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
habe gerade eine leichte Doppeldeutigkeit in meinem Post gesehen. Ich
meinte natürlich, semo soll auf Dich hören, nicht dass Du aufhören
sollst, sorry.

@semo:
Verboten ist erstmal nix.
Aber es macht ja keinen Sinn, sich an einem Programm mit winziger
Funktionalität eine falsche Programmierweise anzugewöhnen, die einem
dann im Weg ist, wenn es mal aufwändiger wird.

In Deinem Programm willst Du den aktuellen IR disablen, damit andere
zwischenreinfunken dürfen, korrekt?
Dann musst Du das globale IR-Flag freischalten (nach dem disable vom
aktuellen IR).
Später musst Du globale IR wieder sperren, und erst DANACH den
aktuellen IR wieder freigeben.
Und Du musst daran denken, den Stack groß genug zu haben, dass mehrere
IR-Aufrufe Platz finden.

Das Ganze ist nicht ganz untrivial. Und ein Fehler im IR-Handling
gehört zu einem der ekligsten Dinge. Deshalb würde ich sowas nur
machen, wenn es garnicht anders geht.

Die sauberste Lösung: Tasten im Timer-IR auswerten und dem HP zur
Verfügung stellen (siehe Peters lib dazu). Genauso UART-In und
UART-Out, die ein- und ausgehenden Zeichen in Ringpuffern
zwischenspeichern. Das funktioniert auch dann noch, wenn Dein Programm
richtig kompliziert wird.

Stefan

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke Stefan!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.