-
-
Erfahrener Benutzer
Robotik Einstein
OK versuchen wir es mal ganz von vorne.
Ein Interrupt ist ein Ereignis, das von einer externen oder internen Quelle des Microcontrollers ausgelöst wird und den normalen Programmablauf unterbricht.
Der ATMEGA 32 hat eine ganze Menge von diesen Interruptquellen.
Die für Dich interessanten dürfte der ICP Interrupt sowie der INT0 bzw. der INT1 und der Timer 1 Overflow Interrupt sein.
Der Input Capture Interrupt ( ICP ) wird durch eine Zustandsänderung am ICP Pin ausgelöst. Ob das bei der steigenden oder fallenden Flanke an diesem Pin passiert ist Einstellbar.
Der Vorteil des ICP ist, das der aktuelle Zählerstand des TCNT1 Registers in das Capture Register übernommen wird, sobald ein ICP Ereignis auftritt.
Sprich die Funktion ist optimal zum messen von Zeiten geeignet.
Der INT0 bzw. 1 wird auch durch zustandsänderungen am entsprechenden Input Pin ausgelöst.
Will man ihn aber zur Zeitmessung nutzen muss der Timer TCNT1 per Software ausgelesen werden, wodurch es manchmal zu Problemen kommen kann - Überholeffekte in der Überlaufvariable des Timers 1.
Nun kommt es noch auf die maximal mögliche Periodendauer zwischen 2 Interrupts an. Ist diese Periodendauer so groß, das der maximale Zählerstand des Counters 1 ( 65535 ) überschritten wird, muß in der Timer 1 Overflow Routine eine weitere Variable hochgezählt werden, die dann das höherwertige Wort der Zeitmessung darstellt und in den ICP und INTx Routinen mit verarbeitet werden muß.
Da der Zeitpunkt vom Auftreten des Interrupts bis zum Auslesen durch die Interruptroutine immer gleich ist ( wenn man das ganz an den Anfang der Interruptroutine setzt ) kriegt man auch mit INTx sehr genaue Werte.
Die tatsächlichen Reaktionszeiten kann man wunderbar mit dem Simulator aus dem AVR Studio 4 ermitteln.
Für optimalen Speed kann man die Interruptroutinen auch in Assembler programmieren, wenn man das kann und mag.
Die umstellung des Interrupt sensing macht man sinnvollerweise im entsprechenden Interrupt.
Wurde der Interrupt durch eine steigende Flanke ausgelöst wird in der gestarteten Interuptroutine auf fallende Flanke umgeschaltet.
Die nun folgende Flanke deines Sensors wird also wieder diese Interruptroutine aufrufen, wo dann wieder auf "steigende Flanke" umgeswitched wird.
Die Auswertung der ermittelten Zeiten lass ich immer in der Hauptroutine machen.
Die entsprechede Interruptroutine ermittelt die Meßwerte, speichert diese in einer Variable ab und setzt ein Flag ( Bit Variable ).
Die Hauptroutine fragt dieses Flag ab, wenn es gesetzt ist wird des wieder zurückgesetzt und die Berechnungsroutine / Displayanzeige oder was auch immer ausgeführt.
So kriegt man schlanke Interruptroutinen und ein nachvollziehbares Programm.
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
-
Foren-Regeln
Lesezeichen