Forum: Mikrocontroller und Digitale Elektronik LCD an Datenbus


von George R. (caco3)


Lesenswert?

Hallo zusammen

Ich habe ein Atmega128 Entwicklungsboard (Ethernut 2.1b) und möchte mein 
Display daran anschliessen.
Um GPIOs zu sparen, möchte ich es direkt an den Daten/Adress-Bus 
anschliessen.

Gemäss der Ethernut-Dokumentation sind der Speicher ab Adresse 0xD000 
nicht verwendet und können verwendet werden.
Daher möchte ich aus den obersten 4 Bit (0xD) einen Chipselect erzeugen.

Nur, wie schreibe ich mit ANSI C Daten an den Speicher mit Adresse 
0xD000?
Ich hatte das früher mal mit einem 80C537 gemacht mit:
1
xdata char display _at_ 0xD000;
Da ich nun einen anderen Prozessor und Compiler (gcc) verwende, weiss 
ich nicht, wie man an eine bestimmte Adresse schreibt.

Vielen Dank für eure Tipps.

Nachtrag:
Generell frage ich mich nun aber auch, ob das vom Timing her überhaupt 
möglich ist.
Wenn ich mir mit dem Oszilloskop eine Leitung des Daten-Busses des uCs 
anschaue, sehe ich eine Pulsdauer von 80ns (Quarz mit 14 MHz). Das 
Display erwarted aber anscheinend viel längere Pulse.

von Thomas E. (thomase)


Lesenswert?

George Ruinelli schrieb:
> Ich hatte das früher mal mit einem 80C537 gemacht mit:xdata char display at 
0xD000;
>
>
>
> Da ich nun einen anderen Prozessor und Compiler (gcc) verwende, weiss
>
> ich nicht, wie man an eine bestimmte Adresse schreibt.

Mit einem Pointer auf die Adresse:

unsigned char* ptrXdata = 0xD000;  //Pointer auf Adr. 0xd000

unsigned char nAusgabe;
*ptrXdata = nAusgabe;          //Schreibe auf Adr.

George Ruinelli schrieb:
> Wenn ich mir mit dem Oszilloskop eine Leitung des Daten-Busses des uCs
>
> anschaue, sehe ich eine Pulsdauer von 80ns (Quarz mit 14 MHz). Das
>
> Display erwarted aber anscheinend viel längere Pulse.

Du hast keinen Datenbus, sondern einen Adress/Datenbus. Erst wird die 
Adresse (A0 -A7) ausgegeben, diese muß dann in einem Latch gespeichert 
werden, dann werden die Daten angelegt. Und wenn WR = low, ist alles 
gültig.


mfg.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

1
#include <stdint.h>
2
uint8_t data;
3
data = 0xab;
4
//...
5
6
// (1) Grundprinzip
7
*((volatile uint8_t *)0xD000) = data;
8
9
// (2) wie (1) aber etwas Bequemlichkeit wenn mehrfach benötigt
10
#define LCD_WRITE(d_) { *((volatile uint8_t *)0xD000) = d_; }
11
// ...
12
LCD_WRITE(data);
13
14
// (3) wie (1), auch etwas bequemer
15
#define LCD_WRITE_ADDR (*((volatile uint8_t *)0xD000))
16
//...
17
LCD_WRITE_ADDR = data;

Betr. Bus-Frequenz: man kann beim ATmega128 wait-states konfigurieren 
(external memory control registers), damit mögliche Verlangsamung reicht 
mglw. schon.

Mglw. ist der Quelltext der Beispiele zum DB101 von Atmel noch eine 
brauchbare Informationsquelle (Original bei atmel.com, mein 
avr-gcc/avr-libc Port davon bei 
http://www.siwawi.arubi.uni-kl.de/avr_projects/#db101_app )

von Peter D. (peda)


Lesenswert?

George Ruinelli schrieb:
> sehe ich eine Pulsdauer von 80ns (Quarz mit 14 MHz). Das
> Display erwarted aber anscheinend viel längere Pulse.

Ja, laut Datenblatt mindestens 450ns.

Dein 80C537 lief warscheinlich mit 11MHz und hat die intern durch 12 
geteilt, also effektiv mit 0,9MHz.

Das wird also nichts mit 14MHz.


Peter

von George R. (caco3)


Lesenswert?

Vielen Dank für eure Infos und Tipps.

Das Ganze scheint mir nun doch reichlich komplizierter zu sein als ich 
mir erhofft hatte. Deshalb finden sich vermutlich im Web auch praktisch 
keine Beispiele dafür.

Selbst wenn ich die Daten mit einem Latch speichern würde, hätte ich 
immer noch das Problem, dass das Timing der anderen Signal (E, R/W, CS, 
D/I) nicht passt. Oder wäre es möglich, diese auch über einen Latch zu 
führen?
Da ich das Display sowieso nur schreibend betreiben will, könnte ich 
doch einige Adressbus-Bits im zweiten Latch zwischenspeichern und als E, 
R/W, CS, D/I ausgeben.

Ansonsten müsste ich das Display doch konventionell mit Port-Bits 
ansteuern. Das habe ich schon mal mit einem PIC30F6014 gemacht. 
Allerdings werden dadurch leider 14 Port-Pins verbaut :(
Das Display ist ein (Standard) 128x64-Pixel-Display von Everbouquet 
(MG12064, http://www.everbouquet.com.tw/MG12064E.htm).

Das von Martin erwähnte AVRDB101 scheint es aber auch direkt zu können, 
zumindest sind da gemäss Schema die Display-Leitungen direkt an den 
Adress- und Datenbus gehängt. Oder vielleicht wird es da auch 
konventionell über die Port-Bits angesteuert?

von tt2t (Gast)


Lesenswert?

> Allerdings werden dadurch leider 14 Port-Pins verbaut

für ein LCD-Display braucht man 6-7 Pins (4 Daten, 2-3 Handshake)

von Peter D. (peda)


Lesenswert?

Die 450ns gelten für ein übliches Text-LCD, von einem GLCD hattest Du ja 
nix erwähnt.
GLCDs sind meistens schneller, mußt mal ins Datenblatt schauen.

GLCDs sind auch deutlich komplizierter, man muß alle Zeichen mit 
put_pixel selber zusammen basteln.


Peter

von George R. (caco3)


Lesenswert?

> für ein LCD-Display braucht man 6-7 Pins (4 Daten, 2-3 Handshake)
Leider unterstützt dieses Display keinen 4-Bit Modus, zumindest ist er 
nicht dokumentiert.

> GLCDs sind auch deutlich komplizierter, man muß alle Zeichen mit
put_pixel selber zusammen basteln.

Den Programm-Code dafür habe ich schon.
Wie gesagt habe ich das Display schon mal an einem PIC erfolgreich 
verwendet und neben Text auch Graphiken ausgegeben.

Beim verwendeten Ethernut habe ich leider nicht so viele Ports 
verfügbar. Und vor allem keine komplette Ports, ich müsste also die 8 
Datenbits sogar auf mehr als einen Port aufsplitten, wenn ich es über 
die Ports ansteuere.

von Thomas E. (thomase)


Lesenswert?

George Ruinelli schrieb:
> Ansonsten müsste ich das Display doch konventionell mit Port-Bits
>
> ansteuern.

Warum kaskadierst nicht 2 595er?
Da brauchst du nur noch 3 Leitungen, hast 16 Ausgänge und so schnell wie 
beim 8051 ist das allemal.

mfg.

von Nils S. (kruemeltee) Benutzerseite


Lesenswert?

oder 2x PCF8574

von Frank K. (fchk)


Lesenswert?

George Ruinelli schrieb:

> Selbst wenn ich die Daten mit einem Latch speichern würde, hätte ich
> immer noch das Problem, dass das Timing der anderen Signal (E, R/W, CS,
> D/I) nicht passt. Oder wäre es möglich, diese auch über einen Latch zu
> führen?
> Da ich das Display sowieso nur schreibend betreiben will, könnte ich
> doch einige Adressbus-Bits im zweiten Latch zwischenspeichern und als E,
> R/W, CS, D/I ausgeben.

Ich würde es so machen:
1
###AVR### ###LCD###
2
-WR  -RD  E    R/-W
3
0    0    x    x     nicht erlaubt
4
1    0    1    1     Lesezugriff
5
0    1    1    0     Schreibzugriff
6
1    1    0    x     Ruhezustand
7
8
d.h 
9
LCD --->  AVR
10
D0-D7     AD0-AD7 (Port A0-A7)
11
D/I       A8      (Port C0)
12
R/-W      -WR
13
E         not (-WR and -RD) (1/4 74HC00)
14
-CS       per HC688 aus A9-A15 (Port C1..C7) ausdecodieren

Da Du A0-A7 nicht brauchst, kannst Du auch auf das Adresslatch 
verzichten.
Die anderen Signale musst Du Dir entsprechend hinbasteln (siehe oben). 
Das Display wäre dann unter einem 512 Byte Block im externen Adressraum 
ansprechbar, wobei das Instruktionsregister die eine Hälfte und das 
Datenregister die andere Hälfte des Adressraums belegt.

Ich würde das einfach mal so ausprobieren. Waitstates kannst Du ja 
leicht einbauen.

fchk

von George R. (caco3)


Lesenswert?

Vielen Dank für all eure raschen und kompetenten Ideen!

Ich werde es einmal mit zwei seriellen Schieberegistern versuchen.
Das hat den Vorteil, dass es einfach zu testen ist und ich kein Problem 
mit dem uC Timing haben werde.
Ausserdem kann ich dadurch das Display auch weiter entfernen, 
(Schieberegister direkt beim Display platziert) und brauche dann nur ein 
längere Kabel mit 3 anstatt 20 Adern.

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.