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
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 :)
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 !
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.
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
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.
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.
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
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.
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 | } |
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.
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.
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 | }
|
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.
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
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.
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..
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.
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?
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!
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?
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.
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.
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!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.