Forum: Mikrocontroller und Digitale Elektronik Bild an TFT Display anzeigen


von clincii (Gast)


Lesenswert?

Moin Moin,

ich muss an einem TFT-Display ein Bild ausgeben, jedoch habe ich absolut 
keine Ahnung wie ich das Bild im Code ausgeben bzw. in einer Variabel 
abspeichern kann.

Ich hoffe jemand hat ein Beispielcode wie man ein Bild am Display 
anzeigen kann. Ich programmiere in C++ mit dem Programm Eclipse.

Mit freundlichen Grüssen clincii:D

PS: Display         -->NHD-2.4-240320SF-CTXL#-FTN1
    Mikrocontroller --> STM32F407

: Verschoben durch User
von proggen (Gast)


Lesenswert?

http://www.newhavendisplay.com/specs/NHD-2.4-240320SF-CTXL-FTN1.pdf
verweist auf:
http://www.newhavendisplay.com/app_notes/ILI9341.pdf

Wenn du fertige libs suchst:
"ILI9341 library" oder "ILI9341 api" lauten die Suchbegriffe.

Da wirst du aber bestimmt noch einiges konfigurieren müssen...


Have a nice day :)

von clincii (Gast)


Lesenswert?

Hallo proggen,

viel Dank für die Antwort, die beiden Datasheets habe ich bereits 
angeschaut sowie ein wenig studiert.

Ich habe leider immer noch nicht die leiseste Ahnung wie ich das Bild 
dem Display übergeben kann. Hätte jemand ein Beispiel wie man ein Bild 
an ein TFT Display übergeben kann?

Worauf muss ich achten? Kann ich das Bild(z.B. .jpg) direkt an die 
Datenleitungen des Display senden oder muss ich das Bild in die 
einzelene Pixel aufteilen und jedes Pixel einzel ansteuern?

Danke !

von Markus S. (acepilot)


Lesenswert?

Warum fängt eigentlich jeder zweite hier mit einem STM32F4 und Displays 
an? Und das scheinbar ohne wirklich einen genaueren Durchblick zu haben.

Hast du denn schon irgendetwas in Code geschrieben? Dann wäre es 
hilfreich, wenn du diesen mit hier anhängst damit man dir helfen kann. 
Der übliche Ablauf ist die benötigten Schnittstellen für das Display zu 
initialisieren. Wenn das geschehen ist muss das Display nach 
Datenblattangaben ebenfalls initialisiert werden. Erst wenn das 
geschehen ist kannst du versuchen etwas auf das Display zu zaubern.

Bevor du dann an die Ausgabe von Bildern denkst fang doch erstaml mit 
einer Linie und Text an. Wenn dies dann funktioniert ist der Weg zu 
einem Bild auch nicht mehr weit.

von clincii (Gast)


Lesenswert?

Hallo,

Das Projekt ist ein Funkgerät, welches von den letztjährigen Lehrlingen 
begonnen wurde. Nun erhielt ich den Auftrag dieses zu beenden.
Und ich muss nun eben ein Bild am Display anzeigen können.

Der Code umfasst mehrere 1000 Zeilen..
Die Initialisierung des Display wurde bereits vorgenommen.

Ich möchte nur wissen wie man ein Bild an das Display sendet!

Mfg

von Thomas F. (igel)


Lesenswert?

clincii schrieb:
> viel Dank für die Antwort, die beiden Datasheets habe ich bereits
> angeschaut sowie ein wenig studiert.

Anschauen und ein wenig studieren reicht aber nicht.
Als ich meine Lib für ein TFT schrieb habe ich das Datasheet zweimal 
komplett durchgelesen und dann abschnittsweise den Code erstellt.


> Ich habe leider immer noch nicht die leiseste Ahnung wie ich das Bild
> dem Display übergeben kann. Hätte jemand ein Beispiel wie man ein Bild
> an ein TFT Display übergeben kann?

Du musst dir Datenschnittstelle des Displays schon selber verstehen. 
Sonst wird das nix.


> Kann ich das Bild(z.B. .jpg) direkt an die
> Datenleitungen des Display senden oder muss ich das Bild in die
> einzelene Pixel aufteilen und jedes Pixel einzel ansteuern?

Hä? Jpeg ist ein komprimiertes Format! Das muss erst mal in ein Bitmap 
dekomprimiert werden. Und dann schickt man die Pixel ans Display.

von Markus S. (acepilot)


Lesenswert?

Schau dir die Seiten ab 110 bis 113 an. Mit Hilfe dieser Befehle kannst 
du dir einen Bereich definieren, in dem Daten auf dem Display geändert 
werden sollen, wenn nicht das gesamte Display überschrieben werden soll.

Seite 114 vom Datasheet zeigt dir dann wie du ein Pixel an das Display 
schicken kannst. Die Daten die du schicken musst sind aber auch abhängig 
von dem verwendeten Color Mode, somit von deiner Initialisierung von der 
du uns ja nichts zeigen möchtest.

Ansonsten hat Thomas vollkommen recht, mit einem JPEG kannst du nichts 
anfangen, du benötigst ein unkomprimiertes Bitmapfile.

von clincii (Gast)


Lesenswert?

Hier die Initialisierung des Displays..
1
 void DisplayInit(){
2
   // Display D4 to D0
3
   GPIO_InitTypeDef GPIO_InitStruct;
4
   GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
5
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
6
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
7
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
8
   GPIO_Init(GPIOE, &GPIO_InitStruct);
9
10
   // Display D7 to D5
11
   GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
12
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
13
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
14
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
15
   GPIO_Init(GPIOB, &GPIO_InitStruct);
16
17
   // Display *Read | *Write | Data/Command
18
   GPIO_InitStruct.GPIO_Pin =  LCD_WRITE | LCD_READ | LCD_DC;
19
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
20
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
21
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
22
   GPIO_Init(GPIOE, &GPIO_InitStruct);
23
24
   // Display *Reset
25
   GPIO_InitStruct.GPIO_Pin =  LCD_RESET;
26
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
27
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
28
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
29
   GPIO_Init(GPIOC, &GPIO_InitStruct);
30
31
   //Touch Controller Chip Select
32
  GPIO_InitStruct.GPIO_Pin = TCH_CS;                      //Chip Select Init
33
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;                  //Output
34
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
35
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
36
  GPIO_Init(GPIOE, &GPIO_InitStruct);
37
38
  // SETUP EXTERNAL INTERRUPT PIN
39
  GPIO_InitStruct.GPIO_Pin = TCH_INT;                      // Touch Interrupt
40
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;                  // Input
41
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
42
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
43
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
44
  GPIO_Init(GPIOC, &GPIO_InitStruct);
45
46
  GPIO_SetBits(GPIOE, TCH_CS);    // Touch Controller /Select
47
48
    // PWM Pin Alternate Function DISPLAY BACKLIGHT
49
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
50
    // PWM Output
51
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
52
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
53
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
54
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
55
    GPIO_Init(GPIOD, &GPIO_InitStruct);
56
57
  /****************************************************************/
58
  /*            LCD Backlight PWM            */
59
  /****************************************************************/
60
    TIM_TimeBaseInitTypeDef TIMER_InitStructure;
61
  TIMER_InitStructure.TIM_Prescaler = 2;
62
  TIMER_InitStructure.TIM_Period = 0;
63
  TIMER_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
64
  TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
65
  TIM_TimeBaseInit(TIM4, &TIMER_InitStructure);
66
67
  TIM_OCInitTypeDef  TIM_OCInitStructure;
68
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
69
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
70
  TIM_OCInitStructure.TIM_Pulse = 0;              // Set PWM duty cycle to 0%
71
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
72
  TIM_OC1Init(TIM4, &TIM_OCInitStructure);          // OC1  ->  Channel 1  ->  PIN12, PORTD
73
  TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
74
75
  TIM_SetAutoreload(TIM4,2099);                // Set PWM to 10kHz
76
  TIM_Cmd(TIM4, ENABLE);                    // enable timer / counter (timer4)
77
  TIM_ARRPreloadConfig(TIM4, DISABLE);              // preload timer configuration
78
79
80
   /****************************************************************/
81
   /*            LCD init                */
82
   /****************************************************************/
83
84
   GPIO_ResetBits(GPIOC , LCD_RESET);      // Enable the Reset
85
   GPIO_SetBits(GPIOE , LCD_READ);        // Disable the Read mode
86
   GPIO_SetBits(GPIOE , LCD_WRITE);      // Disable the Write mode
87
   GPIO_SetBits(GPIOE , LCD_DC);        // Enable the Data mode
88
   delay(1200);                // Wait 120ms
89
   GPIO_SetBits(GPIOC , LCD_RESET);      // Disable the Reset
90
   delay(1200);                // Wait 120ms
91
92
   LCD_Cmd(CMD_SOFTRESET);      // Soft Reset
93
   delay(100);            // delay 10ms
94
   LCD_Cmd(CMD_DISPOFF);           // display off
95
   LCD_Cmd(CMD_SLPOUT);            // exit SLEEP mode
96
   LCD_Cmd(CMD_PWR_CTRL_A);        // power control A
97
   LCD_Data(0x39);
98
   LCD_Data(0x2C);
99
   LCD_Data(0x00);
100
   LCD_Data(0x34);
101
   LCD_Data(0x02);
102
   LCD_Cmd(CMD_PWR_CTRL_B);        //power control B
103
   LCD_Data(0x00);
104
   LCD_Data(0x81);
105
   LCD_Data(0x30);
106
   LCD_Cmd(CMD_PWR_CTRL_1);
107
   LCD_Data(0x26);                 //power control 1
108
   LCD_Data(0x04);                 //second param for ILI9340 (ignored by ILI9341)
109
   LCD_Cmd(CMD_PWR_CTRL_2);
110
   LCD_Data(0x11);                 //power control 2
111
   LCD_Cmd(CMD_VCOM_CTRL_1);
112
   LCD_Data(0x35);
113
   LCD_Data(0x3E);                 //VCOM control 1
114
   LCD_Cmd(CMD_MEM_ACC_CTRL);
115
   LCD_Data(0xA8);                 //memory access control = BGR and flip col&add
116
   LCD_Cmd(CMD_FRAME_RATE_CTRL);
117
   LCD_Data(0x00);
118
   LCD_Data(0x18);                 //frame rate control
119
   LCD_Cmd(CMD_DISP_FUNC_CTRL);
120
   LCD_Data(0x0A);
121
   LCD_Data(0xA2);                 //display function control
122
   LCD_Cmd(CMD_VCOM_CTRL_2);
123
   LCD_Data(0xBE);                 //VCOM control 2
124
   LCD_Cmd(CMD_PIXEL_FORMAT);
125
   LCD_Data(0x55);                 //pixel format = 16 bit per pixel
126
   LCD_Cmd(GAMMA_CONTROL);         //3g gamma control
127
   LCD_Data(0x02);                 //off
128
   LCD_Cmd(GAMMA_CURVE);           //gamma curve 3
129
   LCD_Data(0x01);
130
   LCD_Cmd(COLUMN_ADDRESS);
131
   LCD_Data(0x00);                 //column address set
132
   LCD_Data(0x00);                 //start 0x0000
133
   LCD_Data(0x00);
134
   LCD_Data(0xEF);                 //end 0x00EF
135
   LCD_Cmd(PAGE_ADDRESS);
136
   LCD_Data(0x00);                 //page address set
137
   LCD_Data(0x00);                 //start 0x0000
138
   LCD_Data(0x01);
139
   LCD_Data(0x3F);                 //end 0x003F
140
   LCD_Cmd(CMD_MEM_ACC_CTRL);
141
   LCD_Data(CMD_MEM_ACC_DATA);
142
   LCD_Cmd(CMD_PIXEL_FORMAT);
143
   LCD_Data(0xC5);
144
   LCD_Cmd(CMD_DISPON);            //display ON
145
   delay(100);          // Wait 10ms
146
147
   LCD_Fill(WHITE);        // Draw Background
148
149
  /****************************************************************/
150
  /*          Touch SPI + Interrupt Init          */
151
  /****************************************************************/
152
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);    // SPI Touch Controller
153
  //Set SPI Pins as Alternate Function
154
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);        //Connect SPI Pin CLK to SPI1
155
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);        //Connect SPI Pin MOSI to SPI1
156
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);        //Connect SPI Pin MISO to SPI1
157
158
  GPIO_InitStruct.GPIO_Pin = TCH_CLK | TCH_MISO  | TCH_MOSI;          // CLK | MISO
159
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
160
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;            // Alternative Function -> SPI
161
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
162
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
163
  GPIO_Init(GPIOA, &GPIO_InitStruct);
164
165
  //SPI Communication Init
166
  SPI_InitTypeDef SPI_InitStruct;
167
  SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;  //656.25kHz  (84MHz/128)
168
  SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;    //Full Duplex
169
  SPI_InitStruct.SPI_Mode = SPI_Mode_Master;              //Master
170
  SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;            //8bit
171
  SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;                //Software Chip Select
172
  SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;            //MSB first
173
  SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;              //Clock Idle High
174
  SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;              //2nd Edge -> L->H -> Rising edge
175
  SPI_Init(SPI1, &SPI_InitStruct);                  //Setup SPI1
176
  SPI_Cmd(SPI1, ENABLE);                        //Enable SPI1
177
178
   RESTART_SPI:
179
180
   TscWrite (STMPE811_SPI_CFG, 1, STMPE811_SPI_MODE_1 | STMPE811_AUTO_INCR);//STMPE811_SPI_MODE_2 | STMPE811_AUTO_INCR); //MODE 1 and 2 WORKS
181
182
   TscRead(STMPE811_CHIP_ID, 2);  // read chip ID
183
   if((SPI_Buffer[0] != 0x08))      // if not good -> big problem
184
   {
185
     goto RESTART_SPI;
186
   }
187
   if((SPI_Buffer[1] != 0x11)){
188
     goto RESTART_SPI;
189
   }
190
191
   // Enable TSC,and set TSC operating mode is X, Y only.
192
   TscWrite (STMPE811_TSC_CTRL, 1, STMPE811_TSC_CTRL_EN | STMPE811_TSC_CTRL_XY);
193
   // Enable TSC and ADC
194
   TscWrite (STMPE811_SYS_CTRL2, 1, STMPE811_CTRL2_TS_OFF |
195
                    STMPE811_CTRL2_GPIO_OFF);
196
   // Enable Touch detect, FIFO interrupt.
197
   TscWrite (STMPE811_INT_EN, 1, STMPE811_INT_EN_TOUCHDET |
198
                 STMPE811_INT_EN_TH |
199
                 STMPE811_INT_EN_FIFOOFLOW);
200
   // To select sample time, bit number and ADC reference.
201
   TscWrite (STMPE811_ADC_CTRL1, 1, ((0x06 & STMPE811_ADC_CTRL1_SAMPLE_M)
202
                    << STMPE811_ADC_CTRL1_SAMPLE_S )|
203
                    STMPE811_ADC_CTRL1_MOD);
204
   // To select the ADC clock speed is 3.25 MHz.
205
   TscWrite (STMPE811_ADC_CTRL2, 1, STMPE811_ADC_CTRL2_CLK1);
206
   // To set Average, Touch Detect Delay and Setting Time setting.
207
   TscWrite (STMPE811_TSC_CFG, 1,
208
       STMPE811_TSC_CFG_AVE_8|
209
        ((0x7 & STMPE811_TSC_CFG_DELAY_M) << STMPE811_TSC_CFG_DELAY_S)|
210
        ((0x1 & STMPE811_TSC_CFG_SETTING_M)
211
        << STMPE811_TSC_CFG_SETTING_S));
212
   // Set FIFO threshold level.
213
   TscWrite (STMPE811_FIFO_TH, 1, 0x01);
214
   // Reset FIFO.
215
   TscWrite (STMPE811_FIFO_STA, 1, STMPE811_FIFO_STA_RESET);
216
   // Write 0x00 to put the FIFO back into operation mode.
217
   TscWrite (STMPE811_FIFO_STA, 1, 0x00);
218
   // Set the data format for Z value.
219
   TscWrite (STMPE811_TSC_FRACTION_Z, 1,
220
          (0x07 * STMPE811_FRACTION_Z_M) << STMPE811_FRACTION_Z_S);
221
   // Set the driving capability of the device for touchscreen controller pins.
222
   TscWrite (STMPE811_TSC_I_DRIVE, 1, STMPE811_TSC_I_DRIVE_50);
223
   // Set tracking index, set touchscreen controller op. mode and enable TSC
224
225
   TscWrite (STMPE811_TSC_CTRL, 1,STMPE811_TSC_CTRL_EN |STMPE811_TSC_CTRL_XY);
226
   // Clear all the interrupt status.
227
   TscWrite (STMPE811_INT_STA, 1, 0xFF);
228
   // Set interrupt mode and enable interrupt.
229
   TscWrite (STMPE811_INT_CTRL, 1, STMPE811_INT_TYPE|
230
            STMPE811_INT_GLOBAL);
231
232
   //CHECK IF VALUES OF TC REGISTERS CORRECTLY WRITTEN
233
   TRYAGAIN:
234
   SPI_Buffer[0]=0;
235
   TscRead(STMPE811_ID_VER, 1);    //Check SPI communication by asking for Chip ID x03
236
   if(SPI_Buffer[0]!= 0x03){
237
     goto TRYAGAIN;
238
   }
239
240
   // set display backlight
241
   uint16_t backlight = 0;
242
   while(backlight < 2100){
243
     backlight+=4;
244
     TIM_SetCompare1(TIM4, backlight);  // Set duty cycle to 100%
245
     delay(10);  //1ms
246
   }
247
 }


Kann man mit dem STM32F4 die Dateiumwandlung von jpeg in bmp vornehmen?
Oder muss ich dafür das Bild zuerest auf den PC Laden um eine 
Bitmapdatei zu erstellen?

Mfg

von Thomas F. (igel)


Lesenswert?

clincii schrieb:
> LCD_Fill(WHITE);        // Draw Background

Da hast du doch schon eine Routine um ein Bild auszugeben. Das Bild ist 
halt derzeit lediglich einfarbig.
Das kannst du jetzt für ein BMP umschreiben.

von Markus S. (acepilot)


Lesenswert?

Laut deiner Initialiserung benutzt du den 16Bit Modus. Das Bild würde 
ich vorher schon am PC in ein Bitmap wandeln. Achte darauf das es auch 
dort schon direkt 16Bit hat. Danach kannst du einfach Pixel für Pixel 
des Bildes an das LCD schicken.

Habe dir mal auszugsweise zwei Funktionen von mir angehängt, die ich für 
mein ILI9341 Display nutze. Vielleicht hilft dir das ja schon weiter.
1
//--------------------------------------------------------------
2
// Zeichnet ein Pixel mit einer Farbe an x,y Position
3
//--------------------------------------------------------------
4
void LCD_DrawPixel(int16_t xpos, int16_t ypos, uint16_t color)
5
{
6
  uint8_t hi,lo;
7
8
  LCD_SetWindow(xpos,ypos,xpos,ypos);
9
10
  hi=color>>8;
11
  lo=color&0xFF;
12
13
  P_LCD9341_CMD(0x2C);
14
  P_LCD9341_DATA(hi);
15
  P_LCD9341_DATA(lo);
16
17
}
18
19
20
//--------------------------------------------------------------
21
// stellt ein Display-Fenster zum zeichnen ein
22
// von xtart,ystart zu xend,yend
23
//--------------------------------------------------------------
24
void LCD_SetWindow(uint16_t xstart, uint16_t ystart, uint16_t xend, uint16_t yend)
25
{
26
  uint8_t hi1,lo1;
27
  uint8_t hi2,lo2;
28
29
  hi1=xstart>>8;
30
  lo1=xstart&0xFF;
31
32
  hi2=xend>>8;
33
  lo2=xend&0xFF;
34
35
  P_LCD9341_CMD(0x2A);
36
  P_LCD9341_DATA(hi1);
37
  P_LCD9341_DATA(lo1);
38
  P_LCD9341_DATA(hi2);
39
  P_LCD9341_DATA(lo2);
40
41
  hi1=ystart>>8;
42
  lo1=ystart&0xFF;
43
44
  hi2=yend>>8;
45
  lo2=yend&0xFF;
46
47
  P_LCD9341_CMD(0x2B);
48
  P_LCD9341_DATA(hi1);
49
  P_LCD9341_DATA(lo1);
50
  P_LCD9341_DATA(hi2);
51
  P_LCD9341_DATA(lo2);
52
}
53
54
//--------------------------------------------------------------
55
// interne Funktion
56
// Kommando per SPI an Display senden
57
//--------------------------------------------------------------
58
void P_LCD9341_CMD(uint8_t wert)
59
{
60
  // Kommando
61
  P_LCD9341_WRX(Bit_RESET);
62
63
  // ChipSelect auf Lo
64
  P_LCD9341_CS(Bit_RESET);
65
66
  // Wert senden
67
  spi_writeByte(wert);
68
 
69
  // ChipSelect auf Hi
70
  P_LCD9341_CS(Bit_SET);
71
}
72
73
74
//--------------------------------------------------------------
75
// interne Funktion
76
// Daten per SPI an Display senden
77
//--------------------------------------------------------------
78
void P_LCD9341_DATA(uint8_t wert)
79
{
80
  // Data
81
  P_LCD9341_WRX(Bit_SET);
82
83
  // ChipSelect auf Lo
84
  P_LCD9341_CS(Bit_RESET);
85
86
  // Wert senden
87
  spi_writeByte(wert);
88
89
  // ChipSelect auf Hi
90
  P_LCD9341_CS(Bit_SET);
91
}

von dasrotemopped (Gast)


Lesenswert?

Erster Treffer bei Google :

Code für Copy+Paste:
http://stm32f4-discovery.net/2014/04/library-08-ili9341-lcd-on-stm32f429-discovery-board/

Gruß,

dasrotemopped.

von Dauergast (Gast)


Lesenswert?

dasrotemopped schrieb:
> 
http://stm32f4-discovery.net/2014/04/library-08-ili9341-lcd-on-stm32f429-discovery-board/

Irgendeine Bibliothek wird ja schon benutzt (siehe LCD_Fill() im 
Init-Code). Da die für den ILI9341 alle irgendwie "gleich" aussehen, 
würde ich mal wetten, daß das schon alles vorhanden ist :-)

Irgendwo gibt es sicher auch schon eine BMP_to_ILI9341-Funktion, die 
kann man einfach finden und benutzen, denn das Anzeigen eines statischen 
Bildes auf dem Display eines Funkgerätes dürfte ja sowieso nicht das 
endgültige Ziel sein.

von clincii (Gast)


Lesenswert?

Dauergast schrieb:
> denn das Anzeigen eines statischen
> Bildes auf dem Display eines Funkgerätes dürfte ja sowieso nicht das
> endgültige Ziel sein.

Stimmt, schlussundendlich sollte ich dann mit einem Funkgerät ein Foto 
aufnehmen können und an das andere Funkgerät schicken. Das Bild wird auf 
dem Display angezeigt sowie auf einer SD-Karte abgespeichert.
Dasselbe gilt für die SMS-Funktion

Dauergast schrieb:
> Irgendeine Bibliothek wird ja schon benutzt (siehe LCD_Fill() im
> Init-Code). Da die für den ILI9341 alle irgendwie "gleich" aussehen,
> würde ich mal wetten, daß das schon alles vorhanden ist :-)

Das habe ich mir auch schon gedacht, dass ich eigentlich diese Funktion 
nehmen kann. Jedoch verstehe ich nicht genau wie ich dann die einzelnen 
Pixel des Bitmaps ans Display schicken kann.
Klar bei einem Bitmap welches total weiss ist, ist dies kein Problem.

Hier findet ihr noch die Funktion LCD_FILL
1
void LCD_Fill(uint16_t color)
2
{
3
  uint16_t  column;    // column counter
4
  uint16_t  page;       // pages counter
5
  uint8_t colorH, colorL;
6
  colorH = color >> 8;
7
  colorL = color;
8
9
  //TODO: put this in a function
10
  //Part 1 Bitswap
11
  uint16_t swap_colH_1 = colorH;
12
  swap_colH_1 = (swap_colH_1 & 0xF0)>>4 | (swap_colH_1 & 0x0F)<<4;
13
  swap_colH_1 = (swap_colH_1 & 0xCC)>>2 | (swap_colH_1 & 0x33)<<2;
14
  swap_colH_1 = (swap_colH_1 & 0xAA)>>1 | (swap_colH_1 & 0x55)<<1;
15
  swap_colH_1 &=  0x0007;
16
17
  uint16_t swap_colH_2 = colorH;
18
  swap_colH_2 = ((swap_colH_2 >> 8) & 0x00FF) | ((swap_colH_2 << 8) & 0xFF00);
19
  swap_colH_2 = ((swap_colH_2 >> 4) & 0x0F0F) | ((swap_colH_2 << 4) & 0xF0F0);
20
  swap_colH_2 = ((swap_colH_2 >> 2) & 0x3333) | ((swap_colH_2 << 2) & 0xCCCC);
21
  swap_colH_2 = ((swap_colH_2 >> 1) & 0x5555) | ((swap_colH_2 << 1) & 0xAAAA);
22
  swap_colH_2 = (swap_colH_2 >> 3);
23
  swap_colH_2 &= 0x1F00;
24
25
  uint16_t colorH_swapped_1 = GPIO_ReadOutputData(GPIOB);
26
  uint16_t colorH_swapped_2 = GPIO_ReadOutputData(GPIOE);
27
  colorH_swapped_1 = swap_colH_1 | (colorH_swapped_1 & 0xFFF8);
28
  colorH_swapped_2 = swap_colH_2 | (colorH_swapped_2 & 0xE0FF);
29
30
  //Part 2 Bitswap
31
  uint16_t swap_colL_1 = colorL;
32
  swap_colL_1 = (swap_colL_1 & 0xF0)>>4 | (swap_colL_1 & 0x0F)<<4;
33
  swap_colL_1 = (swap_colL_1 & 0xCC)>>2 | (swap_colL_1 & 0x33)<<2;
34
  swap_colL_1 = (swap_colL_1 & 0xAA)>>1 | (swap_colL_1 & 0x55)<<1;
35
  swap_colL_1 &=  0x0007;
36
37
  uint16_t swap_colL_2 = colorL;
38
  swap_colL_2 = ((swap_colL_2 >> 8) & 0x00FF) | ((swap_colL_2 << 8) & 0xFF00);
39
  swap_colL_2 = ((swap_colL_2 >> 4) & 0x0F0F) | ((swap_colL_2 << 4) & 0xF0F0);
40
  swap_colL_2 = ((swap_colL_2 >> 2) & 0x3333) | ((swap_colL_2 << 2) & 0xCCCC);
41
  swap_colL_2 = ((swap_colL_2 >> 1) & 0x5555) | ((swap_colL_2 << 1) & 0xAAAA);
42
  swap_colL_2 = (swap_colL_2 >> 3);
43
  swap_colL_2 &= 0x1F00;
44
45
  uint16_t colorL_swapped_1 = GPIO_ReadOutputData(GPIOB);
46
  uint16_t colorL_swapped_2 = GPIO_ReadOutputData(GPIOE);
47
  colorL_swapped_1 = swap_colL_1 | (colorL_swapped_1 & 0xFFF8);
48
  colorL_swapped_2 = swap_colL_2 | (colorL_swapped_2 & 0xE0FF);
49
50
  //--------------------------------------------------------------------------
51
  LCD_Cmd(COLUMN_ADDRESS);            // column address set
52
  LCD_Data(0x00);                     // start address
53
  LCD_Data(0x00);                     // is 0
54
  LCD_Data((LCD_WIDTH-1) >> 8);       // end address
55
  LCD_Data((LCD_WIDTH-1));            //
56
  //--------------------------------------------------------------------------
57
  LCD_Cmd(PAGE_ADDRESS);              // page address set
58
  LCD_Data(0x00);                     // start address
59
  LCD_Data(0x00);                     // is 0
60
  LCD_Data((LCD_HEIGHT-1) >> 8);      // end address
61
  LCD_Data((LCD_HEIGHT-1));           //
62
  //--------------------------------------------------------------------------
63
  LCD_Cmd(MEMORY_WRITE);              // write data command
64
  for(column=0; column<LCD_HEIGHT; column++)
65
  {
66
  for(page=0; page<LCD_WIDTH; page++)
67
  {
68
    GPIO_Write(GPIOB , colorH_swapped_1);    // Values from PB0 to PB2 (Display)
69
    GPIO_Write(GPIOE , colorH_swapped_2);    // Values from PE8 to PE12 (Display)
70
    GPIO_ResetBits(GPIOE , LCD_WRITE);    // Enable the Write mode
71
    GPIO_SetBits(GPIOE , LCD_WRITE);      // Disable the Write mode
72
73
    GPIO_Write(GPIOB , colorL_swapped_1);    // Values from PB0 to PB2 (Display)
74
    GPIO_Write(GPIOE , colorL_swapped_2);    // Values from PE8 to PE12 (Display)
75
    GPIO_ResetBits(GPIOE , LCD_WRITE);    // Enable the Write mode
76
    GPIO_SetBits(GPIOE , LCD_WRITE);      // Disable the Write mode
77
    }
78
  }
79
}

von Thomas F. (igel)


Lesenswert?

dasrotemopped schrieb:
> Erster Treffer bei Google :
>
> Code für Copy+Paste:
> 
http://stm32f4-discovery.net/2014/04/library-08-ili9341-lcd-on-stm32f429-discovery-board/

Und in diesem Fall unnütz da diese Lib SPI verwendet, der TO aber die 
Daten parallel überträgt.

von clincii (Gast)


Lesenswert?

Hätte noch eine Frage bezüglich der Umwandlung von JPEG in BMP,
die Kamera nimmt das Bild im JPEG-Format auf, das Display kann jedoch 
nur Bitmapdateien verarbeiten. Kann man das Format mit dem STM32F4 
softwaremässig ändern oder muss ich dafür das Bild auf den PC laden um 
es dann dort zu ändern.

Wenn man es softwaremässig ändern kann, was ich erwarte, wie genau wird 
das Format geändert? Gibts dafür eine fertige Funktion oder muss man 
selber eine Funktion schreiben?

Mfg

von Cyblord -. (cyblord)


Lesenswert?

clincii schrieb:
> Wenn man es softwaremässig ändern kann, was ich erwarte, wie genau wird
> das Format geändert? Gibts dafür eine fertige Funktion oder muss man
> selber eine Funktion schreiben?

Deinen Fragen nach zu Urteilen ist das Projekt drei Nummern zu groß für 
dich.

Such doch einfach mal nach Grafik Libs für den STM32F4.

Wenn aber die Umwandlung per PC eine Option ist, mach das.

Vor allem, mach doch mal bitte einen Schritt nach dem anderen. Wenn du 
dein BMP Bild erfolgreich auf dem Display hast, DANN kannst du dir doch 
überlegen wie du nun aus deinem JPEG ein BMP bastelst.

von clincii (Gast)


Lesenswert?

Cyblord -. schrieb:
> Deinen Fragen nach zu Urteilen ist das Projekt drei Nummern zu groß für
> dich.

Wie gesagt, es ist das Projekt der letztjährigen Lehrlinge welches ich 
nun beenden muss..

Cyblord -. schrieb:
> Wenn aber die Umwandlung per PC eine Option ist, mach das.

Leider ist dies keine mögliche Funktion im Endprodukt, ansonsten hätte 
ich dies so gemacht..

von Cyblord -. (cyblord)


Lesenswert?

clincii schrieb:
> Cyblord -. schrieb:
>> Deinen Fragen nach zu Urteilen ist das Projekt drei Nummern zu groß für
>> dich.
>
> Wie gesagt, es ist das Projekt der letztjährigen Lehrlinge welches ich
> nun beenden muss..

Ändert an der Tatsache ja nichts.

von clincii (Gast)


Lesenswert?

Cyblord -. schrieb:
> clincii schrieb:
>> Cyblord -. schrieb:
>>> Deinen Fragen nach zu Urteilen ist das Projekt drei Nummern zu groß für
>>> dich.
>>
>> Wie gesagt, es ist das Projekt der letztjährigen Lehrlinge welches ich
>> nun beenden muss..
>
> Ändert an der Tatsache ja nichts.

Klar, jedoch kann ich wohl schlecht meinem Chef sagen, dass ich es nicht 
machen werde weil es zu schwierig ist.. oder was denkst du?

von John D. (Gast)


Lesenswert?

clincii schrieb:
>
> Klar, jedoch kann ich wohl schlecht meinem Chef sagen, dass ich es nicht
> machen werde weil es zu schwierig ist.. oder was denkst du?

Wow, das ist gar kein Schul- oder Uni-Projekt? Dann liegt der Fehler 
nicht nur bei dir, sondern auch bei deinem Chef - offensichtlich schätzt 
er deine Fähigkeiten falsch ein. Bevor euch beiden das auf den Kopf 
fällt: Mach' ihm klar, was du kannst und was nicht!

von Cyblord -. (cyblord)


Lesenswert?

clincii schrieb:
> Klar, jedoch kann ich wohl schlecht meinem Chef sagen, dass ich es nicht
> machen werde weil es zu schwierig ist.. oder was denkst du?

Naja eine Aufgabe die 3 Nummern zu groß ist kann und sollte man so auch 
gegenüber dem Chef kommunizieren. Wenn mein Chef heute her kommt und 
verlangt dass ich bis nächste Woche ein Space Shuttle baue muss ich da 
leider auch passen.
Außerdem hören sich deine Ausführungen schon eher so an, als ob das 
ganze Fach nicht deines ist. Bist du denn Fachkraft in einem Bereich? 
Oder auch Lehrling?

von Thomas F. (igel)


Lesenswert?

clincii schrieb:
> meinem Chef sagen, dass ich es nicht machen werde weil es
> zu schwierig ist..

Das sagt man dann in Business-Speech: Das Projekt verzögert sich 
erheblich da die bisherige Software nur rudimentär funktioniert, du dich 
in dieses fremdes Projekt erst noch einarbeiten musst, wichtige 
Software-Komponenten noch fehlen und erst beschafft werden müssen was ja 
eigentlich eher die Aufgabe eines Softwerkers und gar nicht deine ist.

von clincii (Gast)


Lesenswert?

Cyblord -. schrieb:
> Außerdem hören sich deine Ausführungen schon eher so an, als ob das
> ganze Fach nicht deines ist. Bist du denn Fachkraft in einem Bereich?
> Oder auch Lehrling?

Bin noch in der Ausbildung..

Thomas F. schrieb:
> Das sagt man dann in Business-Speech: Das Projekt verzögert sich
> erheblich da die bisherige Software nur rudimentär funktioniert, du dich
> in dieses fremdes Projekt erst noch einarbeiten musst, wichtige
> Software-Komponenten noch fehlen und erst beschafft werden müssen was ja
> eigentlich eher die Aufgabe eines Softwerkers und gar nicht deine ist.

Eigentlich sollten ich dies mit dem Informatiklehrling zusammen beenden, 
wie es die letztjährigen Lehrlinge konnten. Jedoch gibt es dieses Jahr 
kein Informatiklehrling mehr. Dadurch muss ich diese Arbeit übernehmen.

von Draco (Gast)


Lesenswert?

clincii schrieb:
> Eigentlich sollten ich dies mit dem Informatiklehrling zusammen beenden,
> wie es die letztjährigen Lehrlinge konnten. Jedoch gibt es dieses Jahr
> kein Informatiklehrling mehr. Dadurch muss ich diese Arbeit übernehmen.

Gnihihi... Unsere Putzfrau macht nun auch die Arbeit unseres 
Projektmanagers weil er im Urlaub ist :-D

Tu dir selber einen gefallen! Wende dich mit diesem Problem an deinen 
Chef, sage das dies nicht in deinen Fähigkeitsbereich fällt, es sei 
denn, du bekommst jemanden zur Seite gestellt der dich darin einweisen / 
einlernen kann.

Wenn du es durchziehen willst, dann lerne dir die absoluten Grundlagen 
der µC Programmierung an. Es ist schade das dies Display schon 
initialisiert ist, denn normalerweise lernt man mit sowas umzugehen wenn 
man mit Null anfängt damit zu arbeiten. Da versteht man die Arbeitsweise 
des Displays erstmal. Du hast Glück, da gibt es sehr ausführliche Dokus 
zu deinem Display - lerne sie, verstehe sie, und mach einen Schritt nach 
dem anderen!

Nimm es mir nicht übel, du schaffst es nicht eine Routine zu schreiben 
um eine Linie oder Text auszugeben - musst du auch nicht - du bist ja 
kein Programmierer - aber greifst nach den Sternen und willst ein JPEG 
aufnehmen, umwandeln und ausgeben. Und das in einem bereits teilfertigen 
Produkt, wo man nicht mal selbst seine Struktur aufgebaut hat. Du kommst 
da auch nicht mit nem Copy'and'Paste weiter. Weil es ja doch etwas 
spezielleres ist.

Sprich mit deinem Cheff, frag ihn nach Hilfe - sollte er "komisch" 
werden, überlege ob es denn die Firma ist in der du Zukünftig arbeiten 
willst!

von proggen (Gast)


Lesenswert?

Musst du das Ganze in absehbarer Zeit fertig stellen oder ist das ein 
"mach das mal nebenher"-Projekt?

Bei ersterem mach was die anderen dir schon geraten haben und wende dich 
an deinen Chef und zeige ihm deine Situation auf. Du musst ihm ja nicht 
sagen das du es nicht kannst, sondern das du mehr Zeit zum einarbeiten 
und/oder ein wenig Hilfe von jemand mit Erfahrung brauchst.

Sollte eher letzteres der Fall sein und du ein wenig Interesse auf dem 
Gebiet hast was dazu zu lernen, dann sieh es als Einstieg in ein schönes 
Hobby :) Aber trotzdem würde ich an deiner Stelle dem Chef 
kommunizieren, dass du auf dem Gebiet noch unwissend bist.

Fang am besten an den vorhandenen Code zu verstehen und versuch erst 
danach selber was zu machen. Bekomm raus welche library deine Vorgänger 
benutzt haben und such nach Dokumentationen dazu bzw. schau nach wie die 
Sources der library kommentiert sind.

Ich bin jetzt mal davon ausgegangen, dass du bereits etwas Erfahrung 
beim Programmieren von µC hast...

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.