Forum: Mikrocontroller und Digitale Elektronik ILI9341 reagiert anders als erwartet


von Jonas (Gast)


Lesenswert?

Moin,
ich versuche gerade ein LCD mit ILI9341 in Betrieb zu nehmen. Es ist ein 
320*240 TFT mit 16Bit Datenleitung. Im Testaufbau ist noch ein weiteres 
LCD verbaut welches wunderbar funktioniert. Beide Dislays teilen sich 
die WRX und DCX Datenleitungen. Pinbelegung am atmega2560:
1
#define WRX PG2  //LCD und TouchLCD
2
#define DCX PD7 //LCD und TouchLCD
3
#define T_LCD_RD PE3
4
#define T_LCD_CS PH3

DDRDs:
1
DDRG |= (1<<WRX); //WRX
2
DDRD |= (1<<DCX); //DCX
3
DDRH |= (1<<T_LCD_CS);
4
DDRE |= (1<<T_LCD_RD);
5
DDRH |= (1<<T_LCD_RST);


writeCmd und writePar:
1
void writeCmd9341(uint16_t Data){
2
  // CS  Low, DCX  low -> command, WRX from low to high, RDX high
3
  PORTH &=~ (1<<T_LCD_CS); //low Level CS
4
  PORTE |= (1<<T_LCD_RD);
5
  PORTD &=~ (1<<DCX); //low level command
6
  PORTG &=~ (1<<WRX);
7
  PORTC = (Data & 0xff);
8
  PORTA = ((Data >> 8) & 0xff);
9
  PORTG |= (1<<WRX);
10
  PORTH |= (1<<T_LCD_CS);
11
}
12
13
void writePar9341(uint16_t Data){
14
  //CS low, DCX hig -> register, WRX from low to high, rdx high
15
  PORTH &=~ (1<<T_LCD_CS); //low Level CS
16
  PORTE |= (1<<T_LCD_RD);
17
  PORTD |= (1<<DCX); //high level parameter
18
  PORTG &=~ (1<<WRX);
19
  PORTC = (Data & 0xff);
20
  PORTA = ((Data >> 8) & 0xff);
21
  PORTG |= (1<<WRX);
22
  PORTH |= (1<<T_LCD_CS);
23
}

Init Sequenz aufs kleinste Reduziert:
1
void init_ili9341(){
2
  DDRH |= (1<<T_LCD_CS);
3
  DDRE |= (1<<T_LCD_RD);
4
  DDRH |= (1<<T_LCD_RST);
5
  
6
  PORTH |= (1<<T_LCD_RST);
7
  _delay_ms(1); // Delay 1ms
8
  PORTH &=~(1<<T_LCD_RST);
9
  _delay_ms(100); // Delay 10ms // This delay time is necessary
10
  PORTH |= (1<<T_LCD_RST);
11
  _delay_ms(1000); // Delay 120 ms
12
13
  writeCmd9341(0x01);//soft reset
14
  _delay_ms(1000);
15
16
17
  //pixel format
18
  writeCmd9341(0x3A);
19
  writePar9341(0x55);
20
21
22
23
  //exit sleep
24
  writeCmd9341(0x11);
25
  _delay_ms(120);
26
  //display on
27
  writeCmd9341(0x29);
28
}

Ausgabetest:
1
  writeCmd9341(0x2c);
2
  for(unsigned long i = 0; i < 30000; i++){
3
    writePar9341(0x5522);
4
  }

Erwarten würde ich 30000 farbige Pixel, die Datenleitungen werden auch 
mit dem anderen Display geteilt und sind daher auch als Ausgänge 
angelegt.
Das ein und ausschalten des Display (0x28; 0x29) scheint zu klappen, 
wenn das Display eingeschaltet ist werden mehrere Bilder wechselnd 
angezeigt, mal einzelne Streifen, mal halber Bildschirm schwarz mal sehr 
Bunt, aber immer Streifen, keine einzelnen Pixel.
Ich hoffe ich hab nur Tomaten auf den Augen und ihr könnt mir 
weiterhelfen.


Viele Grüße
Jonas

: Bearbeitet durch Moderator
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jonas schrieb:
> Ich hoffe ... ihr könnt mir weiterhelfen.
Nimm bitte das nächste Mal [/c] am Ende des Codes. Halt einfach so, wie 
es in der Anleitung steht.
Und zum Prüfen, ob soweit alles passt, kann man die Vorschau nehmen...

: Bearbeitet durch Moderator
von Mitlesa (Gast)


Lesenswert?

Jonas schrieb:
> Ich hoffe ich hab nur Tomaten auf den Augen

Nö, du willst dir nur nicht das Datenblatt reinziehen oder
alternativ dazu ein existierendes Beispiel ansehen und
daraus lernen.

Die Init-Sequenz ist höchstwahrscheinlich so nicht ausreichend.

Und wenn man Pixel setzen will gehört dazu nicht nur das Kommando
0x2C sondern auch ein Kommando-Satz der dir ein Window definiert
das deinen Schreib-Bereich eingrenzt. Sonst schreibst du nur wild
irgendwo in deinen Grafik-Chip hinein.

Aber du hast dich ja schon anderweitig als lern- bzw. beratungs-
resistent und starrsinnig gezeigt. Warum sollte sich das jetzt
ändern ...

von Jojo (Gast)


Lesenswert?

Moin,
ich bin noch im Forum, aber denke das ich trotzdem helfen kann.
Bei der Initsequenz reicht so ein Minimum eigentlich aus, außer du 
möchtest den internen Speicher oder Gamma Korrekturen nutzen.

Das schreiben der einzelnen Pixel ohne Bildbereich sollte, solang du 
unter 240*320 bleibst kein Problem sein, wenn nachdem Softwarereset 
keine Fenster eingerichtet wird (2ah & 2bh) ist der erste Pixel D0 an X0 
und Y0.

Eventuell ist der Fehler im WritePar, da bin ich aber nicht so mega fit 
im Code lesen.


Viele Grüße
Johannes

von Jonas (Gast)


Lesenswert?

Moin,
ich habe jetzt die Initsequenz in der großen Form, wie in mehreren 
sample Codes übernommen und auch ein Fenster definiert. (auch wenn es im 
Datasheet nicht nötig scheint) Das Ergebnis ist wie vorher auch. Im 
Beitrag drunter gibt es gleich ein paar Fotos. Hilfe!!
1
void init_ili9341(){
2
  DDRH |= (1<<T_LCD_CS);
3
  DDRE |= (1<<T_LCD_RD);
4
  DDRH |= (1<<T_LCD_RST);
5
  
6
  PORTH |= (1<<T_LCD_RST);
7
  _delay_ms(1); // Delay 1ms
8
  PORTH &=~(1<<T_LCD_RST);
9
  _delay_ms(100); // Delay 10ms // This delay time is necessary
10
  PORTH |= (1<<T_LCD_RST);
11
  _delay_ms(1200); // Delay 120 ms
12
13
  writeCmd9341(0x01);//soft reset
14
  _delay_ms(150);
15
  
16
  writeCmd9341(0x01);//soft reset
17
  _delay_ms(1000);
18
  //power control A
19
  writeCmd9341(0xCB);
20
  writePar9341(0x39);
21
  writePar9341(0x2C);
22
  writePar9341(0x00);
23
  writePar9341(0x34);
24
  writePar9341(0x02);
25
26
  //power control B
27
  writeCmd9341(0xCF);
28
  writePar9341(0x00);
29
  writePar9341(0xC1);
30
  writePar9341(0x30);
31
32
  //driver timing control A
33
  writeCmd9341(0xE8);
34
  writePar9341(0x85);
35
  writePar9341(0x00);
36
  writePar9341(0x78);
37
38
  //driver timing control B
39
  writeCmd9341(0xEA);
40
  writePar9341(0x00);
41
  writePar9341(0x00);
42
43
  //power on sequence control
44
  writeCmd9341(0xED);
45
  writePar9341(0x64);
46
  writePar9341(0x03);
47
  writePar9341(0x12);
48
  writePar9341(0x81);
49
50
  //pump ratio control
51
  writeCmd9341(0xF7);
52
  writePar9341(0x20);
53
54
  //power control,VRH[5:0]
55
  writeCmd9341(0xC0);
56
  writePar9341(0x23);
57
58
  //Power control,SAP[2:0];BT[3:0]
59
  writeCmd9341(0xC1);
60
  writePar9341(0x10);
61
62
  //vcm control
63
  writeCmd9341(0xC5);
64
  writePar9341(0x3E);
65
  writePar9341(0x28);
66
67
  //vcm control 2
68
  writeCmd9341(0xC7);
69
  writePar9341(0x86);
70
71
  //memory access control
72
  writeCmd9341(0x36);
73
  writePar9341(0x48);
74
75
  //pixel format
76
  writeCmd9341(0x3A);
77
  writePar9341(0x55);
78
79
  //frameration control,normal mode full colours
80
  writeCmd9341(0xB1);
81
  writePar9341(0x00);
82
  writePar9341(0x18);
83
84
  //display function control
85
  writeCmd9341(0xB6);
86
  writePar9341(0x08);
87
  writePar9341(0x82);
88
  writePar9341(0x27);
89
90
  //3gamma function disable
91
  writeCmd9341(0xF2);
92
  writePar9341(0x00);
93
94
  //gamma curve selected
95
  writeCmd9341(0x26);
96
  writePar9341(0x01);
97
98
  //set positive gamma correction
99
  writeCmd9341(0xE0);
100
  writePar9341(0x0F);
101
  writePar9341(0x31);
102
  writePar9341(0x2B);
103
  writePar9341(0x0C);
104
  writePar9341(0x0E);
105
  writePar9341(0x08);
106
  writePar9341(0x4E);
107
  writePar9341(0xF1);
108
  writePar9341(0x37);
109
  writePar9341(0x07);
110
  writePar9341(0x10);
111
  writePar9341(0x03);
112
  writePar9341(0x0E);
113
  writePar9341(0x09);
114
  writePar9341(0x00);
115
116
  //set negative gamma correction
117
  writeCmd9341(0xE1);
118
  writePar9341(0x00);
119
  writePar9341(0x0E);
120
  writePar9341(0x14);
121
  writePar9341(0x03);
122
  writePar9341(0x11);
123
  writePar9341(0x07);
124
  writePar9341(0x31);
125
  writePar9341(0xC1);
126
  writePar9341(0x48);
127
  writePar9341(0x08);
128
  writePar9341(0x0F);
129
  writePar9341(0x0C);
130
  writePar9341(0x31);
131
  writePar9341(0x36);
132
  writePar9341(0x0F);
133
134
  //exit sleep
135
  writeCmd9341(0x11);
136
  _delay_ms(120);
137
  //display on
138
  writeCmd9341(0x29);
139
  
140
}
init_ili9341();
  writeCmd9341(0x2a);
  writePar9341(0);
  writePar9341(130);
  writePar9341(0);
  writePar9341(150);
  writeCmd9341(0x2b);
  writePar9341(0);
  writePar9341(130);
  writePar9341(0);
  writePar9341(150);

   writeCmd9341(0x2c);
  for(unsigned long i = 0; i < 50; i++){
    writePar9341(0x000);
  }
[c]

Viele Grüße
Jonas

von Jonas (Gast)



Lesenswert?

Hier einmal ein paar Fotos des unkontrollierbaren Displays.

von Bew Underer (Gast)


Lesenswert?

Jonas schrieb:
> Hier einmal ein paar Fotos des unkontrollierbaren Displays.

Sehr beeindruckend und aussagekräftig.

von Jonas (Gast)


Lesenswert?

Bew Underer schrieb:
> Jonas schrieb:
>> Hier einmal ein paar Fotos des unkontrollierbaren Displays.
>
> Sehr beeindruckend und aussagekräftig.

Danke für diese aussagekräftige Hilfe.

von Bew Underer (Gast)


Lesenswert?

Jonas schrieb:
> Danke für diese aussagekräftige Hilfe.

Wenn du so professionell programmierst wie du fotografierst
dann brauchst du ja keine weitere Hilfe.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Jonas schrieb:
> PORTH &=~ (1<<T_LCD_CS); //low Level CS
>   PORTE |= (1<<T_LCD_RD);
>   PORTD &=~ (1<<DCX); //low level command
>   PORTG &=~ (1<<WRX);
>   PORTC = (Data & 0xff);
>   PORTA = ((Data >> 8) & 0xff);
>   PORTG |= (1<<WRX);
>   PORTH |= (1<<T_LCD_CS);

Also, ich kenne dein Display nicht - aber ich weiss, das es immer 
sinnvoll ist, zuerst die Daten anzulegen, dann den Chip freizugeben und 
sie dann in den Chip rein zu takten. Wenn das alles erledigt ist, kann 
man den Chip wieder sperren (mit CS) und die Daten durch andere 
ersetzen.

: Bearbeitet durch User
von John Doe (Gast)


Lesenswert?

@Jonas:
Was an "Längeren Sourcecode nicht im Text einfügen, sondern als 
Dateianhang" hast Du nicht verstanden?

von John Doe (Gast)


Lesenswert?

Hast Du das Dateblatt gelesen?
Z.B. den Satz:
"The display read [...] lines when there is a rising edge of WRX"?

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.