G' Morgen, ich hab' das Forum schon durchsucht und zwei Beiträge zu meinem Problem gefunden - leider konnte die mir nicht weiterhelfen. Ich habe einen Assemblercode wie folgt : [avrasm] .include "definition.inc" .org 0x000 rjmp Initialize .org 0x00b rjmp PortB .org 0x10 rjmp PulseWidthModulation Initialize: ldi Register, 0xff ; Stackpointer initialisieren out 0x3d, Register ldi Register, 0x02 out 0x3e, Register ldi Register, 0x80 ; Systemclock dividieren sts 0x61, Register ldi Register, 0x08 ; auf 78,125kHz sts 0x61, Register Timer0: ; steuert die Pulseweite ldi Register, 0x01 ; Overflow - Interrupt setzen sts 0x6e, Register ldi Register, 0x01 ; Clock dividieren out 0x25, Register Timer1: ldi Register, 0x02 ; Interrupt freigeben sts 0x70, Register ldi Register, 0x41 ; COM2A0=1; COM2A1=0; WGM0=1; WGM1=0; WGM2=0; sts 0xb0, Register ldi Register, 0x01 sts 0xb1, Register PortB_Aus: ldi Register, 0x03 out 0x04, Register sei Slave: rjmp Slave PulseWidthModulation: push Counter andi Counter, 0xff cpi Counter, 0xff breq SetPulseWidth pop Counter inc Counter reti SetPulseWidth: push Value mul Value, Value sts 0xb3, R0 andi Value, 0x0f cpi Value, 0x0f breq ResetValue pop Value inc Value reti ResetValue: pop Value ldi Value, 0x00 reti PortB: ldi R17, 0x02 in Register, 0x05 eor Register, R17 out 0x05, Register reti [\avrasm] Ich bekomme eine Fehlermeldung : "Invalid Opcode 0xffff at address 0x000007". Wo genau soll denn da mein Fehler sein? Kann mir da jemand einen Tipp geben? Vielen Dank im voraus lg Torsten
Nein, das scheint ihn nicht zu stören. Ich hab's mal geändert, passiert das gleiche. lg Torsten
Hi! Ich sehe auf anhieb auch keinen Fehler. Aber vereinfach doch mal den Code. Wenns dann geht, bau immer mehr Teile dazu. Bis der Fehler wieder kommt. dann kannst du den Fehler schonmal eingrenzen.
Das Problem dürfte auf daran liegen, dass irgendwie der Rücksprung aus dem Interrupt schiefgeht, oder dass irgendein Interrupt aktiv ist, der an Adresse 0007 springt. Da du aber derart lese freundlich programmierst, und auch immer schön die Registernamen verwendest und natürlich auch den AVR angegeben hast, den du verwendest habe ich keine Lust jetzt alle Datenblätter danach zu durchsuchen was das nicht passen könnte.
Ich habe das Problem gefunden. Ich habe den Quellcode Stück für Stück neu eingegeben und der Fehler tritt erst auf, wenn ich den Befehl "sei" verwende. Es handelt sich um einen ATmega48. Sorry, wegen der Unleserlichkeit. Gibt es denn eine andere Möglichkeit alle Interrupts global freizugeben? lg Torsten
muß man nicht auch ein paar Register retten in der ISR? Oder ist das nur beim PIC nötig gewesen ... (sorry - Atmel-Programmierung liegt inzwischen etwas zurück bei mir :-(
oder Du hast die falschen ISR-Sprungadressen mit den rjmp's gefüllt am Anfang ...
Torsten Ohne wrote: > Es handelt sich um einen ATmega48. Sorry, wegen der > Unleserlichkeit. Schau mal ins Datenblatt: Adresse 7 ist der OC2A Interrupt, und genau den aktivierst du. Was lernen wir daraus? Anstelle der Adressen die in der Include File definierten Labels und Registernamen verwenden. Dann kann man das Programm besser lesen, vermeidet solche Fehler, und man kann das Programm leichter auf einen anderen AVR anpassen.
Das mit dem Retten der Register ist ein gutes Argument, das hatte ich auch vergessen - danke. Das kann aber auch nicht der Fehler sein, da er auftritt sobald der Interrupt aufgerufen wird. @Jens : Was meinst du mit "falsch gefüllt"? Ich gebe ihm doch mit dem Befehl .org 0x0b ; Interrupt für TIM1_COMPA rjmp SpringeZuInterruptRoutine die Anweisung. Kann ich da auch etwas falsch machen? lg Torsten
@Benedikt : Aber Adresse 7 spreche ich doch gar nicht an? Ich habe doch die 0x0b angesprochen? Kann es sein, dass ich da bei der Programmieren was falsch verstanden habe? Ich dachte, ich dem Controller einfach die entsprechende Interruptnummer geben und ihm sagen springe beim Auslösen an die gewünschte Stelle im Quellcode? grübel lg Torsten
Torsten Ohne wrote: > @Benedikt : Aber Adresse 7 spreche ich doch gar nicht an? Du machst das nicht, aber der AVR, wenn er den OC2A Interrupt ausführt.
Hm... okay, ich sollte mal euren Rat annehmen wegen der Register. Ich danke euch für eure Hilfe. lg Torsten
@ Torsten Ohne (tome28) >@Jens : Was meinst du mit "falsch gefüllt"? Ich gebe ihm doch mit dem >Befehl eigentlich genau das, was Benedikt gerade vorher sagte. Offensichtlich hast Du den OC2A Interrupt aktiviert, der lt. Benedikt auf Adresse 0x7 seine ISR Routine vermutet, der aber in deinem Coding leer ist (nicht initialisiert, deswegen 0xFFFF als invalid Opcode
Im AVR-Studio gibts übrigens eine durchaus nützliche Einrichtung, die sich "Simulator" nennt. Damit soll man der Ursache solcher Probleme sehr schnell auf die Spur kommen können. Mal ausprobieren, was das für ein Wunderding ist? >ldi Register, 0x03 >out 0x04, Register Kein erfahrener Programmierer auf der Welt pflegt einen solchen Codierstil. Vielleicht hast Du Lust, über mögliche Gründe dafür selbst nachzudenken.
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.