PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : externe Interrupts stören sich



Otzelott
05.04.2007, 11:27
Hallo Leute,

ich habe ein kleines Problem in meinem Programm und weiß nicht wie ich es lösen soll. Hier noch eine lurze Beschreibung wie es eigentlich funktionieren soll:

Also ich will von einem RC-Empfänger die Signale von zwei Kanälen aufnehmen und speichern. Ich benutze hierzu ein atmega32 und seine Pins für den externen Interrupt (PD2, PD3).
Das Programm soll erst anfangen aufzuzeichnen, nachdem ich an meiner Fernsteuerung für 5 Sek. voll Bremse gedrückt hab.
Das funktioniert auch, aber nur, wenn ich mit einem externen Interrupt arbeite. Sprich ich nur meine Gas- Bremskurve aufnehme.
Sobald ich den zweiten externen Interrupt it dazu nehme, werden meine beiden Signale zusammenaddiert und die Aufzeichnung startet von selbst.

Ich hoffe ich konnte es halbwegs gut erklären.

Am Anfang ist nur INT0 aktiv für Gas-/Bremse, aber trotzdem wird INT1 berücksichtigt.

GICR = 0x03; // external Interrupt enable für PD2
MCUCR = 0x03; // reagiert auf steigende Flanke

Hier nun mein Code:


// ------------------- externer Interrupt Eingang 0 --> Flankengesteuertes speicher der Zeit -----------------------

ISR(SIG_INTERRUPT0){ // externer Intterrupt
static int zaehler = 0;
static int zaehler2 = 0;
static int zaehler3 = 0;
static int Status = 0;
static int SPlatzh = 0;
static int SPlatzl = 0;
static double zeit = 0;
static double zeitanf = 0;
static double zeitend = 0;

if(ISC00 == 1){ // steigende Flanke
zeitanf = TCNT1;
MCUCR = MCUCR & 0x0E;
}

else { //fallende Flanke
zeitend = TCNT1;
MCUCR = MCUCR & 0x0F;

if (Tueber0 == 0){ // Zeitberechnung ohne Timer0_Überlauf
zeit = zeitend - zeitanf;
}

else { // Zeitberechnung mit Timer0_Überlauf
zeit = 65536 + zeitend - zeitanf;
Tueber0 = 0;
}


if (zeit>=125 && Status == 0){ // voll Bremse zählt Zähler hoch zum starten der Aufzeichnug
zaehler++;
}


if (zaehler == 350){ // nach 5 Sek. startet die Aufzeichnung
if(zaehler2 == 3){
LED2_Toggle;
zaehler2=0;
}
GICR = 0xC0; // Schaltet den externen Interrupt Int1 dazu
zaehler2++;
Status=1;
AnzBytes++;

i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(SPlatzh); // write address = 5
i2c_write(SPlatzl); // write address = 5
i2c_write(zeit); // write value 0x75 to EEPROM
i2c_stop();

if (SPlatzl<=254){ // Bei einem Low Speicherpatz größer 254 wird der High Speicherplatz um 1 erhöht
SPlatzl++;
}
else{
SPlatzl = 0;
SPlatzh++;
}

if (zeit>=125 && Status == 1){ // voll Bremse zählt Zähler hoch zum stoppen der Aufzeichnug
zaehler3++;
}
else{
zaehler3=0;
}

if (zaehler3 == 560){ // nach 8 Sek. stoppt die Aufzeichnung
GICR = 0x00; // Schaltet external Interrupt auf disable
TIMSK = 0x01; // Schaltet Timer 0 ein, restliche Timer aus
LED1_AUS;
LED2_AUS;
}

}
}

}

// ------------------- externer Interrupt Eingang 1 --> Flankengesteuertes speicher der Zeit -----------------------

ISR(SIG_INTERRUPT1){

static int SPlatzh2 = 0;
static int SPlatzl2 = 0;
static double zeit2 = 0;
static double zeitanf2 = 0;
static double zeitend2 = 0;


if(ISC10 == 1){ // steigende Flanke
zeitanf2 = TCNT1;
MCUCR = MCUCR & 0x0B;
}

else { //fallende Flanke
zeitend2 = TCNT1;
MCUCR = MCUCR & 0x0F;

if (Tueber1 == 0){ // Zeitberechnung ohne Timer0_Überlauf
zeit2 = zeitend2 - zeitanf2;
}

else { // Zeitberechnung mit Timer0_Überlauf
zeit2 = 65536 + zeitend2 - zeitanf2;
Tueber1 = 0;
}

i2c_start_wait_2(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write2(SPlatzh2); // write address = SPLatzh
i2c_write2(SPlatzl2); // write address = SPlatzl
i2c_write2(zeit2); // write value zeit to EEPROM
i2c_stop2();

if (SPlatzl2<=254){ // Bei einem Low Speicherpatz größer 254 wird der High Speicherplatz um 1 erhöht
SPlatzl2++;
}
else{
SPlatzl2 = 0;
SPlatzh2++;
}
}

}


Ich hoffe ihr könnt mir helfen !!!

Grüße

Hubert.G
05.04.2007, 12:58
Das ist kein Wunder das das nicht funktioniert, deine Interruptroutine ist viel zu lang, du darfst nur was unbedingt nötig ist in der ISR ausführen, ein Flag setzten und den Rest abhängig vom Flag im main abarbeiten.
Ob ein Fehler im Programm ist habe ich mir jetzt nicht angesehen, aber wenn die ISR 0 aufgerufen ist tut sich mehr als 8sek nichts anderes.
Hubert

Otzelott
11.04.2007, 08:53
Hi,

das mit der ISR war nur ein Fehler der im Programm war, desweiteren habe ich auch immer das komplette MCUCR Register überschrieben.

Danke!!!