Hallo zusammen, ich versuche ein OLED-Display über die SPI-Schnittstelle meines PsoC 4 Entwicklerboards zu betreiben. Leider bisher ohne erfolg. Das Display ist ein Raystar 128x128 OLED-Display mit SSD1327ZB Controller (Datenblatt Siehe Anhang). Ich habe das Display nach vorgaben des Datenblatts angeschlossen und ein kleine Initialisierung dazu geschrieben. Pin: 1-->Ground 2-->5V 3-->Ground 4-->3V 5-->Ground 6-->Ground (SPI Mode) 7-->Ground (SPI Mode) 8-->nicht angeschlossen 9-->200k Ohm auf Ground 10-->Ausgang P0.0 Psoc4 11-->Ausgang P0.2 Psoc4 12-->Ausgang P0.1 PSOC4 13--> nicht angeschlossen 14--> nicht angeschlossen 15--> SCLK 16--> SDIN 17--> nicht angeschlossen 18--> nicht angeschlossen 19--> nicht angeschlossen 20--> nicht angeschlossen 21--> nicht angeschlossen 22--> nicht angeschlossen 23--> nicht angeschlossen 24--> nicht angeschlossen Zur SPI-Schnittstelle habe ich noch drei weitere benötigten digitale Ausgänge hinzugefügt. CS-> Chip Select DC-> Data/Command Control RES-> Reset Signal Das Display macht leider überhaupt nichts. Ich nehme an mein Programm ist fehlerhaft. Über Hilfe würde ich mich freuen Danke im Voraus.
Ich habe kein SSD1327 OLED hier. Wenn ich in eine Situation komme wo gar nichts geht, schaue ich wie andere das gemacht haben. https://github.com/ClockSelect/myevic/blob/master/src/SSD1327.c Schon die Initialisierung ist sehr verschieden und von Timing, wie bei PowerOn, sehe ich bei dir auch nichts.
Ich habe nun ein hilfreiches Muster gefunden und mein Hardwareaufbau etwas optimiert. Was mir noch Probleme bereitet ist die Funktion der Bildausgabe. Wenn ich den Bild-Code "pic1" an die Ausgabefunktion "Pic_show()" übergeben will nimmt er die Daten nicht an. So war es auch im Beispiel-Programm gelöst. int main(void) { SPIM_Start(); Power_On(); Write_Cmd(0xAE); //Set Display OFF Initial_SSD1327(); Pic_show(&pic1);// Ausgabe an Display Write_Cmd(0xAF); //Set Display On } void Pic_show(unsigned char ptr[][MAX_COL/2]){ unsigned char i=0,j=0; Write_Cmd(0x15); //Set Column Address Write_Cmd(0x00); //Start Column Address Write_Cmd(0x3F); //End Column Address Write_Cmd(0x75); //Set Row Address (segment) Write_Cmd(0x00); //Satrt Row Address Write_Cmd(0x7F); //End Row Address for (i = 0;i<MAX_ROW;i++){ for (j = 0;j<MAX_COL/2;j++){ Write_Data(ptr[i][j]); } } } unsigned char pic1 [MAX_ROW][MAX_COL/2]= { 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X 00,0X00, 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X 00,0X00, 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X .......
Das Display sieht aus, wie das EA W128128-XR und so eines hab ich hier laufen. Schau dir mal die Beschaltung des EA-Displays an. EA: Vcc Pin2 >12.5V ;-) Init hab ich auch noch:
1 | Procedure GraphInit; // Init W128128 |
2 | Begin |
3 | OLEDRst:=0; // /Reset |
4 | MDelay(100); |
5 | OLEDRst:=1; // Reset |
6 | MDelay(100); |
7 | |
8 | WriteLCD($A4,false); // Set normal display mode |
9 | WriteLCD($81,false); // Set contrast ... |
10 | WriteLCD($7F,false); // ... to $7F |
11 | WriteLCD($B3,false); // Ser clock divider/oscillator frequency ... |
12 | WriteLCD($40,false); // ... to 64 |
13 | WriteLCD($AF,false); // Display on |
14 | WriteLCD($A0,false); // Set memory addressing mode ... |
15 | WriteLCD(%01010001,false); // A = COM Split |
16 | // 0A0B0CDE // B = COM remap |
17 | // C = 0:horiz.incr. 1:vert.incr. |
18 | // D = Nipple remap |
19 | // E = Column remap |
20 | WriteLCD($A1,false); // Set display start line ... |
21 | WriteLCD($00,false); // ... to 0 |
22 | WriteLCD($A2,false); // Set display offset ... |
23 | WriteLCD($00,false); // ... to 0 |
24 | WriteLCD($2E,false); // Deactivate scroll |
25 | |
26 | MDelay(50); |
27 | End GraphInit; |
WriteLCD schreibt ein Byte über SPI. "false" heißt als Command-Byte (true wäre ein Datenbyte). Dein "Datenblatt" zum Display hat den Namen nicht verdient --> Mist! Was hast du für eine Buchse genommen? Da gibts nämlich bottom up und bottom down, je nachdem wo die Kontakte liegen. Bei der falschen Buchse gibts keinen Kontakt.
:
Bearbeitet durch User
Beitrag #5906115 wurde vom Autor gelöscht.
Hast du den Reset auch am Controller oder fest auf +Ub? Und, wie erwähnt, hast du die richtige Buchse? Mach mal vor und nach dem /CS eine Pause (bei mir reicht ein NOP) rein.
1 | Procedure WriteLCD(Arg:Byte;IsData:Boolean); |
2 | Begin |
3 | If IsData=true |
4 | then |
5 | PortC:=PinC or %00000100; // Daten PortC,2 |
6 | NOP; // ohne das gehts nicht |
7 | else |
8 | PortC:=PinC and %11111011; // Befehl |
9 | NOP; // ohne das gehts nicht |
10 | EndIf; |
11 | PortC:=PinC and %11101111; // /CS PortC,4 |
12 | SPIOutByteC(Arg); // Output arg |
13 | PortC:=PinC or %00010000; // CS |
14 | End WriteLCD; |
:
Bearbeitet durch User
Ja, das ist so ziemlich das selbe Display. Das Display ist genau so angeschlossen wie auf deinem Anschlussplan. VCC ist bei mir natürlich nicht 5V sondern 15V (vertippt). "WriteLCD schreibt ein Byte über SPI. "false" heißt als Command-Byte (true wäre ein Datenbyte)." So hatte ich das auch aus dem Datenblatt gelesen und eigentlich auch umgesetzt. "Dein "Datenblatt" zum Display hat den Namen nicht verdient --> Mist!" Da stimme ich Komplet zu :). "Was hast du für eine Buchse genommen? Da gibts nämlich bottom up und bottom down, je nachdem wo die Kontakte liegen. Bei der falschen Buchse gibts keinen Kontakt." Welche Buchse meinst du? Die FPC Buchse des Displays? Leider bisher alles ohne Erfolg. Das Display bleibt dunkel.
Flor B. schrieb: > Welche Buchse meinst du? Die FPC Buchse des Displays? genau. Meine Platine liegt hinten auf dem Display drauf, d.h. der Flexleiter ist nach hinten umgebogen und die Kontakte sind unten (hab ich mich vorhin getäuscht) --> bottom contact Buchse (nicht bottom up). Würdest du z.B. die Platine waagerecht hinter das Display montieren, so daß der Flexleiter auf der anderen Platinenseite ist, bräuchtest du eine top contact Buchse.
:
Bearbeitet durch User
falls es dich interessiert ..... Schreib mal lauter $FF in den Displayspeicher. Vielleicht liegen die paar Punkte die du setzt alle in den Ecken und runde Displays haben keine ;-)
:
Bearbeitet durch User
>Und, wie erwähnt, hast du die richtige Buchse? Ich nutze aktuell ein Breakoutboard, die Pinbelegung passt. >Schreib mal lauter $FF in den Displayspeicher. Vielleicht liegen die paar Punkte die du setzt alle in den Ecken und runde Displays haben keine ;-) In meiner Ausgabefunktion ist leider noch ein Fehler (Wie oben geschrieben). Aber die Displaydaten sollten passen. Das sie bereits auf einem Baugleichen Dsipay ausgegeben wurden.
Crazy H. schrieb: > falls es dich interessiert ..... > > Schreib mal lauter $FF in den Displayspeicher. Vielleicht liegen die > paar Punkte die du setzt alle in den Ecken und runde Displays haben > keine ;-) Wie hast du das mit der Displayausgabe (Ausgabefunktion) gelöst? Ich komme hier einfach nicht weiter...
Hallo Flor, dazu müßtest du mir sagen, wie dein Compiler grafische Displays behandelt. Hast du im RAM ein Displayabbild und überträgst es mit einer Refresh-Funktion zum Display oder arbeitest du direkt im Display? Bei mir ist ersteres der Fall. Harry
Hallo Harry, bei mir wäre auch ersteres der Fall. Bisher habe ich das mit der Funktion Pic-Show lösen wollen. An die Funktion übergebe ich einfach die auszugeben Bildschirmdaten. In diesem Fall die Daten pic1. Leider funktioniert der Übergabeparameter nicht. int main(void) { Pic_show(&pic1);// Ausgabe an Display } void Pic_show(unsigned char ptr[][MAX_COL/2]){ unsigned char i=0,j=0; Write_Cmd(0x15); //Set Column Address Write_Cmd(0x00); //Start Column Address Write_Cmd(0x3F); //End Column Address Write_Cmd(0x75); //Set Row Address (segment) Write_Cmd(0x00); //Satrt Row Address Write_Cmd(0x7F); //End Row Address for (i = 0;i<MAX_ROW;i++){ for (j = 0;j<MAX_COL/2;j++){ Write_Data(ptr[i][j]); } } } unsigned char pic1 [MAX_ROW][MAX_COL/2]= { 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X 00,0X00, 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X 00,0X00, 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X .......
Hallo Flor, bei mir sieht das so aus:
1 | UserDevice GraphIOS(Cmd:Byte;Arg:Byte); // Cmd=0 --> Page |
2 | Begin // Cmd=1 --> Daten |
3 | If Cmd=0 // nur einmalige Adressierung |
4 | then // notwendig |
5 | If Arg=0 |
6 | then |
7 | WriteLCD($15,false); // Set column address |
8 | WriteLCD($00,false); // Start address |
9 | WriteLCD($3F,false); // End address |
10 | WriteLCD($75,false); // Set page address |
11 | WriteLCD($00,false); // Start address |
12 | WriteLCD($7F,false); // End address |
13 | EndIf; |
14 | else |
15 | DispData[0]:=DispMap[((Arg and $C0) SHR 6)]; // Umwandlung sw --> 4-Bit Graustufen |
16 | DispData[1]:=DispMap[((Arg and $30) SHR 4)]; |
17 | DispData[2]:=DispMap[((Arg and $0C) SHR 2)]; |
18 | DispData[3]:=DispMap[ (Arg and $03) ]; |
19 | |
20 | For iCounter:=0 to 3 do // Ausgabe 8 Pixel |
21 | WriteLCD(DispData[iCounter],true); |
22 | EndFor; |
23 | EndIf; |
24 | End GraphIOS; |
Ja richtig erkannt, kein C. Daß das ein Graustufencontroller ist, weißt du? DispData ist bei mir einfach nur ein Array[0..3] of Byte und dient der Konvertierung s/w --> grau Gruss Harry vergessen: Const DispMap : Array[0..3] of Byte = ($00,$0F,$F0,$FF); Schick doch einfach mal nach der Zeilen-/Spaltenaddressierung 8192 $FF raus, dann muß das Display vollständig eingeschaltet sein, oder du schaltest beim Init auf invers um, dann muß es auch vollständig eingeschaltet sein. Wenn das nicht geht, ist was anderes faul. ..... noch was: mein Displayspeicher ist ein Array[0..2047] of Byte. Ein Bit=ein Pixel.
:
Bearbeitet durch User
Hallo Harry, das Display funktioniert nun:). Mit der Umwandlung der BMP-Datei tue ich mir aber noch etwas schwer. Ich brauche ja einen 8bit Wert für jedes Pixel. Die meisten Programme die BMP-Dateien Wandeln machen das aber mit 8Pixel/byte. Wie machst du das? Gruß Flor
Hi Flor, sorry grad erst gesehen .... deine Frage wurde bereits beantwortet, aber gerne nochmal:
1 | DispData[0]:=DispMap[((Arg and $C0) SHR 6)]; // Umwandlung sw --> 4-Bit Graustufen |
2 | DispData[1]:=DispMap[((Arg and $30) SHR 4)]; |
3 | DispData[2]:=DispMap[((Arg and $0C) SHR 2)]; |
4 | DispData[3]:=DispMap[ (Arg and $03) ]; |
5 | |
6 | For iCounter:=0 to 3 do // Ausgabe 8 Pixel |
7 | WriteLCD(DispData[iCounter],true); |
8 | EndFor; |
DispData : Array[0..3] of Byte; Arg sind die Display-Daten in sw. Harry
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.