mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik IAR Interrupt


Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Ich habe eine Interruptroutine, die mit 125 kHz aufgerufen wird.
Controller ist ein Mega8515 mit 16 MHz. Programmiert wird die Software
im IAR Workbench.

Meiner Rechnung nach, habe ich ca. 180 (abzüglich dem Interruptaufruf -
sagen wir mindestens 150) Taktzyklen zeit, damit die Interruptroutine
fertig wird, bevor erneut ein Interrupt auftritt.

Bei Versuchen (mit no operation Befehlen aufgefüllt), bin ich gerade
auf 43 Taktzyklen gekommen - das ist mir aber zu wenig.

Wozu verwendet IAR die restlichen Taktzyklen (zum Sichern von
Registern?). Wie kann ich das einschränken, dass ich hier mehr Zeit
bekomme?

Vielen Dank für eure Hilfe
Steffen

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du unter den Compiler- und Linkerdirektiven die Listings
aktivierst, bekommst du ein *.map-File. Darin kannst du sehen wieviel
pushes und popps im Programm sind. Weiterhin optimiere auf Speed und
spiel etwas mit den Parametern.

Michael

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Danke für deine Antwort.
Das steht in der Mapdatei zum Interrupt:

CODE
  Relative segment, address: CODE 00000028 - 0000008B (0x64 bytes),
align: 1
  Segment part 37.            Intra module refs:   Segment part 22
           ENTRY                   ADDRESS         REF BY
           =====                   =======         ======
           Timer0_CompA            00000028
               interrupt, non_banked function
               stack 1 = 00000000 ( 00000002 )
               stack 2 = 00000000 ( 00000002 )

Ich kann leider nicht allzuviel damit anfangen.

Wenn ich auf Speed optimiere - treten bei Low seltsame Effekte auf (er
zählt falsch mit) und bei Mid und High geht die Ausgabe im Interrupt
gar nicht mehr ...

Welche Sachen brauchen denn da so viele Taktzyklen?
Steffen

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Was für eine Version von IAR benutzt du?
2. Im *.lst File mußt du bei entsprechender Einstellung deinen C-Code
sehen und parallel dazu den vom Compiler erzeugten Code. Darin siehst
du auch deine Interrupt-Routine incl. pushes und popps. Was du mir im
*.map File gezeigt hast, stimmt erst einmal mit deinen vermutungen
überein. Die Größe Hex 64 sind Dez 100.

Michael

Autor: Steffen (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich verwende die Version 3.20.1.5. Sollte eigentlich das neuste Update
sein.

Ich hab die Interrupt Routine aus dem LST File mal in den Anhang
gestellt - in der ganzen Datei befindet sich kein einziges push oder
pop ...

Viele Grüße & danke!!
Steffen

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmen die 125kHz denn ?

Was macht Dein Hauptprogramm ?


Peter

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Hauptprogramm macht nichts während dessen - Endlosschleife.

Ok, ich merke gerade, dass ich einen kleinen Denkfehler habe. Ich lasse
mittels des Compare Mode den OCA1 toggeln und den Interupt auslösen. Das
Rechtecksignal hat eine Frequenz von 125 kHz. Dh. dann wohl aber, dass
der Interrupt eine Frequenz von 250 KhZ hat - wo ich dann bei 64
Taktzyklen pro Interrupt liege. Das dürfte wohl eher hinkommen, oder?

Ich werde jetzt versuchen die 125 KHz mit dem Timer 0 zu erzeugen. Dann
sollte ich ja mehr Zeit haben ...

Grüße
Steffen

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt sieht es schon besser aus. Aber ich habe dennoch ein kleines
Problem:

Timer0 wird so initialisiert:

TCCR0 =   0x02; // Prescaler 8
TCNT0 =   0xf1;

Wenn ich nun in der Interruptroutine einen Impuls auf PORTB ausgeben
lasse und eine 16 bit Interger Variable inkrementiere, liegt die
Frequenz der Impulse laut Oszi beu 117,6 kHz. -> ich brauche aber genau
125 kHz.

Das Assemblerfile sagt, dass ich etwas 40-50 Taktzyklen brauche um die
nötigen Dinge in der Interruptroutine abzuarbeiten. Ich habe aber
mindestens 90 Taktzyklen Zeit - wo liegt jetzt schon wieder das
Problem?

Für eine kleine Idee zur Lösung wäre ich sehr dankbar.

Grüße
Steffen

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok - ich stell meine Frage nochmal anders - mit den Informationen, die
ich bisher rausgekriegt habe:

Ich habe einen Timer1 Compare Match - der toggelt OCA1 mit 250 kHz - so
dass ein Rechtecksignal mit einer Frequenz von 125 kHz entsteht.

Zusätzlich habe ich einen Timer0 Overflow, der einen Interrupt aufruft
mit 125 kHz. Dieser Interrupt erzeugt an PB0 einen kleinen Impuls.

Wenn ich beide Signale an einem 2 Kanal Oszi darstelle sollten
eigentlich beide Signale 'stehen' - also in Bezug aufeinander immer
an der selben Stelle auftreten.
Das tun sie auch solange, bis ich einen weiteren Befehl in die
Interruptroutine einfüge:
count ++;

count ist eine Integervariable. Nun verschieben sich die Signal und
eines von beiden läuft ... (je nachdem, mit welchem Signal getriggert
wird). Mein erster Gedanke: die Funktion braucht zu viel Zeit - die
folgenden Interrupts werden verzögert.

Den Befehl rausgelöscht und 35 Mal ein no operation eingefügt - siehe
da. es funktioniert wieder. Im Assemblerlisting nachgeschaut. Der
Befehl count ++; benötigt 12 Taktzyklen. Also eigentlich bedeutend
weniger ...

Dennoch wird mit dem Inkrementieren von Counter die Frequenz des Timers
auf ca. 117 kHz zurückgesetzt. Das erklärt das Laufen - aber wieso
schafft der AVR die Befehle nicht innerhalb der Interruptroutine?

Danke für Eure Mühe und Hilfe!!
Steffen

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.