AVR Interrupt Unregelmässigkeit

Gast #779472
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
#779486
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren