Hallo,
ich lange über deinen Code gesessen und möchte dazu folgendes beitragen
Viel Text mit hoffentlikch einer Lösung ganz am Ende.
Deine Tastenabfrage kannst Du so schreiben, da brauchst Du keine Klammern, weil nur eine Anweisung folgt
if (!(PIND &(1<<PD3))) sec=1;
Diese Abfrage kommt eigentlich nur einmal in deine Interrupt Funktion, alle abderen identischen Abfragen kannst Du rausnehmen, die geben dann keinen Sinn.
Wenn die Taste betätigt wird, setzt Du ja im Interrupt dann die Variable "sec" auf 1. Diese bleibt nun solange auf 1 bis sie vom Hauptprogramm wieder auf 0 gesetzt wird.
Dies passiert bei Dir NUR in der Funktion schalten_mit bei dem Zählerstand 213 also nach einem kompletten Durchlauf mit Fussgänger. Das sieht soweit okay aus.
Ich weis jetzt nicht wie oft dein Interrupt ausgelöst wird, anhand deiner Zahlenwerte anscheinend nicht sonderlich häufig. Da könnte es mit der eben genannten Methode "nur im Interrupt" problematisch werden, also lass das vorerst mal so, das tut keinem ja weh, obwohl nicht schön.
Du könntest noch den Int Aufruf schneller machen, z.B. 10 mal schneller und deine Zeitwertabfragen auch entsprechend mit 10 multiplizieren.
Dann reicht die Tastenabfrage nur im Interrupt sicherlich aus.
Idee, aber wieder verworfen....
Könnte es sein, das an deinem Pin wo die Taste dran ist kein Widerstand nach Plus dran ist, dann bekommt er zwar eine schöne Null wenn Du die Taste drückst, aber wenn Du sie losläst hängt der Pin irgendwie inder Luft.
Gibt aber auch keinen Sinn, da der High Pegel bei Dir nie ausgewertet wird.
etwas übersichtliche ist folgende Vorgehensweise:
Code:
while(1)
{
if (sec==0) schalten_ohne(); //Ampelschaltung ohne fussgaenger
else schalten_mit(); //Ampelschaltung mit fussgaenger
switch(igr) /* den Zeitwert auswerten */
{
case 0 : rot_schalten(ein);
break; /* fertig, sprige hinter die switsch Anweisung */
case 76 : gelb_schalten(ein);
break;
case 107 : rot_schalten(aus);
gelb_schalten(aus);
gruen_schalten(ein);
break;
case 183 : gruen_schalten(aus);
gelb_schalten(ein);
break;
case 213 : gelb_schalten(aus);
igr=0;
break;
} /* ende switch */
} /* ende while */
Was fällt mir noch ein:
Ist dein Taster defekt und gibt schlechten Kontakt ?
ich davon tonnenweise rumliegen.....
dann hab ich ein ein Read Modify Write Problem gedacht, kenne ich von den PICs von Microchip her.
Port lesen Bit ändern und zurück schreiben. Dein Taster ist aber auf einem anderen Port als deine LEDs, also eher unwahrscheinlich.
Letzte Idee:
Die Variable sec wird im Interrupt gesetzt,
du hast sie als int definiert, könnte also sein, dass sie 2 Bytes belegt
Wenn nun im Hauptprogramm der Wert gesetzt wird und ein Interrupt während der Verarbeitung
der beiden Bytes auftritt, könnte das schief gehen.
Um das zu verhindern versuche mal folgendes:
Sperre die Interrupts während Du den Wert sec auf Null setzt.
Atomaren Code erzeugen nennt man das wohl, also so:
cli(); // sperre alle Interrupts
sec = 0; // setzen den Wert
sei(); //Interrupts aktivieren
vielleicht konnte ich Dir irgendwie weiterhelfen
viel Spass noch wünscht Dir
Siro
Lesezeichen