Guten Morgen,
ich habe vor einer Weile angefangen mit dem 89S8253 zu programmieren.
Jetzt muss ich mal etwas zum internen RAM fragen, wo ich mir unsicher
bin,
der Controller hat ja unter der Adresse 80h bis FFh seine SFR
dann sind ja noch 128 Register frei von 00h bis 7Fh,
diese kann ich mit Assembler durch
1
RAMregister data 00h ; 8bit Register
benennen und dann kann man ja noch einzelne Pins benennen
1
RAMpin data 00h ; 1bit Pin
das high ("1") oder low ("0") ist, kann ich ein Register und einem Pin
im RAM gleichzeitig die Adresse 00h geben, so das sie unabhängig
voneinander verwendet werden können?
Wie sieht das aus mit dem EEPROM, wenn ich Daten in das EEPROM laden
möchte, dann werden ja auch Daten im (x)RAM hinterlegt, kann es
irgendwelche Konflikte geben?!
(Mit Konflikten meine ich, das die Daten in irgendeiner Form in der
gleichen Adresse die ich für Pins und Register verwende hinterlegt
werden)
Ich speicher immer einzelne 8bit Daten im EEPROM, also ich verwende
nicht diese bis 32 Byte Abspeicherung.
Ich bedanke mich im Voraus für eure Antworten!
Dome
Der EEPROM-Bereich ist unabhämgig vom (X)RAM Bereich, auch bei gleichen
Adressen.
Der bitadressierbare Bereich überlappt den RAM Bereich, allerdings ist
bit 0 nicht auf byte 0, sondern byte 0x20 (32).
Das ist ein Feature, damit man denselben Wert sowohl als ganzes Byte als
auch als jedes der einzelnen Bits ansprechen kann.
Solche Grundlagen stehen schon in Wikipedia
http://de.wikipedia.org/w/index.php?title=Datei:MFrey_Internal_RAM_MCS-51-DE.svg&filetimestamp=20070609072126
> dann sind ja noch 128 Register frei von 00h bis 7Fh,
Diese RAM-Adressen sind direkt addressierbar (z.B. mov 020h, #0AAh),
aber sie sind die untere Hälfte des kompletten RAMs von 256Byte. Die
andere Hälfte liegt wie die SFR von 0x80 bis 0xFF, ist aber nur
indirekt adressierbar (d.h. über die Pointer-Register R0 oder R1), die
SFR sind nur direkt adressierbar. Die untere RAM-Hälfte kann sowohl
direkt als auch indirekt adressiert werden.
> benennen und dann kann man ja noch einzelne Pins benennen
Nicht Pins, sondern Bits. Die bit-adressierbaren Bytes liegen im Bereich
von 0x20 bis 0x2F, also 16 Bytes = max. 128 Bits.
Zuätzlich kann man noch alle SFR-Bytes, deren Adressen ohne Rest durch
acht teilbar sind auf diese Art "umbenennen".
> RAMpin bit 00h ; 1bit Pin
Mich wundert dass dein Assembler 00h akzeptiert, meiner wollte immer
einen Offset von 20h drauf haben, also erstes Bit bei 20h.
> kann ich ein Register und einem Pin im RAM gleichzeitig die Adresse 00h #> geben, so das sie unabhängig voneinander verwendet werden können?
Klarstellung: Du kannst einem Register oder einem BIT keine Adresse
zuweisen, aber du kannst eine Byte- oder Bit-Variable an einer
bestimmten Stelle im Speicher ablegen. Ein kleiner, aber feiner
Unterschied :)
Die Unterscheidung ob es ein Bit oder Byte ist, wird durch den Befehl
erkannt, also gibt's keine Überlappungen.
Das gleiche gilt für die oben erwähnte RAM-/SFR-Adressierung, der
Controller weiss anhand Adressierung & Adresse wo's hinsoll, also auch
hier keine Überlappung.
> Wie sieht das aus mit dem EEPROM, wenn ich Daten in das EEPROM laden> möchte, dann werden ja auch Daten im (x)RAM hinterlegt, kann es> irgendwelche Konflikte geben?!
Sie werden nicht im XRAM hinterlegt, sondern der Mechanismus, mit dem
man das XRAM anspricht wird für's EEPROM verwendet. Lies das
EEPROM-Kapitel nochmal: Vor dem EEPROM-Zugriff wird ein Flag gesetzt,
mit dem das XRAM ab- und dafür das EEPROM eingeschaltet bzw. an die
Adresse vom XRAM gesetzt wird. Das nennt man "Mapping".
Alles in allem bzw. kurz und bündig: Wenn du's richtig machst gibt's
keine "Doppelzugriffe" :)
Ralf
Danke für die schnellen Antworten, ich habe das grade mal so versucht:
1
register data 00h // ist bzw. entspricht Register0
2
bit1 bit 00h
3
4
clr bit1
5
mov register,#0FFh
6
7
start: cjne r0,#0FFh,start
8
jb bit1,start
9
clr ledrot // schaltet die rote LED an
10
ljmp start
(wenn ich den Wert ändere, der im Register steht oder wenn ich das bit
nicht auf "0" Setze, dann geht die LED nicht an)
das würde doch heißen, das mein "Bit" das ich verwende und das
"Register" nicht gehen würde, wenn ich das richtig verstanden habe?!
Aber es Funktioniert, er möchte kein Offset, also das ich das bit auf
0x20 lege, ich Programmier mit Keil uVision 4.
> (wenn ich den Wert ändere, der im Register steht oder wenn ich das bit> nicht auf "0" Setze, dann geht die LED nicht an)
Korrekt, weil sowohl das Byte/Register als auch das Bit nicht den
Prüfbedingungen entsprechen.
> das würde doch heißen, das mein "Bit" das ich verwende und das> "Register" nicht gehen würde, wenn ich das richtig verstanden habe?!
Kannst du das mit anderen Worten ausdrücken? Mir ist grad nicht klar,
was dein Satz aussagen soll oO
Falls du meinst, dass es nicht geht, weil du entweder das Register
oder das Bit änderst, das liegt daran, dass du durch deinen
Programmablauf eine Ver-UND-ung geschaffen hast, d.h. sobald entweder
das Register oder das Bit nicht zutreffen leuchtet die LED auch nicht.
Wenn du eine Ver-ODER-ung machen möchtest, dann sollte es ungefähr so
aussehen:
1
start: cjne r0,#0FFh,tstbit
2
jmp ledon
3
tstbit: jb bit1,start
4
ledon: clr ledrot // schaltet die rote LED an
5
ljmp start
Das sollte bewirken, dass sobald entweder das Register oder das Bit
zutreffen, die LED leuchtet. Umgekehrt heisst das, wenn du nur _eines
der beiden ändert, leuchtet's trotzdem...
> Aber es Funktioniert, er möchte kein Offset, also das ich das bit auf> 0x20 lege, ich Programmier mit Keil uVision 4.
Was DU möchtest, ist dem verwendeten Assembler egal :) Wenn ER die
Bitadresse mit Offset haben will, dann isses so. Wenn nicht, auch gut.
Ralf
@Ralf
Also zu dem Programm:
cjne R0,#0FFh,start
wenn R0 nicht 0FFh hat dann springt er zu start, in dem Fall würde das
Programm immer bei:
start: cjne R0,#0FFh,start
bleiben und bei
jb bit1,start
würde das Programm wenn "bit1" high wäre immer zu start springen.
Das heißt, wenn ich "bit" und "Register" beide im RAM auf 00h hätte wäre
das ja der gleiche RAM speicherplatz (wenn ich das nicht falsch
verstanden habe)
register data 00h
bit1 bit 00h
Das würde heißen, wenn ich in bit1 oder im Register eines der beiden
ändere, dann beeinflusst das ja das andere. (oder?)
Und wenn ich jetzt das bit1 auf low setze und das register auf 0FFh und
wenn das bit1 ein teil von dem Register ist, weil beide auf 000h im RAM
weisen, dann muss ja zwangsweise bit1 auf high gesetzt werden.
clr bit1
mov register,#0FFh
Und es benötigt an bit1 ein low, da sonst die LED nie leuchten würde,
verstehst du was ich meine?
> Das heißt, wenn ich "bit" und "Register" beide im RAM auf 00h hätte wäre> das ja der gleiche RAM speicherplatz (wenn ich das nicht falsch> verstanden habe)
Hast du aber falsch verstanden :) Nochmal: Der bitadressierbare
Speicherbereich beginnt bei dem Byte an Adresse 20h.
Das heisst:
1
bit1 bit 00h
wird wahrscheinlich von deinem Assembler an Adresse 20h angewendet.
Wenn du allerdings das hier machst:
1
register data 20h
2
bit1 bit 00h
...dann sollten sich tatsächlich beide überschneiden, da "bit1" dann das
Bit0 von "register" ist.
Prüfen kannst du das, indem du:
1. register auf 0xFF setzt
2. bit1 löschst
3. im Programm auf 0xFE (Bit0 gelöscht) prüfst
Ralf
Jetzt kommt der AHA Effekt ;-)
Ja, mich hatte das verwirrt, das die bits ab 20h anfangen und ich hab
gedacht das ich dann irgendwie name bit 20h machen muss und dann hab ich
mich wieder gewundert, da ich ja dann doch das Byte anspreche und so
lach
Ok jetz weiß ichs, vielen Dank =)
Und wenn ich jetzt keine bits verwenden würde, dann könnte ich den
speicherplatz der bits als Bytes verwenden in dem ich 20h bis 2Fh
verwende?
> Jetzt kommt der AHA Effekt ;-)
Das war mein Ziel :)
> Ja, mich hatte das verwirrt, das die bits ab 20h anfangen und ich hab> gedacht das ich dann irgendwie name bit 20h machen muss und dann hab ich> mich wieder gewundert, da ich ja dann doch das Byte anspreche und so
Ich vermute dein Assembler (Keil?) ist so nett, dir den Offset
abzunehmen, da der Bit-Bereich eine eigene Adressangabe im Linker hat
(und damit den Offset "heimlich" drauf addieren kann).
> Ok jetz weiß ichs, vielen Dank =)
Gerne.
>> Und wenn ich jetzt keine bits verwenden würde, dann könnte ich den>> speicherplatz der bits als Bytes verwenden in dem ich 20h bis 2Fh>> verwende?> Ja, es geht =)
Es kommt sogar noch besser: Du kannst das gleichzeitig machen, wenn es
denn sinnvoll ist, da es dann ein Byte und auch ein Bitcontainer ist.
Wenn du beispielsweise ein Byte über die serielle Schnittstelle
bekommst, mit dem du bestimmte Portbits setzen musst und die Portbits
nicht demselben Port angehören, kannst du die Bits einzeln auslesen.
Das Schema an sich wird gern verwendet, um eben einzelne Bits,
beispielsweise in einer Statusvariablen, gezielt setzen zu können, ohne
mit aufwendigem ver-UND-en und ver-ODER-n auskommen zu können.
Ralf