Forum: Mikrocontroller und Digitale Elektronik Programm anhalten bis ein definitives Siganl anliegt


von Ronald H. (do7rh)


Lesenswert?

Ich bin gerade am Verzweifeln. Ich möchte zu beginn meines Programms
einen Funktionstest oder auch Kabeltest durchführen. Es soll zu beginn
geprüft werden, ob an PD4 und PD5 länger als z.B. 3 Sekunden ein HIGH
anliegt. Erst dann soll es weiter gehen. Ich dachte mir es ginge mit
einer if-Schleife, die ich bei HIGH Signal an beiden PORTs um einen
erhöhe und bis zum erreichen eines bestimmten Wertes eine for Anweisung
ausführen lasse. Somit ist ja aber nicht sichergestellt, das die ganze
Zeit über HIGH an beiden anliegt. Andere Idee war bei LOW wieder
runterzählen zu lassen.
Ich habe so etwas schon einmal bei einer Lichtschrankensteuerung in der
Zeitung "Funkamateur" gesehen. Da wurde zu beginn auf eine
erfolgreiche Verbindung der Lichtschranken gewartet. Leider finde ich
den Artikel nicht mehr.
Hat jemand eine Idee, wie man so was lösen könnte? Mir gefällt die Idee
mit der if-Schleife nicht so wirklich

PS: Die Interrupts sind schon belegt

von peter dannegger (Gast)


Lesenswert?

Umgekehrt denken:

Eine Variable wird im Timerinterrupt hochgezählt und in der Schleife
wird sie 0 gesetzt, sobald ein Pin low ist.

Die Schleife wird abgebrochen, sobald die Variable den Wert für 3s
überschreitet (z.B. 30 bei einem 100ms-Interrupt).


Peter

von Ronald H. (do7rh)


Lesenswert?

Umgekehrt denken ist ganr nicht mal so einfach.

Den ersten Teil habe ich nun gelöst bekommen.
Mit

while(PIND & (1 << PD6));

warte ich so lange, bis ich an PD6 ein LOW habe. Danach sollen PD 4 und
PD 5 abgefragt werden. Ich habe es mal so versucht

for ((warten = 0); (warten <= 50);)
{
   while(PIND & (1 << PD5));
   _delay_ms(100);
   while(PIND & (1 << PD4));
   _delay_ms(100);
   kabelwarten = kabelwarten +1;
}

Aber das bringt leider nicht den gewünschten Erfolg

Wie meintest du das mit dem Timerinterrupt. Welchen Timer benötige ich
dafür? Die Interrupts am µC habe ich schon durch eine Zeitmessung
belegt.
Kann ich das nicht mit einer einfachen if-Anweisung machen?
if PD5 & PD6 = LOW, dann warten + 1
else warten = 0
das alles dann wieder in eine for-Schleife wie oben?
Ich glaube ich denke immernoch falsch?!

Roanld

von Berti (Gast)


Lesenswert?

if schleifen gibts net...

do{
}
while

wär ein Ansatz!

von peter dannegger (Gast)


Lesenswert?

1
//
2
unsigned int waitcount;
3
4
do{
5
 if( !(PIND & 1<<PD5) )
6
   waitcount = 0;
7
 if( !(PIND & 1<<PD4) )
8
   waitcount = 0;
9
}while( waitcount < 30 );


Ich habe immer nen Timer laufen, der eine Art Systemzeitgeber darstellt
und alles zeitabhängige steuert.
So braucht man nicht nen Haufen Timerinterrupts sondern nur einen
einzigen für alles.
Und da drin wird dann eben auch "waitcount" hochgezählt.



Peter

von Ronald H. (do7rh)


Lesenswert?

Ich habe es jetzt etwas anders gelöst bekommen

Die überwachung, ob die 2. Schaltung angeschlossen ist mache ich mit:

while(PIND & (1 << PD6));

Solange ich hier kein LOW bekomme bleibt das Programm stehen.
Die abfrage, ob die beiden Eingänge danach auch justiert sind mache ich
mit:

for ((kabelwarten = 0); (kabelwarten <= 50);)
{                       if(PIND & (1<<PD4) && PIND & (1<<PD5))
   {
   kabelwarten = kabelwarten +1;
   _delay_ms(200);
   }
   else kabelwarten = 0;
}

Nur wenn die Schleife 50 mal ohne ein LOW durchlaufen wird, macht das
Programm weiter.

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.