Hallo Zusammen,
Bei verschiedenen 8051-Derivaten (z.B. 8052, 80C320, usw.) wir haben
zwei DPTRs. Man muss aber ständig aufpassen, welchen DPTR verwendet
wird.
Momentan habe ich so gemacht (Keil A51, aber es ist egal):
DPTR0 macro
mov dps,#0
endm
DPTR1 macro
mov dps,#1
endm
................................
und:
DPTR0
mov dptr,<irgendwas>
dann:
DPTR1
mov dptr,<irgendwas>
Habt Ihr eine elegante Lösung dafür? z.B. etwas ähnliches: :)))
mov dptr0,<irgendwas>
und
mov dptr1,<irgendwas>
Danke,
Karoly
Mit 2 DPTRs kann man zum Beispiel Blockumladungen (kopieren) ausführen.
Quelladresse in den 1. Zieladresse in den 2. und dann immer nur DPS
umschalten, wobei DPTR jedesmal inkrementiert wird.
Nachteil beim 8051 ist wirklich, daß es nur einen inc DPTR gibt, und das
zum umschalten des DPTRs kein direkter Bitbefehl verwendet werden kann.
Vorsicht ist vorallem geboten, wenn man DPTR in einer Interruptroutine
verwendet. DPTR auf Stack und DPS (falls man Ihn verändert).
Dirk
Karoly Kovacs wrote:
> @Peter:> Ich habe wahrscheinlich nicht richtig formuliert.> Es gibt viele Programmteile, wo man alle beide DPTRs verwenden> kann/muss/usw.>> Hier ist ein Beispiel: (kopieren aus Tabelle2 in Tabelle1)>> mov dps,#0 ; selekt dptr0> mov dptr,#tabelle1> mov dps,#1 ; selekt dptr1> mov dptr,#tabelle2> mov r4,#tablen> zykl: movx a,@dptr> inc dptr> mov dps,#0 ; selekt dptr0> movx @dptr,a> inc dptr> mov dps,#1 ; selekt dptr1> djnz r4,zykl>> Es wäre viel eleganter (und SICHERER!) irgendwie so schreiben:>> mov dptr0,#tabelle1> mov dptr1,#tabelle2> mov r4,#tablen> zykl: movx a,@dptr1> inc dptr1> movx @dptr0,a> inc dptr0> djnz r4,zykl>> Karoly
Hallo Karoly,
ja, das wäre es.
Aber der 8051core wird deswegen warscheinlich nicht mehr geändert ;-)
Es gibt aber viele andere µCs, die das perfekt beherschen.
Sogar der 8086 hatte schon sehr elegante Befehle, mit automatischer
Umladung.
Dirk
Die Frage ist doch, wann braucht man mal exzessive Kopierorgien im XRAM
?
Eigentlich recht selten bis garnicht und da kann man durchaus die etwas
umständliche Art des 8051 tolerieren.
Falls man aber wirklich im extern angeschlossenen XRAM Kopierorgien
veranstalten muß, nimmt man einfach als 2. Pointer P2+R0. Das geht dann
noch schneller als mit nem 2. DPTR:
http://home.tiscali.de/peterd/appl/soft/xcopy/index.htm
Ich habe den 2.DPTR höchstens in Interrupts benutzt, damit man das
Pushen und Poppen spart.
Peter
@Peter:
Es geht nicht darum, dass der Programmierer zu blöd ist, und nicht
kennt, wie es NOCH machen kann! :)))
Also, ich muss sagen, es gibt solche Situationen, wo man diese
"Kopierorgien im XRAM" machen muss.
Ich habe auch ein Projekt, wo ich ziemlich komplizierte
Datentransformationen machen musste. (Orgelsteuerung) Die "Kopierorgie",
was ich oben geschrieben habe, war BLOß EIN BEISPIEL (das einfachste
Beispiel).
Danke aber für die nette Ideen!
(Wenn jemand noch Interesse hat, hier ist sich mein erster Versuch mit
AWK es zu "lösen" - es gehört aber noch zum Testen, u. erweitern.)
Karoly
========================================================================
===
function convert() {
if (tolower($0) ~ "dptr0") {
printf "\tmov dps,#0\n"
for (i=1;i<=NF;i++) {
printf "%s%s
",substr($i,1,index(tolower($i),"dptr0")+3),substr($i,index(tolower($i),
"dptr0")+5)
}
printf "\n"
}
else if (tolower($0) ~ "dptr1") {
printf "\tmov dps,#1\n"
for (i=1;i<=NF;i++) {
printf "%s%s
",substr($i,1,index(tolower($i),"dptr1")+3),substr($i,index(tolower($i),
"dptr1")+5)
}
printf "\n"
}
else {
print "Warning! Bad dptr usage:"
print tolower($0)
}
}
{
if (tolower($0) ~ "dptr") {
if (tolower($0) ~ "@a *\\+ *dptr") {
convert()
}
else if (tolower($0) ~ "dptr,") {
convert()
}
else if (tolower($0) ~ "@dptr") {
convert()
}
else {
convert()
}
}
else print tolower($0)
}
Peter Dannegger wrote:
> Die Frage ist doch, wann braucht man mal exzessive Kopierorgien im XRAM> ?>> Eigentlich recht selten bis garnicht und da kann man durchaus die etwas> umständliche Art des 8051 tolerieren.>
Das kommt auf die Anwendung an. Außerdem geht es nicht nur ums XRAM
sonder auch vom Programmspeicher ins XRAM.
Hatte durchaus schon Anwendungen, wo dies zum tragen kam.
> Falls man aber wirklich im extern angeschlossenen XRAM Kopierorgien> veranstalten muß, nimmt man einfach als 2. Pointer P2+R0. Das geht dann> noch schneller als mit nem 2. DPTR:>> http://home.tiscali.de/peterd/appl/soft/xcopy/index.htm>
Dann kann man aber auch gleich DPH,DPL auswechseln. Die 4 Befehle pro
Wechsel machen es dann auch nicht mehr aus.
>> Ich habe den 2.DPTR höchstens in Interrupts benutzt, damit man das> Pushen und Poppen spart.>
Das ist bei mir ebenso der häufiste Anwendungsfall.
Das ganze kann man auch mit den Registerbänken machen.
>> Peter
Dirk
Dirk Hofmann wrote:
> Dann kann man aber auch gleich DPH,DPL auswechseln. Die 4 Befehle pro> Wechsel machen es dann auch nicht mehr aus.
Na das meine ich nicht, sind immerhin 17/11 Zyklen.
Ob das Kopieren also 55% länger dauert, kann schon ein erheblicher
Unterschied sein.
Das der 2. DPTR weitgehend nutzlos ist, hat damit zu tun, daß es einfach
keine freien Befehle mehr gibt (außer 0xA5) für INC DPTR0/1, MOVX
DPTR0/1.
Aber wie schon gesagt, in Assemblerprogrammen habe ich nie größere XRAM
Kopierorgien.
Sowas braucht man nur in größeren Programmen und da lasse ich einfach
den C-Compiler sich drum kümmern.
Über 4kB Flash nehme ich keinen Assembler mehr, sonst verliere ich den
Überblick. Da muß es C sein.
@Karoly,
was machst Du mit AWK aufm 8051 ?
Ich denke, Du programmierst in Assembler.
Peter
@Peter:
Ok, wir haben es schon einmal von Dir gelesen, wir haben es endgültig
gelernt! :))) (Nur unter vier Augen frage ich: was machst Du mit
"deiner" C-Code, wenn das Programm sehr Zeitempfindlich ist?) Übrigens:
ich mag auch in C programmieren, es gibt aber solche Aufgaben, wo man
mit C "nicht zu viel" machen kann.
> Das der 2. DPTR weitgehend nutzlos ist [...]
Habe bloß eine winzige Frage: WARUM haben dann die Hersteller den
zweiten DPTR-Register "entdeckt", wenn es soooo überflässig/unbrauchbar
wäre? :)))
Oh, meine Güte!
Zum AWK: Du bist gar nicht einfacher Mensch! :)))
Also zurück zu der Grundfrage!
Ich wollte die ganze DPTR-Geschichte ein bisschen einfacher (und
sicherer!) machen. Ich habe überlegt, ob man es mit einem
Makro-Preprozessor machen könnte. Wollte aber keine "komplizierte"
Makroprozessoren, wie M4 oder anderen einsetzen (weil es hier um nur ein
Paar spezielle DPTR-Befehle geht), habe deswegen das obige Progrämmchen
als "Preprozessor" verwendet.
Aber egal, ich sehe schon, dass meine Frage völlig überflüssig, und
störend war. Ich bitte um Entschuldigung, wenn ich Dich mit meinen
blöden Fragen sooo störe.
Karoly
Karoly Kovacs wrote:
> Ok, wir haben es schon einmal von Dir gelesen, wir haben es endgültig> gelernt! :)))
Oh Gott, da ist aber einer eingeschnappt.
Wenn Du nur Deine Meinung bestätigt haben willst und keine andere hören,
dann setz Dir doch nen Heiligenschein aus blinkenden LEDs auf.
>> Das der 2. DPTR weitgehend nutzlos ist [...]
Ist meine persönliche Meinung, darf ich doch mal äußern, ist ja ein
freies Land.
Ich hab ihn einmal für nen schnellen Interrupthandler eingesetzt, sonst
nie.
> Zum AWK: Du bist gar nicht einfacher Mensch! :)))
Ich weiß nicht, was AWK ist, brauchst es mir jetzt aber auch nicht mehr
erläutern. Würde Dich damit ja nur belästigen.
> Ich wollte die ganze DPTR-Geschichte ein bisschen einfacher (und> sicherer!) machen. Ich habe überlegt, ob man es mit einem> Makro-Preprozessor machen könnte. Wollte aber keine "komplizierte"> Makroprozessoren, wie M4 oder anderen einsetzen (weil es hier um nur ein> Paar spezielle DPTR-Befehle geht), habe deswegen das obige Progrämmchen> als "Preprozessor" verwendet.
Ich weiß ja nicht, was für einen Assembler Du einsetzt.
Ich setze den Keil A51 ein und der hat ja auch schon nen Macroprozessor.
Damit könnte man bestimmt das machen, was Du willst, wenn ich bloß
wüßte, worauf Du hinaus willst.
Auch wenn ich viel poste, muß ich noch lange nicht alles wissen und
verstehen.
Aber Du willst ja nicht erläutern, worum es Dir geht, sondern nur
rummotzen.
Peter
Karoly Kovacs wrote:
> Es wäre viel eleganter (und SICHERER!) irgendwie so schreiben:>> mov dptr0,#tabelle1> mov dptr1,#tabelle2> mov r4,#tablen> zykl: movx a,@dptr1> inc dptr1> movx @dptr0,a> inc dptr0> djnz r4,zykl
Das sieht zwar auf den ersten Blick schön aus, aber Du definierst den
Standardbefehlssatz um und hast damit völlig inkompatiblen Code.
Sowas erlauben die Macros im A51 nicht, Macros dürfen nicht nach
Befehlen beginnen. Man könnte aber MOV_DPTR0 und MOV_DPTR1 usw. als
Macronamen verwenden.
Auch mußt Du dann jedesmal "mov DPS,#0" und "mov dps,#1" einfügen, d.h.
der Code wird größer und langsamer.
Der Preprozessor arbeitet ja zeilenweise, aber das Programm kann
springen, wie es lustig ist.
Warum das sicherer sein soll, erklärt sich mir nicht.
In den Beispielen im Dallas-Datenblatt wird ja auch nicht darauf Wert
gelegt, welcher DPTR nun der aktive ist, sondern es reicht völlig zu
wissen, wann der andere aktiv sein muß.
Deshalb wird dort auch "inc dps" statt "mov dps,#0/1" verwendet (spart
einen Zyklus).
Peter
Peter Dannegger wrote:
> Karoly Kovacs wrote:>>> Es wäre viel eleganter (und SICHERER!) irgendwie so schreiben:>>>> mov dptr0,#tabelle1>> mov dptr1,#tabelle2>> mov r4,#tablen>> zykl: movx a,@dptr1>> inc dptr1>> movx @dptr0,a>> inc dptr0>> djnz r4,zykl>>> Das sieht zwar auf den ersten Blick schön aus, aber Du definierst den> Standardbefehlssatz um und hast damit völlig inkompatiblen Code.>> Sowas erlauben die Macros im A51 nicht, Macros dürfen nicht nach> Befehlen beginnen. Man könnte aber MOV_DPTR0 und MOV_DPTR1 usw. als> Macronamen verwenden.>> Auch mußt Du dann jedesmal "mov DPS,#0" und "mov dps,#1" einfügen, d.h.> der Code wird größer und langsamer.> Der Preprozessor arbeitet ja zeilenweise, aber das Programm kann> springen, wie es lustig ist.>> Warum das sicherer sein soll, erklärt sich mir nicht.>> In den Beispielen im Dallas-Datenblatt wird ja auch nicht darauf Wert> gelegt, welcher DPTR nun der aktive ist, sondern es reicht völlig zu> wissen, wann der andere aktiv sein muß.> Deshalb wird dort auch "inc dps" statt "mov dps,#0/1" verwendet (spart> einen Zyklus).>>> Peter
@Peter +++
@Karoly
bin grad heimgekommen.
Jetzt beruhigt Euch mal wieder.
So bringt das ja wohl garnix.
@Peter
Wir hatten ja schon mal die Diskussion auch wegen Assembler versus C.
Mein Standpunkt ist und bleibt:
Sei gut in dem was Du tust, dann stehen viele Wege offen und einer kann
vom anderen lernen. Niemand ist over the TOP.
Ich programmiere jetzt schon über 20 Jahre.
Und meine Passion ist es weiter zu tun.
Ich denke, Du tust das auch schon eine Weile.
Glaube, wir sollten uns wirklich mal zurückversetzen und nicht den Boden
der Realität unter den Füssen verlieren.
Im Prinzip ist die Diskussion um die DPTR switcherei nur
Zeitverschwendung.
Wenn es beim 8051 befehlsmäßig so ist, dann ist es so.
Es gibt genügend andere µCs die dieses Manko nicht haben, dafür andere.
Zufrieden werden wir nie richtig sein.
Ich beschäftige mich grad nebenbei mit den TMS320C64xxx DSPs von TI.
Die machen über 28 GFLOPS.
Auch hier wird es Leute geben, die damit wieder unzufrieden sind.
Wenn wir uns mit dem beschäftigen, was maßgeblich ist und Erfolge
erzielen
die nicht auf dem Rücken der Anwender oder Kunden ausgetragen werden
auch "Bananensoftware" genannt, ist das wohl OK.
Wünsche eine geruhsame Nacht.
@Dirk: Danke für die netten Worte! (Übrigens: ich programmiere seit ca.
31.J.)
@Peter:
Entschuldige, bitte, Du hast Recht, ich habe es versehen! (Bytezahl)
> Ich setze den Keil A51 ein und der hat ja auch schon nen Macroprozessor.> Damit könnte man bestimmt das machen
Nein, leider nicht. Es kann das nicht machen.
> Sowas erlauben die Macros im A51 nicht,
Soweit hast Du Recht, das kann A51 nicht.
> Macros dürfen nicht nach Befehlen beginnen.
Hier hast Du aber nicht Recht. Wer hat es gesagt? (Ich musste meinen
"ersten" Makroprozessor in 1976 an der Uni schreiben...)
Also Makroprozessor != Makroassembler (oder Makro Preprozessor)
Siehe: http://de.wikipedia.org/wiki/Makroprozessor
(Mit einem "guten" Makroprozessor kann man "fast beliebige"
Textkonversionen machen. z.B. M4, o.ä.)
Zur AWK: http://de.wikipedia.org/wiki/Awk
AWK (und SED) sind sehr mächtige Textprozessoren.
> In den Beispielen im Dallas-Datenblatt wird ja auch nicht darauf Wert> gelegt, welcher DPTR nun der aktive ist, sondern es reicht völlig zu> wissen, wann der andere aktiv sein muß.> Deshalb wird dort auch "inc dps" statt "mov dps,#0/1" verwendet (spart> einen Zyklus).
Ja, ich weiss. (Seit 1997 programmiere ich den Dallas. Damals konnte man
"nur" den Datenblatt in Internet finden, ich habe deswegen das komplette
Buch von Dallas bestellt.)
Aber ganz exakt macht man es mit ORL und ANL maskiert, weil in anderen
Derivaten einige andere Bits auch belegt sind.
Also jetzt höre ich auf mit unserer endlose Diskussion, danke für die
nette Antworten!
Karoly
Karoly Kovacs wrote:
> Aber ganz exakt macht man es mit ORL und ANL maskiert, weil in anderen> Derivaten einige andere Bits auch belegt sind.
Dazu steht bei Dallas, daß DPS.1 immer 0 bleibt, d.h. ein "inc dps"
wechselt immer nur DPS.0 und läßt alle anderen unverändert.
Peter
Karoly Kovacs wrote:
> Und was ist mit dem AT89S8252? (zum Bleistift)
Ja, bei dem wirds höllisch kompliziert, daher habe ich solche Spielchen
sein gelassen.
Der hat ja unterschiedliche Adressen für DPH/L0 und DPH/L1 !!!
Wenn man da DPH/L berechnet (Sprungtabelle) und DPS aber falsch gesetzt
ist, stürzt dein Programm super ab.
Das nenne ich wirklich einen völlig unbrauchbaren 2.DPTR.
Peter
Peter Dannegger wrote:
> Karoly Kovacs wrote:>> Und was ist mit dem AT89S8252? (zum Bleistift)>> Ja, bei dem wirds höllisch kompliziert, daher habe ich solche Spielchen> sein gelassen.>> Der hat ja unterschiedliche Adressen für DPH/L0 und DPH/L1 !!!>> Wenn man da DPH/L berechnet (Sprungtabelle) und DPS aber falsch gesetzt> ist, stürzt dein Programm super ab.>> Das nenne ich wirklich einen völlig unbrauchbaren 2.DPTR.>>> Peter
Genau das ist das generelle Problem.
Wenn Du in einer Interrupt Service Routine den DPTR ebenfalls
verwendest,
solltest Du ihn auf dem Stack retten.
Die Frage ist, was jetzt schneller geht. Alle 4 Dxx Register auf den
Stack
(wenn man dort auch beide verwendet) oder nachschauen, welcher aktiv ist
und nur diesen zu pushen.
Version 1 geht warscheinlich schneller.
Dirk
OK, die Frage war aber nicht das!
Peter hat geschrieben:
> Atmel schreibt auch "inc AUXR1"
Ich habe dann ein Beispiel (einen Derivat) genommen, wo ich Recht habe.
:)))
(Also, beim AT89S8252 darf man weder mit "mov", noch mit "inc" den DPS
setzen.)
Karoly
Dirk Hofmann wrote:
> Die Frage ist, was jetzt schneller geht. Alle 4 Dxx Register auf den> Stack
Das nenn ich ja mal wirklich ne super ""Einsparung"" !
Statt durch den 2.DPTR 2*Push+Pop zu sparen muß ich nun 4*Push+Pop
machen.
Nene, ich weiß schon, warum ich im 8252 nie den 2.DPTR benutzte (in
meinen Assembler-Tagen und abgekündigt ist der 8252 ja auch).
Peter
Peter Dannegger wrote:
> Dirk Hofmann wrote:>>> Die Frage ist, was jetzt schneller geht. Alle 4 Dxx Register auf den>> Stack>>> Das nenn ich ja mal wirklich ne super ""Einsparung"" !>> Statt durch den 2.DPTR 2*Push+Pop zu sparen muß ich nun 4*Push+Pop> machen.>> Nene, ich weiß schon, warum ich im 8252 nie den 2.DPTR benutzte (in> meinen Assembler-Tagen und abgekündigt ist der 8252 ja auch).>>> Peter
@Peter
gemeint war, wenn Du im Hauptprogramm beide verwendest.
Kannst dann ja kaum den 2.DPTR in der ISR verwenden ohne ihn zu retten.
Außerdem!
C ist ja nun eine absolut stackorientierte Sprache und ballert vieles
drauf.
Absolute Optimierung des Programmcodes nützt also nur dort, wo dieser
auch prozentual sehr häufig ausgeführt wird.
Bei anderen Anwendungen ist die Flexibilität dann eher vordergründig.
Dirk
Karoly Kovacs wrote:
> Es wäre viel eleganter (und SICHERER!) irgendwie so schreiben:>> mov dptr0,#tabelle1> mov dptr1,#tabelle2> mov r4,#tablen> zykl: movx a,@dptr1> inc dptr1> movx @dptr0,a> inc dptr0> djnz r4,zykl
Hast Du eigentlich Deinen AWK überhaupt schonmal ausprobiert ?
Es würde mich mal interessieren, welchen Assembler er aus Deinen obigen
Zeilen erzeugt.
Da muß ja vor jedem DPTR0/1-Befehl noch ein "mov dps,#0/1" stehen und
der Code wesentlich größer sein, als wenn man ihn direkt in Assembler
schreibt.
Und dann müßte das AWK auch noch völlig anderen Code für den 8252
erzeugen, abhängig davon, welches Include Du lädst.
Daher denke ich, der Code wird nicht SICHERER!, sondern UNSICHERER.
Peter
> Und dann müßte das AWK auch noch völlig anderen Code für den 8252> erzeugen, abhängig davon, welches Include Du lädst.
Genau!
Hier ist die erzeugte Liste:
mov dps,#0
mov dptr,#tabelle1
mov dps,#1
mov dptr,#tabelle2
mov r4,#tablen
mov dps,#1 ; Fehler!
zyk: mov a,@dptr
mov dps,#1
inc dptr
mov dps,#0
mov @dptr,a
mov dps,#0
inc dptr
djnz r4,zykl
Ich habe aber NIE gesagt, dass das Programm fertig ist. (Habe oben als
"erster Versuch" gekennzeichnet. Es gibt noch Fehler, und müsste man
weiter Optimieren, die unnötige DPS-Setzen zu vermeiden - tja, das AWK
Script habe ich in ca. 15 Min. geschrieben).
Habe aber nach Deine Einträge kein Lust es weiter entwickeln. :)))
Ich bleibe bei meiner "alter" Lösung.
Karoly