Hallo zusammen,
habe ein Problem. Und zwar fällt mir nicht ein wie ich(Siehe
Dateianhang) den nächsten Wert in der Tabelle in den Akkumulator
bekomme. Habe schon versucht den dptr zu erhöhen, ohne Erfolg. Hoffe auf
eine baldige Antwort.
Gruß Peter
ISREX0: mov dptr,#frequenzcode
...
inc dptr
Das Initialisieren des dptr sollte ausserhalb der ISR erfolgen. Und es
wäre nicht verkehrt, den dptr auf die Obergrenze zu prüfen.
Hallo,
3 Möglichkeiten
dptr initialisieren, in der isr nur erhöhen; schlecht wenn du den wo
anders noch brauchst
akt. Adresse der Tabelle wo anders zwischenspeichern; in der ISR von
dort holen und nach inc wieder abspeichern
in einem Register die Tabellenposition mitzählen und in der ISR die akt.
Adresse aus Tabellenstartadresse und Zählregister berechnen
An ein Zurücksetzen der Adresse am Ende der Tabelle solltest du auch
noch denken.
Sascha
Im Moment noch nicht wichtig, aber du solltest bedenken, das deine ISR
sowohl den Akku als auch den DPTR zerstört.
Wenn du eines von beidem mal im Hauptprogramm verwendest, gibts
Probleme.
Am sinnvollsten ist vermutlich, ein Pointerbyte zu erhöhen und das in
den Akku zu laden. Dann funktioniert 'MOVC A,@DPTR+A' richtig.
Achtung, Bereichscheck ist wichtig. Wenn der Pointer grösser als 8 wird,
hast du lustige Klänge, aber keinen Ton mehr.
Hab jz mal versucht es so zu lösen, aber jetzt wird nicht mal der erste
Wert reingeladen. Bin leider noch etwas unerfahren mit Assembler, daher
wird mir das ganze noch nicht ganze schlüssig. Wäre schon wenn ich
vielleicht ein Beispiel sehen könnte, wie es funktioniert.
Gruß Peter
Du reihst da eigentlich nur wahllos irgendwelche Mnemonics aneinander.
Es wäre sicher sinnvoll, mal zu kommentieren, was du erreichen willst
und was du vermutest, was der Code tut.
Überlege doch mal, was der Code in der ISR tut:
1
ISREX0: mov dptr,#frequenzcode
2
jmp TabelleInit
3
mov A,#TabelleInit
4
mov TL0,A
5
mov TH0,A
6
reti
Der jmp Befehl z.B. ist völlig sinnlos. Auch das Laden von #TabelleInit
ist Quark.
Habs nochnmal überarbeitet und denke, dass es so vielleicht
funktionieren könnte. Jedoch wird zwar der nächste Wert wieder geladen,
aber schaffe es nicht, dass alle Frequenzen hineingeladen werden.
Also, ich verliere jetzt die Lust. Du hast immer noch keine Kommentare
drin und bei oberflächlicher Betrachtung zumindest eine sinnlose
Endlosschleife in 'TabelleInit'.
Ahoi,
Habe ein Problem und zwar verstehe ich nich bzw. habe überhaupt keine
Ahnung habe, wie ich es schaffe, das mit jedem Betätigen des Tasters,
also mit Auslösen des Externen Interrupts, der nächste Wert aus der
Tabelle in den Timer geladen wird. Hoffe auf eine baldige Antwort.
Gruß Günni
Wenn man jedesmal den selben Code laden will:
ist
ISREX0: mov dptr,#frequenzcode ;weise dptr freqenzcode zu
mov A,#0x00 ; gib Akkumulator die Adresse des
frequencodes
movc A,@A+dptr ; Hole die Konstante die abgespeichert
ist
mov TL0,A ; in TL0 laden
mov TH0,A ; in TH0 laden
reti
in der ISR sicher sinnvoll
Bist du dir sicher, daß Assembler die Programmiersprache der Wahl ist ?
Wenn man immer das gleiche macht und unterschiedliche Ergebnisse bei
einem deterministischen System wie dem Mikrocontroller erwartet ist da
schon das grundlegende Verständnis mangelhaft.
Ich will dir hier keinen Vorwurf stricken, aber dir fehlt da das
Verständnis was da passiert.
Statische Variable (kann auch bei der Einfachheit ein Register sein) und
ein Hochzählen (Überlauf abfangen) wäre für den Anfang nicht schlecht.
Die zählste dann natürlich in der ISR hoch bis zu einem maximalen Wert
und bei max wieder von vorn.
Dennis H. schrieb:> mov A,#0x00 ; gib Akkumulator die Adresse des
Statt das Register A immer mit 0 zu laden, wurde ich eine globale
Variable laden und diese vom Verlassen der Interruptroutine
inkrementieren.
ISREX0: mov dptr,#frequenzcode ;weise dptr freqenzcode zu
mov A,COUNT ; gib Akkumulator die Adresse des
frequencodes
movc A,@A+dptr ; Hole die Konstante die abgespeichert
ist
mov TL0,A ; in TL0 laden
mov TH0,A ; in TH0 laden
mov A,COUNT
add A,#1
mov COUNT,A
reti
GEKU schrieb:> Dennis H. schrieb:>> mov A,#0x00 ; gib Akkumulator die Adresse des>> Statt das Register A immer mit 0 zu laden, wurde ich eine globale> Variable laden und diese vom Verlassen der Interruptroutine> inkrementieren.>> ISREX0: mov dptr,#frequenzcode ;weise dptr freqenzcode zu> mov A,COUNT ; gib Akkumulator die Adresse des> frequencodes> movc A,@A+dptr ; Hole die Konstante die abgespeichert> ist> mov TL0,A ; in TL0 laden> mov TH0,A ; in TH0 laden>> mov A,COUNT> add A,#1> mov COUNT,A>> reti
Problematisch wirds bei Überschreiten der Array-Größe.
Definiert ist nur 0-6. Ab sieben liest er dann dahinter weiter. Kann gut
gehen. Gibt aber sicher nicht die passenden Töne wieder.
Ist ein klassischer Buffer-Overflow.
http://www.keil.com/support/man/docs/is51/is51_cjne.htm
Günni schrieb:> So habs jz so abgeändert, dass dptr ausserhalb initalisiert wird,> weiß> aber nicht wie beim Betätigen des Tasters es mit der ISR> zusammmenspielt.
anstatt der #6, #10 eigtl wegen der Anzahl der Werte in der Tabelle
Dennis H. schrieb:> Ist ein klassischer Buffer-Overflow
Ist doch auch lehrreich, oder?
Man könnte 8 Werte nehmen und vor dem Rückschreiben der Variablen den
Wert mit 7 maskieren. COUNT&=0x07;