Forum: Mikrocontroller und Digitale Elektronik AVR Interrupt Unregelmässigkeit


von Andreas (Gast)


Lesenswert?

Hallo Leute,

ich versuche nun schon eine Weile einen sauberen Interrupt zu 
programmieren. Leider habe ich immer wieder das selbe Problem. Ich 
arbeite momentan mit dem STK500, dem ATmega88P und dem AVR Studio4.

Das Programm soll jedes Mal, wenn ein externes Signal an Port D Pin 3 
anliegt in den Interrupt springen und die Addition ausführen. Dieses 
externe Signal erfolgt zyklisch als Recktecksignal.
Wenn die geforderten Winkel (2880,20160) erreicht werden, dann soll Port 
C Pin1 (V1)rückgesezt bzw. gesetzt  werden.
Sobald der IstWinkel den Wert 40000 überschritten hat, soll der 
IstWinkel wieder auf 0 zurückgesetzt werden und wieder von vorne 
hochzählen.
Wenn ich nun V1 an einem Oszi anzeigen lasse, dann treten immer wieder 
Unregelmässigkeiten auf und das Öffnen von V1 wird in unbestimmten 
Abständen übersprungen.
Das Problem hängt irgendwie mit dem IstWinkel zusammenm, ich kann mir 
aber nicht erklären woran es liegt. Ich weiß, dass die Zahl 288 nicht 
ein Vielfaches von 40000 ist, aber das dürfte eigentlich nicht das 
Problem sein.

Hier ist der Quellcode:

while(Freigabe){

  //Interrupt starten
  EIMSK|= (1<<INT1);//aktiviere INT1
  EICRA|= (1<<ISC11)|(0<<ISC10); //bei negativer Taktflanke

  //Startwinkel beim Linkslauf
  IstWinkel=0;

  //Solange der Winkel < 40° und > 0° ist->Schleife durchlaufen
  while(IstWinkel < 40000 && IstWinkel > 0){

  //Auswahl des Öffnungs- bzw. Schließwinkel von V1
  if(IstWinkel == 2880){
    PORTC &= ~(1<<V1);//Ventil wird geöffnet
    PORTC &= ~(1<<S0);
    PORTC &= ~(1<<S1);
    _delay_us(25);
    phiV1O = 2880;
  }
  if(IstWinkel == 20160){
    PORTC |= (1<<V1);//Ventil wird geschlossen
    PORTC &= ~(1<<S0);
    PORTC |= (1<<S1);
    _delay_us(25);
    phiV1S = 20160;
  }
  }//Ende (while <40000)
}// Ende while(Freigabe)


//Interrupt
ISR(INT1_vect){
  IstWinkel = IstWinkel + 288;
}


Muss ich da irgendetwas im Quellcode ändern? Ich verzweifle langsam an 
dem Problem...

Ich bin für jede Hilfe dankbar.

Gruß

Andreas

von Johannes M. (johnny-m)


Lesenswert?

Erstens ist das nicht der komplette Code.

Zweitens: Bitte formatiere den Code, so dass er besser lesbar ist. Die 
Forensoftware gibt dafür extra die Möglichkeit.

Drittens: Was für ein "Signal" löst den Interrupt aus? Mechanischer 
Kontakt (Prellen)? In dem Falle kann es mit großer Wahrscheinlichkeit 
passieren, dass der Interrupt mehrmals direkt hintereinander kommt, ohne 
dass in der Zwischenzeit die Auswertung im Hauptprogramm greift. Da wird 
aber immer auf exakte Gleichheit abgefragt, was nicht gut ist.

Viertens: Ist die Zählvariable volatile deklariert? OK, die Tatsache, 
dass es anscheinend zumindest manchmal funktioniert, spricht dafür, dass 
es daran nicht liegt.

von Andreas (Gast)


Lesenswert?

Jetzt habe ich den Fehler endlich herausgefunden...

es muss >= 0 heißen.

Es hat sich also erledigt. :)

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.