Forum: Mikrocontroller und Digitale Elektronik externes RAM per ASM ansteuern


von Bruno M. (brumay)


Lesenswert?

Hallo,
ich habe wieder mal ein Problem, bei dem ich nicht weiterkomme.
Ich habe eine Schaltung mit ATmega162, 74HCT573 und einem 32k Speicher 
AS7C256. Mit Hardware Interface funktioniert die Schaltung. Für 
Testzwecke versuche ich das nun mit einer ASM Software Lösung.
1
Write:
2
sbi    PORTD, WR    ; Write auf high
3
sbi    PortE, 1    ; ALE auf high
4
clr    temp
5
out    PortC, temp    ; Ausgabe High Adressen
6
ldi    temp, 0x0F      
7
out    PortA, temp    ; Ausgabe Low Adressen  
8
cbi    PortE, 1    ; ALE auf low, Adresse wird gehalten
9
cbi    PORTD, WR    ; Write auf low
10
ldi    Data, 0b01010101        
11
out    PortA, Data    ; Daten werden bereitgestellt
12
sbi    PORTD, WR    ; Write auf high
13
nop
14
sbi    PortE, 1    ; ALE auf high
15
ret
16
17
;**************************************************************************
18
Read:
19
sbi    PortE, 1    ; ALE auf high
20
clr    temp
21
out    PortC, temp    ; Ausgabe High Adressen
22
ldi    temp, 0x0F      
23
out    PortA, temp    ; Ausgabe Low Adressen
24
cbi    PortE, 1    ; ALE auf low, Adresse wird gehalten
25
sbi    PORTD, WR    ; Write auf high
26
clr    temp              
27
out    DDRA, temp    ; Alles Eingang
28
in    Data, PinA    ; Daten abholen
29
nop
30
sbi    PortE, 1    ; ALE auf high
31
32
mov    temp, Data
33
rcall  uart_transmit
34
ret

CE hängt an PortC7 und ist damit immer low.

Das Problem ist, daß ich beim Lesen immer die Adresse von PortA bekomme 
und nicht die Daten.
Was mache ich falsch?

von Jens G. (jensig)


Lesenswert?

Bruno M. schrieb:
> Das Problem ist, daß ich beim Lesen immer die Adresse von PortA bekomme
> und nicht die Daten.

Weil Du PortA+C für die Adressen benutzt. Warum sollen auf A dann Daten 
liegen?

: Bearbeitet durch User
von Monk (roehrmond)


Lesenswert?

Bruno M. schrieb:
> in    Data, PinA    ; Daten abholen

Was ist denn Data? Du musst an dieser Stelle ein register angeben, zum 
Beispiel
> in r16,pina

Ich bin unsicher, ob die Groß/Kleinschreibung von PinA hier eine Rolle 
spielt. Als ich meine AVR noch in Assembler programmierte, hatte ich die 
Registernamen jedenfalls immer klein geschrieben.

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Jens G. schrieb:
> Weil Du PortA+C für die Adressen benutzt. Warum sollen auf A dann Daten
> liegen?

Er könnte einen Multiplexer verwenden, um Daten und Adressen zu trennen, 
aber vergessen haben, den in seinem Code anzusteuern ...

von Bruno M. (brumay)


Lesenswert?

Jens G. schrieb:
> Bruno M. schrieb:
>> Das Problem ist, daß ich beim Lesen immer die Adresse von PortA bekomme
>> und nicht die Daten.
>
> Weil Du PortA+C für die Adressen benutzt. Warum sollen auf A dann Daten
> liegen?
Weil dafür eigentlich der 74HCT573 sorgen muß, der mit ALE gesteuert 
wird.

von Bruno M. (brumay)


Lesenswert?

Monk schrieb:
> Bruno M. schrieb:
>> in    Data, PinA    ; Daten abholen
>
> Was ist denn Data? Du musst an dieser Stelle ein register angeben, zum
> Beispiel
>> in r16,pina

Data ist R17! Groß- und Kleinschreibung spielt keine Rolle.

von S. L. (sldt)


Lesenswert?

Ich sehe nirgendwo D7 in §Read:
'PD7 RD (Read strobe to external memory)'

von Heiner B. (karadur)


Lesenswert?

Was machst du mit /OE?  Wenn /CE und /OE dauerhaft auf low sind hast du 
mit /WR auf High einen Konflikt am Port A

von Bruno M. (brumay)


Lesenswert?

S. L. schrieb:
> Ich sehe nirgendwo D7 in §Read:
> 'PD7 RD (Read strobe to external memory)'
1
A write cycle is accomplished by asserting chip enable (CE) and write enable (WE) LOW. Data on the input pins I/O0-I/O7 is
2
written on the rising edge of WE (write cycle 1) or CE (write cycle 2). To avoid bus contention, external devices should drive
3
I/O pins only after outputs have been disabled with output enable (OE) or write enable (WE).
4
A read cycle is accomplished by asserting chip enable (CE) and output enable (OE) LOW, with write enable (WE) high. The
5
chip drives I/O pins with the data word referenced by the input address. When chip enable or output enable is high, or write
6
enable is low, output drivers stay in high-impedance mode.

Auszug aus dem Datenblatt!

von S. L. (sldt)


Lesenswert?

> ... read cycle is accomplished ... and output enable (OE) LOW

Und wo im Programm geschieht das?

von Bruno M. (brumay)


Lesenswert?

Ich glaube, ich habe den Fehler gefunden. Ich habe mir bei dieser 
Gelegenheit den Datenblattauszug nochmals durchgelesen:
1
A write cycle is accomplished by asserting chip enable (CE) and write enable (WE) LOW. Data on the input pins I/O0-I/O7 is
2
written on the rising edge of WE (write cycle 1) or CE (write cycle 2).

Wenn ich das richtig interpretiere, muß ich zuerst die Daten in den 
74HCT573 schieben und dann erst die Adresse und nicht umgekehrt!

von Bruno M. (brumay)


Lesenswert?

Sorry, das war Unsinn!

von Jens G. (jensig)


Lesenswert?

Bruno M. schrieb:
>> Weil Du PortA+C für die Adressen benutzt. Warum sollen auf A dann Daten
>> liegen?
> Weil dafür eigentlich der 74HCT573 sorgen muß, der mit ALE gesteuert
> wird.

Ok, konnte grad das ALE nicht zuordnen.

Bruno M. schrieb:
> CE hängt an PortC7 und ist damit immer low.

Und was ist mit /OE bei Latch und RAM?

von Jens G. (jensig)


Lesenswert?

Heiner B. schrieb:
> Was machst du mit /OE?  Wenn /CE und /OE dauerhaft auf low sind hast du
> mit /WR auf High einen Konflikt am Port A

So meinte ich das ...

von Bruno M. (brumay)


Lesenswert?

S. L. schrieb:
>> ... read cycle is accomplished ... and output enable (OE) LOW
>
> Und wo im Programm geschieht das?

Das ist hardwaremäßig fest verdrahtet!

von Bruno M. (brumay)


Lesenswert?

Jens G. schrieb:
> Heiner B. schrieb:
>> Was machst du mit /OE?  Wenn /CE und /OE dauerhaft auf low sind hast du
>> mit /WR auf High einen Konflikt am Port A
>
> So meinte ich das ...

Kannst du das näher erklären! Wo ist da ein Konflikt?

von Jens G. (jensig)


Lesenswert?

Bruno M. schrieb:
> Jens G. schrieb:
>> Heiner B. schrieb:
>>> Was machst du mit /OE?  Wenn /CE und /OE dauerhaft auf low sind hast du
>>> mit /WR auf High einen Konflikt am Port A
>>
>> So meinte ich das ...
>
> Kannst du das näher erklären! Wo ist da ein Konflikt?

Weil sowohl PortA als auch IO des RAM im write-Code gleichzeitig kurz 
"outputen", solange WE=H

: Bearbeitet durch User
von Bruno M. (brumay)


Lesenswert?

Jens G. schrieb:
> Weil sowohl PortA als auch IO des RAM gleichzeitig kurz "outputen"

Das kann eigentlich nicht sein, da ich DDRA auf Eingang stelle, bevor 
ich die Daten einlese.

von Bruno M. (brumay)


Lesenswert?

Jens G. schrieb:
> Weil sowohl PortA als auch IO des RAM im write-Code gleichzeitig kurz
> "outputen", solange WE=H

Du meinst, ich sollte WE früher auf low ziehen?

von Bruno M. (brumay)


Lesenswert?

Bruno M. schrieb:
> Du meinst, ich sollte WE früher auf low ziehen?

Ich habe es mal versucht, aber keine Änderung.

von Heiner B. (karadur)


Lesenswert?

Ich kenn den ATmega162 nicht aber die 80xx. So wie ich im Manual des 162 
es verstehe kann man mit Steuerregistern das externe Interface für den 
XMEM aktivieren. Danach müßte das Interface die Steuersignale selbst 
generieren.
Insbesondere werden die Datenrichtungsregister überschrieben.
Würde für mich auch keinen Sinn machen wenn man bei XMEM die 
Steuersignale noch selbst erzeugen müßte.

von Bruno M. (brumay)


Lesenswert?

Heiner B. schrieb:
> es verstehe kann man mit Steuerregistern das externe Interface für den
> XMEM aktivieren

Das ist völlig richtig und wie ich eingangs geschrieben habe 
funktioniert die Schaltung wenn ich XMEM nutze. Ich brauche die 
Softwarelösung aber für ein anderes Problem.

von Tim S. (Firma: tsx89) (freak_ts) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> in    Data, PinA    ; Daten abholen

Warum nur(?) PinA?? Sorry hab keine Ahnung...

von Peter D. (peda)


Lesenswert?

/OE des RAM kommt an /RD von der CPU.
Nur vor dem Lesen wird /RD=0 und danach /RD = 1.
Beim Adresse laden und beim Schreiben muß /RD = 1 bleiben.

von Bruno M. (brumay)


Lesenswert?

Peter D. schrieb:
> /OE des RAM kommt an /RD von der CPU.
> Nur vor dem Lesen wird /RD=0 und danach /RD = 1.
> Beim Adresse laden und beim Schreiben muß /RD = 1 bleiben.

Ich zitiere nochmals das Datenblat:
quote
A read cycle is accomplished by asserting chip enable (CE) and output 
enable (OE) LOW, with write enable (WE) high.
unquote

Ein RD kommt darin nicht vor.

von S. L. (sldt)


Lesenswert?

> Ein RD kommt darin nicht vor.

Und was ist RD anderes als OE - Output Enable?

von Heiner B. (karadur)


Lesenswert?

Für den Zugriff auf das RAM mit CE auf low mußt du ein Port als High 
Adress verwenden. /WE muss high sein . Dann die Lowadresse an den Port 
mit dem Latch
ALE auf Low und sofort wieder auf High. Wenn du schreiben willst Daten 
an den Datenport und danach /WE auf low und sofort wieder auf high.

Lesen: Adressen wie zuvor an die Ports. Datenport danach auf lesen. /OE 
auf low. Port lesen. /OE auf high setzen.

von Bruno M. (brumay)


Lesenswert?

Ich habe den Code mal so abgeändert, wie ich den Vorschlag verstanden 
habe. Nur OE habe ich weggelassen, da es fest verdrahtet ist und im 
Datenblatt auch so nicht vorkommt. Leider hat das nichts geändert.
1
Write:
2
sbi    PORTD, WR    ; Write auf high
3
sbi    PortE, 1    ; ALE auf high
4
clr    temp
5
out    PortC, temp    ; Ausgabe High Adressen
6
ldi    temp, 0x0F      
7
out    PortA, temp    ; Ausgabe Low Adressen  
8
cbi    PortE, 1    ; ALE auf low, Adresse wird gehalten
9
sbi    PortE, 1    ; ALE auf high
10
ldi    Data, 0b01010101        
11
out    PortA, Data    ; Daten werden bereitgestellt
12
cbi    PORTD, WR    ; Write auf high
13
sbi    PORTD, WR    ; Write auf high
14
nop
15
ret
16
17
;**************************************************************************
18
Read:
19
sbi    PORTD, WR    ; Write auf high
20
sbi    PortE, 1    ; ALE auf high
21
clr    temp
22
out    PortC, temp    ; Ausgabe High Adressen
23
ldi    temp, 0x0F      
24
out    PortA, temp    ; Ausgabe Low Adressen  
25
cbi    PortE, 1    ; ALE auf low, Adresse wird gehalten
26
sbi    PortE, 1    ; ALE auf high
27
cbi    PORTD, WR    ; Write auf high
28
clr    temp              
29
out    DDRA, temp    ; Alles Eingang
30
in    Data, PinA    ; Daten abholen
31
sbi    PORTD, WR    ; Write auf high

Ich muß noch hinzufügen, daß ich natürlich schon alles möglich eversucht 
habe. So habe ich sowohl das Latch als auch das RAM unabhängig 
voneinander getestet und es hat funktioniert. Das Problem kann also nur 
an der Kombination der beiden ICs liegen.

von Heiner B. (karadur)


Lesenswert?

/OE aktiviert den Ausgang des RAM. Auf den Datenleitungen liegen somit 
immer Daten die dem Speicherinhalt der jeweiligen Adresse liegen. Das 
kann nicht funktionieren.

von Bruno M. (brumay)


Lesenswert?

Heiner B. schrieb:
> Das
> kann nicht funktionieren.

quote
A read cycle is accomplished by asserting chip enable (CE) and output
enable (OE) LOW, with write enable (WE) high.
unquote

...dann ist also das Datenblatt falsch?

von Heiner B. (karadur)


Lesenswert?

Das passt schon, aber die Daten vom RAM sind schon am Ausgang wenn du 
die Low Adresse am Port ausgibst. Port A gegen Ausgang Ram. Wer gewinnt?

von S. L. (sldt)


Lesenswert?

> ...dann ist also das Datenblatt falsch?

Es wird wohl seinen Grund haben, dass der ATmega162 hardwaremäßig mit 
/RD arbeitet.

Und ALE ist active high.

von Heiner B. (karadur)


Lesenswert?

S.L hat recht ALE muss low sein damit die Adresse gespeichert wird.
Hab schon lange nicht mehr mit den 80xx gearbeitet.

von Bruno M. (brumay)


Lesenswert?

Ich glaube, ich brauche erst mal ne Denkpause.
Schon mal herzlichen Dank für die Beiträge!

Beitrag #7716207 wurde vom Autor gelöscht.
von S. L. (sldt)


Lesenswert?

> Ich brauche die Softwarelösung aber

Hmm - was ist an der Hardwarelösung verkehrt?

Nichts für ungut - manchmal mögen meine Assoziationen vielleicht etwas 
schräg sein (bringt das Alter so mit sich):

" ... einen Streich spielen. Er wird sogar die Lebkuchen aufs Spiel 
setzen und sich vielleicht den verderblichsten Unsinn wünschen, den 
allerunökonomischsten Blödsinn, einzig um in diese ganze positive 
Vernünftigkeit sein eigenes unheilbringendes phantastisches Element 
beizumischen. Gerade seine phantastischen Einfälle ... "

von S. L. (sldt)


Angehängte Dateien:

Lesenswert?

Falls aber doch ein tieferer Sinn hinter dem Unterfangen steckt, hier 
ein Denkanstoß.

Zu
> ... OE ... Das ist hardwaremäßig fest verdrahtet!
hat Heiner B. schon alles gesagt (das Verhalten ist im besten Falle 
undefiniert).

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

S. L. schrieb:

> Zu
>> ... OE ... Das ist hardwaremäßig fest verdrahtet!
> hat Heiner B. schon alles gesagt (das Verhalten ist im besten Falle
> undefiniert).

Ich würde es doch vorsichtigerweise eher so ausdrücken: es ist nur nicht 
dokumentiert. Leider kann ich zum konkreten Delinquenten Atmega162 auch 
nichts sagen, aber ich habe vor Jahren andere AVRs mit XMEM-Interface 
beackert (konkret: 8515), bei denen das ebenfalls nicht dokumentiert 
war, sich aber immerhin doch ein funktionierender Workaround für den 
rein Software-basierten Zugriff realisieren ließ.

Allerdings war da keiner der XMEM-Pins dediziert, alle liessen sich auch 
über ganz normale GPIO-Zugriffe erreichen (jedenfalls, wenn das 
XMEM-Interface deaktiviert war). Ein /OE gab es dort allerdings meiner 
Erinnerung nach gar nicht.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

S. L. schrieb:
> Hmm - was ist an der Hardwarelösung verkehrt?

Noch einfachere Lösung: Mikrocontroller mit eingebauten 32 KiB RAM 
nutzen, z.B. STM32G070CB.

von Heiner B. (karadur)


Lesenswert?

/OE ist ein Problem der Funktion/Beschaltung des RAM und nicht des 
Prozessors.

von Klaus S. (kseege)


Lesenswert?

Wenn man ein Oszilloskop hat, schaut man sich an, wie die 
funktionierende Schaltung abläuft.

Hat man keins, macht man es sicherheitshalber so wie alle Anderen, also:
RD und WR high, ALE Low
Adresse auf die Adressausgänge (hier PA und PC)
ALE hoch
ALE wieder runter, Adresse ist am RAM

Dann zum Schreiben:
Datenbyte auf PA ausgeben
WR runter
WR wieder rauf

oder zum Lesen:
PA auf Input umschalten
RD runter
PA einlesen
RD wieder rauf

schon funktionierts. Alle Abweichungen von dieser Reihenfolge
geschehen auf eigene Gefahr.

Gruß Klaus (der soundsovielte)

von S. L. (sldt)


Lesenswert?

> ... OE ... Das ist hardwaremäßig fest verdrahtet!

Vielleicht soll partout ein Controller-Pin eingespart werden; in diesem 
Fall könnte man acht Widerstände in den Datenbus zum RAM einschleifen, 
geschätzt 220 Ohm bis 1 k - aber oh je ...

von S. L. (sldt)


Lesenswert?

Klaus Seegebarth schrieb:
> RD runter
> PA einlesen
> RD wieder rauf

Ah, danke für den Hinweis! Mein Programm funktioniert hier zwar (auf 
einem STK200), aber es muss in §ext_read natürlich korrekterweise 
heißen:
1
    cbi     PORTD,7                                     ; /RD
2
    in      data,PINA
3
    sbi     PORTD,7

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Niklas G. schrieb:
> S. L. schrieb:
>> Hmm - was ist an der Hardwarelösung verkehrt?
>
> Noch einfachere Lösung: Mikrocontroller mit eingebauten 32 KiB RAM
> nutzen, z.B. STM32G070CB.

Oder lieber gleich was wirklich brauchbares: RP2354 mit satten 520kByte. 
Viel billiger als die ganze kleine STM32-Gülle und viel mehr Resourcen.

Selbst mit STM32M4 muss man sich schon ordentlich strecken, um an diese 
Performance mit diesen Resourcen heran zu kommen. STM hat mit diesen 
neuen RP endgültig ausgedient. Jedenfall für fast alles unterhalb H7/G7.

Gut so. Konkurrenz belebt das Geschäft. Für die Anwender wird es 
zunächst mal günstiger. Man muss bloß aufpassen, dass die Raspi-Truppe 
kein Quasi-Monopol etabliert bekommt. Dann würde es eklig werden.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ob S. schrieb:
> RP2354 mit satten 520kByte

Nun bleibt mal auf dem Teppich.
Mich ärgert viel mehr, das der TE seine Definitionen nicht mitpostet und 
auch keinen Schaltplan preisgibt. Da fühlste dich schon ein wenig wie 
beim 'Rate mal mit Dosenthal'.
Und dann kommt z.B.
Bruno M. schrieb:
> Data ist R17!
mit Ausrufezeichen, als verstünde sich das von selber.

von Klaus S. (kseege)


Lesenswert?

Matthias S. schrieb:
> Mich ärgert viel mehr, das der TE seine Definitionen nicht mitpostet und
> auch keinen Schaltplan preisgibt. Da fühlste dich schon ein wenig wie
> beim 'Rate mal mit Dosenthal'.

Der TO hat deutlich geschrieben, daß er das SRAM am ATmega162 in der von 
Atmel vorgesehenen Methode dran hat und daß es damit funktioniert. Wer 
das nicht
versteht (und kein Datenblatt lesen kann), der sollte den Griffel
stillhalten. Im Datenblatt sind gleich auf der ersten Seite die Signale
AD0-7,A8-15, RD, WR und ALE angegeben, man muß nichts suchen. Jeder, der 
schon einmal ein SRAM im Multiplex angeschlossen hat, kennt das auch 
auswendig.

Just my 2 cents

von Thomas (kosmos)


Angehängte Dateien:

Lesenswert?

Das entscheidende ist dieser Strich über dem WE. Das heist "low aktiv". 
Write enable ist es also wenn der Pegel low ist.

Im Datenblatt https://www.farnell.com/datasheets/101856.pdf sieht man 
auf Seite 4 und 5 die Pegelwechsel.

Liegt beim ATMega162 JTAG auch auf PortC dann ggf. das JTAG disable bit 
setzen das da nichts dazwischen funkt hatte das mal bei einem ATMega16

Normalerweise muss du beim Lesen nur die Adresse anlegen nach dem letzen 
Pegelwechsel an den Adressleitungen liegen die Daten nach 12, 15 oder 
20nSek (je nach deinem SRAM-Typ) automatisch an, da kannst du dir einen 
weiteren Takt sparen. WE legst du vorher auf high und CE und OE vorher 
auf low.

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.