diese Library dient zum ansteuern eines Grafik LC-Displays mit einem SSD1289-Chip.
(240 x 320 Pixel und 16bit Farbe)
das Display wird über den External-Memory-Contoller “FSMC” verwaltet und muss dementsprechend mit der CPU verbunden werden (siehe Pinbelegung in der Library)
die Library bedient die Grundfunktionen wie Initialisierung, Screen-Ausrichtung, Hintergrundbeleuchtung, setzen vom Cursor und löschen vom Bildschirm.
für die Grafik-Funktionen (Linen, Kreise, Bilder) gibt es eine Graphic-Library
für Textausgabe gibt es eine Font-Library
Falls ein Beispielprogramm von hier die LIB “ST7783″ benutzt, dann einfach die include Zeile abändern (in include “SSD1289″) der rest kann gleich bleiben.
Hinweis : ich konnte die LIB nicht selbst testen (hab kein SSD1289-Display). Gruss und Danke an “Tobias” für den Test.
Backlight : (Hinweis)
Das CPU-Signal “LCD_Backlight” kann (und darf) nicht direkt an die LEDs der Hintergrundbeleuchtung angeschlossen werden !! Es muss ein PNP-Transistor dazwischengeschaltet werden (siehe Bild). [PB0 = LED_EN]
16bit 8080-Parallel-Mode :
1 2 3 4 | PS0 = Hi PS1 = Lo PS2 = Lo PS3 = Hi |
Benutzte Pins :
1 2 3 4 5 6 7 8 9 10 11 | PB0 -> LCD_Backlight PE3 -> LCD_RS PD0 -> LCD_D2 PE7 -> LCD_D4 PD1 -> LCD_D3 PE8 -> LCD_D5 PD4 -> LCD_RD PE9 -> LCD_D6 PD5 -> LCD_WR PE10 -> LCD_D7 PD7 -> LCD_CS PE11 -> LCD_D8 PD8 -> LCD_D13 PE12 -> LCD_D9 PD9 -> LCD_D14 PE13 -> LCD_D10 PD10 -> LCD_D15 PE14 -> LCD_D11 PD14 -> LCD_D0 PE15 -> LCD_D12 PD15 -> LCD_D1 |
Voraussetzungen :
1 2 | Benutzte Module der CooCox-IDE : GPIO,FSMC Benutzte Librarys : keine |
Standard Farben :
1 2 3 4 5 6 7 8 9 10 11 | #define RGB_COL_BLACK 0x0000 #define RGB_COL_BLUE 0x001F #define RGB_COL_GREEN 0x07E0 #define RGB_COL_RED 0xF800 #define RGB_COL_WHITE 0xFFFF #define RGB_COL_CYAN 0x07FF #define RGB_COL_MAGENTA 0xF81F #define RGB_COL_YELLOW 0xFFE0 #define RGB_COL_GREY 0xF7DE |
Funktionen :
1 2 3 4 5 6 7 | ErrorStatus UB_LCD_Init(void); // init vom LCD void UB_LCD_SetCursor2Draw(uint16_t xpos, uint16_t ypos); // setzt den Cursor zum zeichnen void UB_LCD_FillScreen(uint16_t color); // füllt den Screen mit einer Farbe void UB_LCD_Backlight_On(void); // Backlight einschalten void UB_LCD_Backlight_Off(void); // Backlight ausschalten void UB_LCD_SetMode(LCD_MODE_t mode); // Modus : Portrait,Landscape void UB_LCD_SetWindow(uint16_t xstart, uint16_t ystart, uint16_t xend, uint16_t yend); // setzt ein Window zum zeichnen |
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | //-------------------------------------------------------------- // File : main.c // Datum : 14.04.2013 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F4 // IDE : CooCox CoIDE 1.7.0 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der LCD-Library (SSD1289) // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_lcd_ssd1289.h" int main(void) { uint32_t n; SystemInit(); // Quarz Einstellungen aktivieren UB_LCD_Init(); // Init vom LCD // Display mit einer Farbe loeschen UB_LCD_FillScreen(RGB_COL_BLUE); // Cursor setzen UB_LCD_SetCursor2Draw(10,50); // einen roten Strich zeichnen for(n=0;n<100;n++) { LCD_RAM=RGB_COL_RED; } while(1) { } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Funktioniert hervorragend mit einem SSD1289 Display. Vielen Dank für die Library!!! Musste Backlight aber entgegen des Anschlussplans von Hand mit Widerstand gegen VCC legen um etwas zu sehen.
super…endlich mal eine Rückmeldung. Das mit dem Backlight hätte ich noch dazuschreiben müssen. Die CPU kann natürlich die Hintergrundbeleuchtung nicht selbst treiben, dafür brauchen die LEDs zu viel Strom. Es muss also ein PNP-Transistor eingebaut werden, der mit dem “Backlight_Enable-Signal” von der CPU geschaltet wird und den Strom für die LEDs aushält. Da mach ich noch eine Skizze dazu. Danke
Hey, danke für die Lib. Habe mich bisher immer gescheut mit Grafikdisplays anzufangen, da diese im Vergleich zu Standard 2×16 recht komplex erscheinen. Jetzt habe ich mir ein Display mit SSD1289 Controller zugelegt. Aber wieso hat dein Display 18 Datenleitungen, meins hat nur 16 (0-15). Wie kann das sein obwohl es der gleiche Controller ist? Andere Designs haben auch nur mit 16 Datenleitungen, kannst du mir da eine Hilfestellung geben?
sorry, ist wirklich etwas dämlich geschrieben. Der LCD-Chip hat einen 18bit breiten Datenbus. Theoretisch kann man ihn auch in diesem 18bit-Mode betreiben. Aber da der FSMC-Bus nur 16bit breit ist und es auch einen 16bit-Mode gibt (es gibt auch noch einen 8bit-Mode) werden nur 16Datenleitungen benötigt. komischerweise werden nicht Bit16 und Bit17 weggelassen sondern Bit8 und Bit9. Es sind in der Summe also 16 Datenleitungen so wie bei dir.
hm ok, mein Fehler, wer zählen kann ist klar im Vorteil…
noch funktioniert es bei mir nicht, bin noch am Fehler suchen, Verbindungen sind ok, aber die Initialisierung schlägt fehl, ich melde mich
zusätzlich zu den 16 Datenleitungen und 4 Steuerleitungen müssen am Display noch der Reset (auf Hi) , und der 16bit-8080-Mode per (PS0-3 = “1001″) gesetzt sein.
Event. meldet sich dein Display auch mit einer anderen ID-Nr. zurück. Die ID muss 0×1289 oder 0×8989 sein. Prüf mal was dein Display zurückliefert.
Jup genau, der Reset auf High und dann bekomme ich die 8989 als ID zurück, das Display bleibt dann allerdings nur weiß. PS0-3 sind mir im Datenblatt auch begegnet, aber die sind bei mir leider nicht rausgeführt, da ich nur die Version mit 2×17 Pin Leiste habe. Ich werde mal schauen ob ich einen anderen Code zu diesen Display zum laufen bekomme damit ich einen Hardwarefehler ausschließen kann, denn deine Lib funktioniert ja.
wenn die ID ausgelesen werden kann, müsste eigentlich auch der Rest funktionieren. Benutzt du das STM32F4 Discovery-Board ?. Hast du einen Link zum Datasheet vom Display (nicht vom Controller). Bist du SICHER das der RS-Pin vom Display an PE3 angeschlossen ist ?
Aha, ich habe nochmal alles durchgemessen und dabei festgestellt, dass die Verbindung RS/PE3 hochohmig war, nun funktionierts. Respekt zu deinem Fern-Fachwissen. für die Verdrahtung muss ich mir noch was überlegen, 30 Leitungen on-the-fly zum Dev-Board zu verdrahten ist zu meiner Schande sehr fehleranfällig. Vielen Dank für deine Hilfe.
schön das es jetzt geht. Und beim “verdrahten” gebe ich dir recht ab einer bestimmten Anzahl von Leitungen lässt man lieber eine Platine herstellen…auch wenns mehr kostet. das SRAM Board bei mir ist der gleiche Fall.
Hey! Danke für diese Anleitung. Leider komme ich damit überhaupt nicht klar. Ich verwende das STM32f4 Discovery Board und habe das LCD mit dem SSD1289.
Ich habe folgende Fragen:
1. Wie muss ich DB8 und DB9 verbinden? Oben wurde ja schon diskutiert, dass an dem LCD nur 16 Datenanschlüsse sind. DB16 und DB17 gibt es nicht, dafür muss man ja DB8 und DB9 verbinden.
2. Ist REST der RESET Anschluss der High braucht?
3. Was ist mit PS0-3? Mein Board hat das nicht, mein LCD auch nicht.
Als ID kommt nur Müll zurück.
HILFE!
Danke!
Hi Sefco,
1. wenn dein Display nur 16 Datenleitungen hat (D0-D15), dann diese so anschließen : PD14=D0, PD15=D1, PD0=D2, PD1=D3, PE7=D4, PE8=D5, PE9=D6, PE10=D7, PE11=D8, PE12=D9, PE13=D10, PE14=D11, PE15=D12, PD8=D13, PD9=D14, PD10=D15 -> prüf die nochmal alle nach !!
2. Der Reset Pin vom Display ist wahrscheinlich Lo-Aktiv (muss also im Betrieb auf Hi liegen…genau wie der Reset der CPU…kannst du also mit dem NRST-Pin vom Discovery verbinden)
3. PS0-3 muss es bei deinem LCD geben. wahrscheinlich aber fest eingestellt (und hoffentlich auf 8080-Mode, sonst funktioniert die Library nicht)
Funktioniert wunderbar mit der geänderten Pinbelegung! Vielen Dank und weiter so!
Gruß
Guten Abend!
Zuerst mal vielen Dank für diese tolle Homepage!
Ich wollte diese Library zusammen mit einem LCD von Embedded Artists verwenden ( http://www.embeddedartists.com/sites/default/files/support/displays/lcd_32_qvga/3.2_inch_QVGA_TFT_Color_LCD_Users_Guide.pdf )
Folgende Dinge funktionieren:
-Backlight On/Off
-Chip-ID Auslesen (Wert: 0×8989)
Jedoch wird nichts auf dem Display dargestellt. Ich weiss, aus der ferne ist es schwierig sich ein Bild von der Lage zu machen, aber hast du vielleicht eine Idee, wo der Fehler liegen könnte?
Vielen Dank für die Hilfe
Gruss Simon
Wenn es sample code gibt vergleiche mal das init
wenn die ID=8989 ist, dann ist der Chip ein SSD1289 und die original Init-Funktion sollte passen. Kann es der gleiche Fehler wie oben beschrieben sein : prüf nochmal “per Ohmmeter” die Verbindungsleitung von PE3 nach, die muss am Display am Pin “RS” ankommen. Und prüf alle Konfig Pins laut Datenblatt nochmal nach. Eingestellt sein muss der Mode : 16bit-parallel, 8080-Mode, i86-Interface, 16bit Farbe. (siehe Datasheet Kapitel 3.2 und 3.4)
Danke für die Unterstützung!
Habe den Fehler gefunden, bei der WR Leitung hatte es eine Kaltelötstelle.
Gruss
Hallo,
ich hätte bloß ein paar “Verständnisfragen” und zwar:
Man könnte ja das Display auch so ansteuern (z.B. write Befehl): Man legt kurz 0×22 mit RS=0 an irgendwelche GPIO-Ports an und dann mit RS=1 die Daten.
Denk ich da richtig?
Mit dem FSMC machst du ja eigentlich genau das gleiche. RS=PE3=FSMC_A19=1.
Meine eigentliche Frage ist nun:
A19 ist für mich =1 mit einer Adresse von 0×80000 aufwerts bis 0×100000.
Warum legst du aber um Daten zu schreiben die Adresse 60100000 an?
Ich weiß dass deine lib funktioniert, aber wo ist mein Denkfehler?
Hier nochmal der Code den ich nicht ganz verstehe:
//--------------------------------------------------------------
// Adressen vom FSMC um auf das Display zuzugreifen
// Bank = Bank-1 / PSRAM-1 => BaseAdr 0x60000000
// RS-Pin = PE3=FSMC_A19 = BitNr 19 => Offset 0x00100000
// (siehe Seite 1316+1317 vom Referenz Manual)
//--------------------------------------------------------------
#define LCD_REG (*((volatile unsigned short *) 0x60000000)) // RS = 0
#define LCD_RAM (*((volatile unsigned short *) 0x60100000)) // RS = 1
#define LCD_RAM_ADR 0x60100000 // Adresse vom RAM
grüße
Matthias
wenn du den FSMC nicht benutzen willst, kannst du das Display natürlich auch “per Hand” und normalen GPIO’s schalten…wird aber langsamer sein. Und ich habe die Seite vom RefManual ja dazugeschrieben, da steht warum die Adresse A19 (bzw. alle) um 1 Bit nach links verschoben ist.
Weil Bank 1 die Basis Adresse von 0×60000000 hat.
Sie Datenblatt Memory map
Hallo,
Danke für die schnelle Antwort. In meiner Version des Ref-Man wird auf Seite 1316-17 OTG_FS beschrieben. Ich konnte mir nicht vorstellen dort meine Antwort zu finden. Ich habe sie in meinem Refman auf Seite 1520-21 gefunden.
Auch danke an dich Joerg aber das war mir bereits bewusst.
Ach ja übrigens: Ich arbeite gerade an einer lib für den ssd1963(über den kann man 7″ ansteuern XD ) auch über fsmc und will meine lib gleich in deine integrieren. Wenn du willst kann ich dir diese dann zukommen lassen, um sie hier zu posten.
grüße
Matthias
Hallo Matthias,
hast du schon die Lib für den SSD1963 geschrieben?
Funktionierte auf Anhieb mit dem SainSmart 320×240 TFT LCD ohne adjustable shield.
REST auf high
Bei mir wird das display vom 3V-Spannungsregler des STM32F4 discovery boards versorgt und das geht auch. Hat jemand die Information gefunden, ob dieses display auch 3,3V abkann?
Vielen Dank für die library und die Beschreibung, einfacher geht’s nicht!
da gibts bestimmt ein Datenblatt von…da steht sowas drinn
Hallo,
gibt es schon ein Beispielcode für den SSD1963?
von mir nicht…ich schreibe nur über die Sachen die ich auch testen kann. Und ein Display mit SSD1963 hab ich nicht.
Hallo Uwe,
ich brauche Library für SSD1963. Kannst du mir helfen.
ich sagte doch schon : ich habe so ein Display nicht.
Hi wollte mal wissen ob das umschalten von landscape auf Portrai bei dir so einfach klapt bei mir passiert da einfach nix oder verstehe ich das ganze einfach nur falsch?
wenn ich umschalte auf Landscape dann habe ich doch querformat und meine koordinaten sind doch dann vertauscht oder wie soll ich das verstehen denn bei mir passiert nix und es wird immer noch alles genauso angezeigt wie vorher??
habe jetzt auch immer meine koordinaten umgesetzt aber leider klappt das mit der setdisplaywindow() dann nicht mehr wirklich und verstehen tu ich es auch nicht wirklich was du da genau machst wäre toll wenn du mir da mal helfen kannst
Der DisplayMode sagt aus in welcher weise eine Schrift oder ein Bild auf dem Display dargestellt wird. Die Seiten (x=kurze Seite und Y=lange Seite) bleiben dabei gleich. Bei dem Demo oben wird die Linie einmal auf der kurzen und im Landscape-Mode auf der langen Seite gezeichnet aber der Startpunkt (10,50) ist in beiden fällen gleich.
Hi, erstmal Danke für die Library!
Hat am Anfang alles funktioniert. Doch nach ein paar sec war das Display nur noch weiß. Nach dem ich dass Board neu eingesteckt und neu programmiert habe, wieder das gleiche. Bei den darauffolgenden Versuchen blieb das Display nur noch weiß! Was kann ich falsch gemacht haben? Als Transistor habe ich einen pnp BC307 verwendet, und alles so angesteckt wie beschrieben (Müsste stimmen sonst wäre kurzzeitig nicht das Display blau geworden mit dem roten Strich!).
Hoffe ihr könnt mir helfen!
Danke
klingt nach Hardware-BUG. Sind die Leitungen zum Display “short as possible” ?. Prüfe alle nochmal nach auf Verbindung und Kurzschluss.
Habe alles nochmals durchprobiert, immer noch das gleiche Problem. An den Verbindungen kann es fast nicht mehr liegen! Der Emitter wurde mit den 5V vom DiscoveryBoard Verbunden, der Kollektor mit den Backlight VDD des Displays, und die Basis mit PB0… Müsste doch alles stimmen?
Die Hintergrundbeleuchtung kannst du zur not auch direkt an +5V hängen (dann ist sie hallt immer an) aber ich Vermute den Fehler immer noch an den Zuleitungen. Funktioniert die Initialisierung , also wird dir richtige ID vom Display zurückgeliefert ?
Nach langem probieren hab ich gemerkt wie du gedacht hast: einer der Kabel spielt verrückt…
Jetzt heißt es wohl suchen
Danke für deine Hilfe
Hallo,
ich habe folgendes Problem:
Die Bibliothek funktioniert super und ich kann auch text auf dem Display ausgeben.
Nur funktioniert das leider nicht immer! Das Display muss einige mal vom Strom getrennt werden um den Text auf dem Display zu sehen. Jedoch dann hat er immer noch Pixelfehler die sich auch bei jedemmal neuen initialisieren an einer anderen Stelle widerfinden.
Die Kabel zum Display habe ich alle schon überprüft.
Hatte jemand schon einmal so ein Problem?
Gruß,
Sebastian
klingt nach hardware…welche länge haben deine Verbindungskabel zum display ? prüf die kabel noch ein zweitesmal nach “wackelkontakt” event. kannst du mal in der Software (im H-File) die zwei Werte “LCD_SSD1289_FSMC_AST” und “LCD_SSD1289_FSMC_DST” grösser machen, aber ich denke nicht das es das ist.
Vielen Dank für die schnelle Antwort.
Werde ich demnächst testen, wenn ich wieder in der Hochschule bin.
Gruß,
Sebastian
Hallo!
Ich habe mir das SainSmart 3.2″ Display mit dem SSD1289 Treiber gekauft. Das hat aber auch noch Touch und einen SD-Karten Slot, daher 40 Pins. Nun weiß ich nicht welcher wofür ist, und wie ich noch den Touch und die SD Karte ansteuern kann. Weißt du bisschen mehr als ich?
Ach hier noch der Link: http://www.sainsmart.com/sainsmart-3-2-tft-lcd-display-touch-panel-pcb-adapter-sd-slot-for-arduino-2560.html
Guten morgen,
eine super grundsätzliche Frage:
Warum brauche ich den überhaupt einen Controller, der STM32F4 kann das doch schon – oder verstehe ich das falsch.
Z.B. wenn ich das hier einsetzen will:
http://www.buydisplay.com/default/tft-4-3-inch-lcd-module-touchscreen-display-for-mp4-gps-480×272
Das ganze gibt es auch mit SSD1963:
http://www.buydisplay.com/default/4-3-lcd-touch-screen-module-display-tft-ssd1963-controller-mcu
Ich frage mich nur:
– Was für Vorteile habe ich durch einen Controller wie den SSD1963
– Wenn ich es richtig sehe, so sind die Anschlüsse an den SSD1963 identische mit einem Display ohne?? Controller (HSync, VSync, PixelClock,….)
– Vorteil von Platinen mit Controller ist oft, das die Stromversorgung der Hintergrundbeleuchtung integriert ist
Mein Ziel ist eine “Grafikkarte” die sich per CAN steuern lässt und einfach per CAN Message Bilder von einer SD – Karte abruft und eingaben auf den CAN Bus legt.
Ich würde mich freuen wenn mir hier jemand etwas bei der Entscheidungsfindung helfen würde.
Grüße
Etlam
der F407 hat keine TFT-Schnittstelle sondern nur eine DCMI
mit dem F429 könntest du ein Display auch ohne externen Controller betreiben
(der F429 hat einen TFT-Controller eingebaut)
der große Unterschied zwischen Displays mit Controllern und denen ohne
ist : ohne Controller brauchst du fast immer ein externes RAM
als Bildspeicher (im F429 Board ist ein externes 8MByte RAM verbaut)
bei 320 x 240 Pixel (a 16bit) brauchst du alleine für ein komplettes Bild 150 kByte RAM, wenn du dazu das interne RAM benutzt, bleibt nicht mehr viel
für deine restliche Software.
Hallo,
vielleicht bin ich ja blind aber wo sind denn die Funktionen wie SetPixel usw? Ich sehe nur Sachen wie LCD_RAM = color. Ist der Bildschirm im Speicher des Controllers gemapped (was ja ganz schön eng wird) und muss man sich Basisfunktionen wie Quadrat, Text, Linie usw. selbst schreiben? Sorry wegen der naiven Frage aber ich habe über die Sache bisher nur drüber geschaut. Eigentlich wäre mir ein 3.2z Display mit ILI9341 und SPI lieber aber leider finde ich keines. Denn dafür habe ich schon alles geschrieben.
Gruss,
Christian
der FMC spricht das Display wie ein externes RAM an
(das Display hat ja ein eingebautes RAM für 320 x 240 Pixel)
der Befehl : LCD_RAM = color ist also das “setpixel” an aktueller CursorPos
(CursorPos wird automatisch vom Display incrementiert)
und für Graphic gibt es eine extra Library von mir
und für Fonts wieder eine eigene.
Hallo,
habe ich die Grafik Lib und die Fonts jetzt übersehen? Finde den Link nicht.
Wollte mir da erst was selbst zusammenstricken, da ich 3 Font Größen brauche aber leider keine Seiten gefunden auf denen fertige header Files liegen. Ich schätze mal das ist die einzige Möglichkeit ein 3.2z Display an einen 407 zu flanschen. Diese Winzdinger vom 429er sind mir echt zu klein.
#7 : http://mikrocontroller.bplaced.net/wordpress/?page_id=507
#8 : http://mikrocontroller.bplaced.net/wordpress/?page_id=527
Danke. Und die lässt sich auf die Low Level Funktionen Lib vom SSD1289 anpassen? Dann bestelle ich mir nämlich die Displays jetzt in der Bucht.
ja.
Hi!
I try to use this LIB and found an interesting problem.
To display text string I wrote routine, when I code so
Set_back_Color(RGB_COL_BLACK);
Set_text_Color(RGB_COL_RED);
LCD_PutString8(20, 10, “Test TXT fOR LcD&?123″);
all work perfect, but if I use WHITE color for text
Set_back_Color(RGB_COL_BLACK);
Set_text_Color(RGB_COL_WHITE);
LCD_PutString8(20, 10, “Test TXT fOR LcD&?123″);
I have noise (by back_Color and text_Color colored) in text area (place selected by UB_LCD_SetWindow() routine). I tested some colors (RED, GREEN) but only with WHITE all time got a problem. What is wrong?
PS Big thank for yours LIBs, they are very helpfull for many people!
I think I solved the problem: I put a development board on a piece of metal foil, and the problem has disappeared. So the problem was due to long wires (some pieces have a length of 8 cm) and interference.
Hallo,
das gute zuerst deine Bibliotheken funktionieren meißt “out of the box”
Das Problem: Ich kann das Rechenbeispiel aus der STM Application note zum Berechnung des FSMC Timings bei der Display Anbindung nicht nachvollziehen.
Ist Applikartion note-AN 2790
Ich verwende einen STM32F407IGT6 mit 168 Mhz.
und auch ein SSD1289 LCD.
Könntest du mir ( am besten per Mail) nachvollziehbar erläutern, wie du die Timing werte berechnet hast.
Danke im Voraus.
Gruß
Marc