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?
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.
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.
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...
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)
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;
...
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).
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.
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?)
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 ;-)
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
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.
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?
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!
-------------------------------------------------------------
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.
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"
// 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
uintp;uchari,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
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).
...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.
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).
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.
Bessermeier oder jemand anderes eine Idee? Ist vermutlich ja recht
trivial. Vielleicht hat der Entwickler des Codes auch etwas fehlerhaftes
programmiert.
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.
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.
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.
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?
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.