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
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
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
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
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
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
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
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.