Forum: Mikrocontroller und Digitale Elektronik Benörige Hilfe bei Grafikdisplay LM240120


von Julian (Gast)



Lesenswert?

Hallo ihr Experten,

habe auf der diesjährigen Embededd World ein Grafikdisplay von einem 
chinesischen Aussteller als Sample erhalten. Dieser meinte, dass ich ich 
alle nötigen Daten dazu online finden würde. Wenn ich unter unter der 
Modellbezeichnung suche, finde ich im Grunde fast nichts. Bei der Suche 
nur nach LM240120 immerhin etwas mehr.

Z.B.:

Der Hersteller Topway hat mir auf Anfrage immerhin ein Skizze geschickt, 
allerdings nichts darüber, wie man das Teil ansteuert.

Laut Aussteller besitzt das Ding einen intergrierten Controller aber 
auch den kann ich auf der Platine nicht ausfindig machen. Welcher könnte 
das sein.

Laut: 
http://topwaydisplay.en.made-in-china.com/offer/noXQFjuKkIWC/Sell-240x120-Cog-Display-LM240120-.html
könnte ein UC1608 verbaut sein, auch wenn die Modellbezeichnung 
abweicht.

Habe mal zwei Fotos und die vom Hersteller erhaltene PDF-Datei 
angehängt.

Kennt jemand das Teil, oder ein ähnliches und kann mir weiterhelfen? 
Würde es gerne mit einem kleinen AVR zum Leben erwecken, notfalls auch 
durch probieren. Aber wie anfangen, gibt es da sinnvollen Beispielcode?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Julian schrieb:
> Kennt jemand das Teil, oder ein ähnliches und kann mir weiterhelfen?

 8bit Databus + Read + Write + Data/Control + Reset + ChipSelect +
 BackLightAnode + GND + VCC.

 Alles auf 3V3 - angesteuert werden einzelne Pixel.

 Was genau ist dein Problem ?

 P.S.
 Wird wahrscheinlich genau wie ein 128x64 angesteuert, nur eben mehr
 Pixel.

: Bearbeitet durch User
von Christoph db1uq K. (christoph_kessler)


Lesenswert?

http://www.orientdisplay.com/pdf/UC1608.pdf
Ein reiner Pixelgrafik-Controller ohne Character-ROM, bis maximal 
240*128 Pixel.
Das Interface zum Mikrocontroller läßt sich wie üblich auf 4/8 Bit 
Busbreite umstellen und kennt die beiden Modi "6800" (rd/not-write und 
enable) und "8080" (/rd,/wr). Die Aussage von topwaydisplay "parallel or 
seriell" kann ich im Datenblatt nicht finden.

von Julian (Gast)


Lesenswert?

Alles klar, danke euch erstmal. Hat den jemand Erfahrung mit dem UC1608 
und ggf. guten Beispielcode in C?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Julian schrieb:
> Alles klar, danke euch erstmal. Hat den jemand Erfahrung mit dem UC1608
> und ggf. guten Beispielcode in C?

 Wird wohl kaum dieser Controller sein.
 Erstens, UC1608 hat 240x128 Pixel - der verlinkte hat 120x240.
 Zweitens, UC1608 hat 2 Pins um die Busbreite auszuwählen - der
 verlinkte hat diese Pins nicht.

 Software Ansteuerung wird wahrscheinlich kein Problem sein -
 Initsequenz ist fur die meisten LCD die selbe.

 Und Hardwaremässig wird es in etwa so sein:
1
 Befehl schreiben           Daten schreiben              Daten lesen      
2
         _________            ______________             _______________ 
3
CS  ____/                 ___/                       ___/                
4
    __                    ___________________        ___________________ 
5
D/C   \___________                                                       
6
    _____________         ___________________        ______
7
RD                                                         \____________
8
    ______                _______                    ___________________      
9
WR        \______                \____________

 Aber eine fertige Library genau für diesen Typ wirst du kaum finden,
 da musst du schon ein bisschen selber schreiben...

: Bearbeitet durch User
von pegel (Gast)


Lesenswert?


von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

pegel schrieb:
> Sieht passig aus:

 Tatsächlich.
 Na ja, wird wohl nix mit 4bit Ansteuerung...

von Julian (Gast)


Lesenswert?

Habe vom Hersteller nun die Information erhalten, das es sich bei dem 
Controller um den UC1618T handelt.
Für den finde ich leider kein ausfürliches Datenblatt. Aber vielleicht 
meldet sich UltraChip ja noch auf meine Anfrage.

Des weiteren habe ich aber von TopWay einen Beispielcode mit 
chinesischen Kommentaren zugemailt bekommen. Den habe ich weitestgehend 
von Google von Chiniesisch ins Englische übersetzen lassen.

Der Code ist allerdings für den Keil-Compiler geschrieben. Könnte mir 
mal bitte jemand erklären, ob ich folgenden Teil so für GCC umwandeln 
kann? Bzw. wenn nicht, wie dann?


//Original (Keil)
//---Parallel Interface Definition-----
#define LCDBUS    P1
sbit _CS     = P3^4;
sbit _RES    = P3^5;
sbit RS      = P3^6;
sbit _WR     = P3^7;
sbit _RD     = P3^1;
______________________________________



//Neu (GCC)
#define LCDBUS PORTC |= 0xff
#define _CS PORTB |= (1<<PB4)
#define _RES PORTB |= (1<<PB5)
#define _RS PORTB |= (1<<PB6)
#define _WR PORTB |= (1<<PB7)
#define _RD PORTB |= (1<<PB1)

von Julian (Gast)


Lesenswert?

Hey Leute,

ich habe für ein Grafikdisplay einen Beispielcode vom Hersteller 
erhalten. Dieser ist allerdings für den Keil-Compiler.

Wer kann mir helfen, diesen Code für AVR-GCC zu konvertieren?

Die includes lauten:

#include <reg52.h>
//gefunden: http://www.keil.com/dd/docs/c51/reg52.h

#include <intrins.h>
//gefunden: http://www.keil.com/support/man/docs/c51/c51_intrins_h.htm

Es geht im Grunde um das Konvertieren folgender Zeilen:

//---Parallel Interface Definition-----

#define LCDBUS    P1
sbit _CS     = P3^4;
sbit _RES    = P3^5;
sbit RS      = P3^6;
sbit _WR     = P3^7;
sbit _RD     = P3^1;

und folgende Zeilen in der main:

void main()
{
  SP=0x60;
  EA=0;
...

von Jim M. (turboj)


Lesenswert?

Geht nicht so einfach. Das sind 8051 (bzw. 8052) spezifische Sachen, die 
es auf dem AVR in der Form nicht gibt - jedenfalls nicht in C.

Aber: So ein parallel LCD Interface gibts für AVR wie Sand am Meer. Das 
klaut man sich einfach irgendwo her (-> Google, Github).

von Carsten W. (eagle38106)


Lesenswert?

Julian schrieb:
> //---Parallel Interface Definition-----
>
> #define LCDBUS    P1
> sbit _CS     = P3^4;
> sbit _RES    = P3^5;
> sbit RS      = P3^6;
> sbit _WR     = P3^7;
> sbit _RD     = P3^1;
>
> und folgende Zeilen in der main:
>
> void main()
> {
>   SP=0x60;
>   EA=0;
> ...


SP ist der Stackpointer
EA ist das *E*nable *A*ll Interrupts Flag
Mit sbit XYZ = P<x>^<Y> definiert man sich einen direkten Bitzugriff auf 
den Pin <Y> vom Port <X>.

Das in AVR Code umzusetzen ist viel Handarbeit, da sowohl die Hardware 
wie Timer und Schnittstellen anders sind, als auch die Ports anders 
angesteuert werden.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Julian schrieb:
> sbit _CS     = P3^4;

Wasimmer das ist, es ist kein C...

von STM STM STM (Gast)


Lesenswert?

Johann L. schrieb:
> Wasimmer das ist, es ist kein C...

Wenn der Keil das "so" macht dann bin ich froh
dass ich kein Keil habe / benutze.

(oder: wieder mal ein Beispiel wie man Kunden an sich bindet?)

von Dr. Sommer (Gast)


Lesenswert?

Johann L. schrieb:
> Wasimmer das ist, es ist kein C...

Wieso, wenn sbit ein Integer-Typ und P3 eine Integer-Variable ist? Okay, 
_CS ist kein erlaubter C-Bezeichner, aber das auch genutzte RS schon ;-)

von Julian (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal der vollständige Code zu dem Display. Vielleicht kann mir 
daraufhin jemand sagen, an welchem Code ich mich orientieren kann, um 
das auf einem Atmega168 zum laufen zu bekommen.



----

Den Text "Längeren Sourcecode nicht im Text einfügen, sondern als 
Dateianhang" hat Andreas sicherlich nur zur Belustigung hier über das 
Editfeld gesetzt, da bin ich mir fast sicher.

-rufus

: Bearbeitet durch User
von Regelnaufpasser (Gast)


Lesenswert?

Julian schrieb:
> Hier mal der vollständige Code zu dem Display.

.... und von den Regeln zum Posten von Code hast noch nichts gehört?

von Schlaumeier (Gast)


Lesenswert?

Julian schrieb:
> Hier mal der vollständige Code zu dem Display. Vielleicht kann mir
> daraufhin jemand sagen, an welchem Code ich mich orientieren kann, um
> das auf einem Atmega168 zum laufen zu bekommen.

Das basiert auf einem 8052-Design, wie häufig bei den Chinesen. Mit ein 
bißchen Fleiß beim Überarbeiten und ein bißchen Programmierknowhow ist 
das problemlos auf einem ATMEGA zum Laufen zu bewegen.

Vorgehen:
Lad es in Deine IDE, kommentiere alles aus, was einen Fehler bringt. 
(Die Kommentare möglichst eng an den Fehler setzen.) Wenn es fehlerfrei 
übersetzt wird, mach Dich nach und nach an die auskommentierten Stellen, 
überlege, wozu die Stelle gut ist und wie man das auf dem ATMEGA 
umsetzen kann oder ob das auf einem ATMEGA nicht benötigt wird und 
gelöscht werden kann. Dann noch die ATMEGA-typischen Dinge ergänzen. 
Wenn auf diese Weise alle auskommentierten Stellen weg sind, sollte ein 
lauffähiges Programm herauskommen.

von Julian (Gast)


Lesenswert?

Danke Schlaumeier, so werde ich da rangehen.

von Bessermeier (Gast)


Angehängte Dateien:

Lesenswert?

Also ich würde das so machen.

(Diskussionsgrundlage, Hilfe zur Selbsthilfe)

von Julian (Gast)


Lesenswert?

Hab die von Bessermeier vorgeschlagenen änderungen vorgenommen und noch 
folgendes aufgrund von Compilerfehlern geändert:

neu: asm volatile ("nop");
alt: _nop_();

neu: void ShowBMP(uchar x,uchar y,uchar width, uchar high,uchar bmp[])
alt: void ShowBMP(uchar x,y,width,high,uchar bmp[])

neu: uchar DISPLOGO[]={
alt: uchar code DISPLOGO[]={

Die main sieht jetzt so aus:

int main()
{
  //SP=0x60;
  //EA=0;

  //--initialize the interface------------
  RESET_HIGH;
  CS_HIGH;
  // parallel interface initialization¯
  LCD_PORT=0xff;
  WR_HIGH;
  RD_HIGH;
  //------------------------
  initLCDM();
  while(1)
  {
    ShowBMP(0,0,240,15,DISPLOGO);
    delayms(800);
    ShowBMP(0,0,240,15,cros1);
    delayms(800);
  }
}

Das ganze lässt sich nur leider nicht kompilieren. Fehler:

Severity  Code  Description  Project  File  Line  Column
Error    Program Memory Usage   :  7930 bytes   48,4 % Full
        Data Memory Usage     :  7201 bytes   703,2 % Full  (Memory 
Overflow)  Grafikdisplay_HL240120HFW  Grafikdisplay_HL240120HFW  0  0



Wenn ich aber uchar DISPLOGO[] und uchar cros1[] auskommentiere dann 
wirds fehlerfrei kompiliert. Was muss ich da noch ändern?

von Bessermeier (Gast)


Lesenswert?

Julian schrieb:
> LCD_PORT=0xff;

Das ist unnütz.

Aber du musst den Port den du verwendest noch auf Output stellen:
1
DDRC = 0;
2
DDRC |= (1<<CS_PIN);
3
DDRC |= (1<<RESET_PIN);
4
DDRC |= (1<<RS_PIN);
5
DDRC |= (1<<RD_PIN);
6
DDRC |= (1<<WR_PIN);

für DDRC natürlich den Port den du wirklich verwendest.

-------------------------------------------------------------
Und verwende verdammt nochmal endlich die C-Formatierung wie
sie beim Posten angegeben/verlangt ist!
-------------------------------------------------------------

von Julian (Gast)


Lesenswert?

Ja, hatte den PortC komplett auf Ausgang gesetzt: DDRC |= (0xff).

Wenn ich mir das mit den ganzen Speicherfressenden Bits anschaue, kann 
das wohl auch rechnerisch nicht passen. Bei 120x240 Pixeln wären das ja 
schon für ein Bild 28,8 KB. Wird also unmöglich bei 16KB Flash.

von Erdowahn (Gast)


Lesenswert?

Lasse Deine Arrays mal im Flash, und zwar so
1
const uchar DISPLOGO[] PROGMEM = {
2
  ...
3
}
und analog
1
const uchar cros1[] PROGMEM = {
2
  ...
3
}
und dann fütterst Du Deine Funktionen mit dem Makro
1
pgm_read_byte(&DISPLOGO)
analog mit dem anderen Array.
Nicht vergessen,
1
#include <avr/interrupt.h>
zu inkludieren.

von Erdowahn (Gast)


Lesenswert?

Deine Formatierung ist grausig, und wird so nicht funktionieren.
Befehle hinter einem Doppelslash werden als Kommentar ignoriert.
1
//------------------------ initLCDM(); while(1)
2
{
3
ShowBMP(0,0,240,15,DISPLOGO); delayms(800); ShowBMP(0,0,240,15,cros1); delayms(800); }
4
}
5
// end program
Hoppla, habe selber nen Fehler gemacht, das Adresszeichen ist hier nicht 
notwendig.
Somit schlage ich folgendes vor:
1
//------------------------
2
  initLCDM();
3
  while(1)
4
  {
5
    ShowBMP(0,0,240,15,pgm_read_byte(DISPLOGO));
6
    delayms(800);
7
    ShowBMP(0,0,240,15,pgm_read_byte(cros1));
8
    delayms(800);
9
  }
10
}
11
// end program
Den Rest bekommst Du schon selber hin.

von Erdowahn (Gast)


Lesenswert?

War wieder Mist, moment mal...

von Julian (Gast)


Lesenswert?

Sorry, die Formatierung ist nichtmal von mir, sondern direkt aus China.

Brauche ich die interrupt.h oder meinst du eher die pgmspace.h?

Vielen Dank soweit. Für heute ist erstmal Schluss, morgen sehe ich 
weiter.

Habs jetzt so gelöst:

#include <avr/pgmspace.h>

  while(1)
  {
    ShowBMP(0,0,240,15,pgm_read_byte(&DISPLOGO));
    delayms(800);
    ShowBMP(0,0,240,15,pgm_read_byte(&cros1));
    delayms(800);
  }

Damit ist der Speicherfehler weg und es tauchen nur noch 2 Warnungen 
auf:

"passing argument 5 of 'ShowBMP' makes pointer from integer without a 
cast"

von Erdowahn (Gast)


Lesenswert?

1
void ShowBMP(uchar x,y,width,high,const uchar PROGMEM *bmp)
2
{
3
// Coordinate X is the column of pixels in columns 0-240
4
// The coordinate Y is the number of pixels
5
// The width of the width is the number of horizontal columns
6
// The height of the graph is high for the vertical dotted line, the value is 0-127
7
// The graphic array bmp [] is the image data to be written, expressed as 1bpp (8dots / byte), horizontally
8
9
  uint p; uchar i,j;
10
  x=x+14;
11
  y=y;
12
  SdCmd(0xf4); SdCmd(x);SdCmd(0); // set the left edge of the operation window
13
  SdCmd(0xf5); SdCmd(y); // set the upper bound on the operation window SdCmd(0xf6); SdCmd(x+width-1);SdCmd(0); // set the right window of the operation window
14
  SdCmd(0xf7); SdCmd(y+high-1); // set the lower bound of the operating window
15
  SdCmd(0xf9); // set the window operation to enable
16
  SdCmd(0x00);SdCmd(x);SdCmd(0x00); // set the start column address
17
  SdCmd(0x60+(y&0x0f)); SdCmd(0x70+(y>>4)); // Set the starting line address
18
  p=0; // array pointer is initialized
19
  for(i=0;i<high;i++) // loop line data volume
20
  {
21
    for ( j=0;j<width;j++) // loop bytes / line
22
    {
23
      SdData(pgm_read_byte(bmp+p)); // write data
24
      p++;
25
    }
26
  }
27
}
28
29
void main()
30
{
31
  //--initialize the interface------------
32
  RESET_HIGH;
33
  CS_HIGH;
34
  // parallel interface initialization¯
35
  LCD_PORT=0xff;
36
  WR_HIGH;
37
  RD_HIGH;
38
  initLCDM();                                   
39
  while(1)                                      
40
  {                                             
41
    ShowBMP(0,0,240,15,DISPLOGO);
42
    delayms(800);                               
43
    ShowBMP(0,0,240,15,cros1);   
44
    delayms(800);                               
45
  }                                             
46
}

Sollte so gehen.

von Erdowahn (Gast)


Lesenswert?

Julian schrieb:
> Habs jetzt so gelöst:
>
> #include <avr/pgmspace.h>

Richtig, wo war mein Kopf schon wieder?

von Julian (Gast)


Lesenswert?

Adresszeichen fliegt noch raus. Mit der Codeformatierung hier im Forum 
werde ich mich dann auch mal auseinandersetzen.

von Erdowahn (Gast)


Lesenswert?

War wieder Mist, gerade selber ausprobiert:
1
void ShowBMP(uchar x,y,width,high,const uchar *bmp)
2
{
sollte passen.

von Julian (Gast)


Angehängte Dateien:

Lesenswert?

Vielen Dank bis hier her. Habe soeben mal alles angeklemmt und was soll 
ich sagen, es funktioniert. Zwar noch nicht richtig (siehe Bilder) aber 
immerhin, ein Lebenszeichen!

Vielleicht kann ja nochmal jemand über den Code schauen, was noch zu 
ändern wäre (ebenfalls angehängt).

von Julian (Gast)


Lesenswert?

...und noch etwas auffälliges Wenn ich beide Bilder mit der 
delayfunktion darstellen lasse, wird trotzdem nur immer das gleiche 
Vogelbild (cros1) angezeigt. Allerdings leicht schräg versetzt im 
Wechsel.

von Bessermeier (Gast)


Lesenswert?

Beispielhaft ein Zeile heruagepickt:
1
SdCmd(0xf6); SdCmd(x+width-1);SdCmd(0);

Daten sollten dann auch mit der entsprechenden Funktion
(die da lautet: void SdData(uchar Ddata)) gesendet werden.

Das gilt für alle SdCmd(..) da laut Datenblatt nach einem
Kommandobyte null bis mehrere Datenbytes gesendet werden
(sollen/müssen).

von Julian (Gast)


Lesenswert?

Also statt SdCmd(...) überall SdData(...) verwenden? Wo hast du das 
Datenblatt gefunden? Ich habe zum UC1618T (steht oben im Sourcecode) 
lediglich eine dreiseitige Zusammenfassung finden können aber leider 
nichts detailiertes.

von Julian (Gast)


Lesenswert?

Bessermeier oder jemand anderes eine Idee? Ist vermutlich ja recht 
trivial. Vielleicht hat der Entwickler des Codes auch etwas fehlerhaftes 
programmiert.

von pegel (Gast)


Lesenswert?

Warum bewegst du jedes mal so grosse Datenmengen?
Gib einfach 1 Byte an verschieden Positionen aus und beobachte was 
passiert.

von pegel (Gast)


Lesenswert?

Gibt es hier jemanden der auch im Microchip Forum unterwegs ist?

http://www.microchip.com/forums/m798562.aspx

Dort gibt ein gewisser amitwadje an das er das Vollständige Datenblatt 
hochgeladen hat. Der link da hin funktioniert zwar nicht mehr, aber ich 
denke das er das DB noch da hat.

von Julian (Gast)


Angehängte Dateien:

Lesenswert?

Hatte wegen einem Datenblatt schon UltraChip direkt angeschrieben, aber 
keine Reaktion erhalten.

Habe soeben mal versucht, auf PROGMEM zu vezichten und eben nur soviele 
Pixel eines Bildes zeichen zu lassen, wie ich in den Speicher des Atmega 
bekomme...
also den Originalcode verwendet.

Das funktioniert, da oben links begonnen wird mit zeichnen (siehe Bild). 
Also stimmt vermutlich irgendwas mit dem Speicherzugriff nicht.

von pegel (Gast)


Lesenswert?

In deiner initLCDM Funktion sind schon einige Befehle drin die die 
Speicherbereiche würfeln können.
Ich würde die einfach auskommentieren und wie gesagt einfach nur ein 
einzelnes Byte an verschiedene Positionen senden.

von Julian (Gast)


Lesenswert?

Fehler gefunden, pgm_read_byte in der while(1) war schuldig. 
Rausgeschmissen und jetzt passt alles. Danke an alle Mithelfer.

von Julian (Gast)


Lesenswert?

Wie man ja feststellen konnte, bin ich recht frisch in der Thematik. 
Jetzt, nachdem das Teil scheinbar ordnungsgemäß funktioniert, würde ich 
es gerne nutzen um gewisse Werte auszugeben. Dafür werden ja Fonts 
benötigt. Wo setzte ich da sinnvollerweise an? Es gibt ja scheinbar 
unzählige Bibliotheken. Kann mir jemand einen konkreten Tip geben, was 
sich da für dieses 240x120 Display anbieten würde? Also ggf. auch einen 
Link?

von pegel (Gast)


Lesenswert?

Da du nun festgestellt hast wie die Bits in das Display kommen,
ist das wenn du bei einem Vielfachen von 8 bleibst kein grosses Problem 
mehr.
Versuche einfach ein Kästchen von 8x8 oder 24x16 o.ä. Pixeln 
darzustellen.
Dann ist es wie beim Bitmap übertragen.
Die Zeichensätze kannst du aus anderen Projekten einfach übernehmen.

Andere Schriftgrössen und Positionen kannst du dann mit der 
Fensterfunktion des UC1618 benutzen, wenn du die findest.

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.