... funktionieren tut leider keins ... einzelne Prozeduren ausschalten und feststellen ... externe Interrupt in Konflikt kommt ...
Hallo Nik, vor Jahren hatte ich mal unglaublich zähe Probleme mit Interrupts. Abhilfe schaffte ich mit einem kompletten Satz ISRs - für jeden Vektor nach dem Muster
Code:
// === Nicht unterbrechbare ISR für Vektor "EINERNACHDEMANDERN"
ISR(EINERNACHDEMANDERN) // Vektor ij,
{ //
return; //
} // Ende ISR(EINERNACHDEMANDERN)
// ============================================================================= =
Wenn ich mich richtig erinnere, war das schon mal die halbe Miete. Dann wurden die ISR der Reihe nach mit einem Toggel-Bit zu einer LED versehen. Damit (und mit nem Oszilloskop) war der Schuldige schnell identifizierbar.
... nicht verstehe ist: Der INT0/1 ... höchste Priorität ... Also müsste sich doch ... genau dieser Interrupt durchsetzen ...
Jein. Im Prinzip und theoretisch hast Du völlig Recht. Aber höchste Priorität heißt nicht, dass er - ohne besondere Softwareverfahren - sonstige InterruptServiceRoutinen unterbrechen kann. Das ist per default unterbunden, kann aber durch eine Interruptfreigabe innerhalb einer ISR ermöglicht werden; Ergebnis sind dann sogenannte nested Interrupts. Nested Interrupts sind aber oft ne äusserst hinterhältige Erfindung (ich hab einen mit bester Funktion am Laufen). Langer Rede kurzer Sinn: Wenn eine ISR gerade läuft - ohne dem nested-Trick - hat selbst eine höher priorisierter Interrupt keine Aktien zu einer Unterbrechung.
Und um die lange Post noch länger zu machen: üblicherweise habe ich an meinem Codeanfang, direkt nach den Portdefinitionen und noch vor jeglicher anderen Aktion eine Routine um "irgendwelche" Interrupts bzw. Abstürze zu erkennen:
Code:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
for(i=0; i< 15; i++) // gLED2(PB5) blinken lassen bevor Interrupts erlaubt sind
{ // um ungewollte Resets u.ä. besser erkennen zu können
// 25 Schleifen um die Slaves SICHER hochfahren zu lassen
// Ab Version x60: 15 Schleifen um die Slaves SICHER hochfahren zu lassen
ClrBit(PORTC, LCg); // LED auf PC6 schalten EIN, HELL
waitms(3); // ###>>> Die onBoard-LEDs schalten K<->Portpin <<<###
SetBit(PORTC, LCg); // LED auf PC6 schalten AUS, Dunkel
waitms(97); //
ClrBit(PORTC, LCr); // LED auf PC5 schalten EIN, HELL
waitms(3); // ###>>> Die onBoard-LEDs schalten K<->Portpin <<<###
SetBit(PORTC, LCr); // LED auf PC5 schalten AUS, Dunkel
waitms(97); //
} // Ende von for(i=0; i<
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
... und diese ominöse Wait-Routine ist KEINE Bibliotheksroutine sondern ein selbst geschriebenes Ding (damit ich genau weiß, was da geschieht). Diese Routine ist aber KEIN präzises Uhrwerk!
Code:
// ============================================================================= =
// ============================================================================= =
//### Programm pausieren lassen !! Der Pausenwert ist nur experimentell !
void waitms(uint16_t ms) // Mit #define auch Aufruf wms ( ms );
{ //
for(; ms>0; ms--)
{
uint16_t __c = 4000;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
} //
} // Ende void waitms(uint16_t ms)
// ============================================================================= =
Lesezeichen