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
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 :-(
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.
@ 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.
Eine eigene Frage?
Dieser Thread ist über 18 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.