Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage zum internen RAM des 89S8253


von Dome (Gast)


Lesenswert?

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

von Dome (Gast)


Lesenswert?

Ach halt, bei der Benennung des Pins mache ich das so:
1
RAMpin  bit  00h   ; 1bit Pin

mein Fehler g

Dome

von MaWin (Gast)


Lesenswert?

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

von Ralf (Gast)


Lesenswert?

> 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

von Dome (Gast)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

> (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

von Dome (Gast)


Lesenswert?

@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?

von Ralf (Gast)


Lesenswert?

> 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

von Dome (Gast)


Lesenswert?

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?

von Dome (Gast)


Lesenswert?

Ja, oke sorry is ne dumme Frage ^^

Ja, es geht =)

von Ralf (Gast)


Lesenswert?

> 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

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
Noch kein Account? Hier anmelden.