www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mikrocontrollers Eingang bestimmten Impuls abfragen


Autor: Hans Bernd (baggy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
würde gerne den Eingang eines Mikrocontrollers überwachen.
Dieser Eingang wird z.B. alle 60s durch einen Taster kurz auf low 
gesetzt. Wenn jetzt dieser Impuls eine Zeit ausbleibt, soll ein Ausgang 
auf high gesetzt.
Kann mir jemand einen groben Programmablauf in c zeigen.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Kann mir jemand einen groben Programmablauf in c zeigen.

 timeoutTaster++;
 if(timeoutTaster > TIMEOUT) schalteausgang();

SCNR ;)

Autor: Hans Bernd (baggy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieser Ablauf zählt doch timeoutTaster hoch und sobald er > TIMEOUT ist, 
wird geschaltet.
Bei diesem Ablauf wird doch die Zeit nicht berücksichtigt, oder?

Autor: Tom M. (tomm) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde den Taster an einen Pin anschliessen, der als Interruptquelle 
dienen kann. Dann ISR einrichten, welcher auf High-Low Übergang an 
diesem Pin reagiert und ein Flag setzt. Ggf. Timer für zweite ISR neu 
initialisieren, damit dieser asap feuert.

Eine weitere ISR könnte 1x/Sekunde auslösen (Timer verwenden) und die 
Sekunden hochzählen bzw. neu bei 0 beginnen, wenn das Flag gesetzt ist.

Im main wäre dann Schlafen angesagt. Wenn ISRs laufen, wacht die CPU auf 
(main loopt also einmal) und du testest kurz den Sekundenzähler und 
machtst abhängig davon $WASIMMERDUWILLST.

"programming left as an excercise to the reader"... ;-)

Autor: Hans Bernd (baggy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht das so?
Solange e<60 ist wird hochgezählt. Also 60Sekunden.
Nach 60s wird PORTC.5 auf high gesetzt, falls nicht ein Interrupt 
ausgelöst wird, welcher e auf 0 setzt.

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
int e;
e=0;
}


// Declare your global variables here
int t=1000;
int e=0;
while (1)
      {
      if (e < 60) e = e++;
      delay_ms(1000);
      if (e > 60) PORTC.5 = 1;
      else PORTC.5=0;
      };
}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom M. schrieb:
> Ich würde den Taster an einen Pin anschliessen, der als Interruptquelle
> dienen kann. Dann ISR einrichten, welcher auf High-Low Übergang an
> diesem Pin reagiert und ein Flag setzt.

So würde ich es gerade nicht machen!

Der Taster prellt und die Leitung zum Taster kann sich Störungen 
einfangen.
Man braucht eine Entprellsoftware, um den Taster abzufragen.

Den Interrupt (Pin-Change-Interrupt) könnte man bestenfalls bei 
Batteriebetrieb nur zum Aufwachen benutzen.


Peter

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hans Bernd schrieb:
> Dieser Ablauf zählt doch timeoutTaster hoch und sobald er > TIMEOUT ist,
> wird geschaltet.
> Bei diesem Ablauf wird doch die Zeit nicht berücksichtigt, oder?

Wenn der ganze Vorgang exakt jede 1 Sekunde abläuft, dann wird die Zeit 
sehr wohl indirekt berücksichtigt.
Der Wert in timeoutTaster ist dann ein direktes Mass für die Zeit, die 
verstrichen ist, seit timeoutTaster zuletzt auf 0 gesetzt wurde.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hans Bernd schrieb:
> Geht das so?

Nein.
Das e in ext_int0_isr ist ein anderes e als das in ... ja wo eigentlich? 
Du hast keine main Funktion. Aber egal, das e in ext_int0_isr ist auf 
jeden Fall ein anderes als jedes andere e in deinem Programm.

Aber abgesehen davon würde das schon funktionieren.
Die Zeit wird unter Umständen nicht besonders genau sein, aber wenn es 
auf 1 Sekunde mehr oder weniger nicht ankommt ....

Autor: Hans Bernd (baggy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kann ich denn mit dem Interrupt mein e aus dieser Funktion
auf 0 setzten?
while (1)
      {
      if (e < 60) e = e++;
      delay_ms(1000);
      if (e > 60) PORTC.5 = 1;
      else PORTC.5=0;
      };
}

Autor: Hans Bernd (baggy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit volatile müsste die Variable zaehler ja sowohl im Interrupt als auch 
im Programm die Gleiche sein.


volatile int zaehler;

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
zaehler=0;
}

while (1)
      {
      if (zaehler < 60) zaehler++;
      delay_ms(1000);
      if (zaehler > 60) PORTC.2 = 1;
      else PORTC.5=0;
      };
}

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.