cancel
Showing results for 
Search instead for 
Did you mean: 

16-bit parallel - ILI9325C Display and STM32F401RET6

kiwiosek2007
Associate II

Hello,

I am trying to connect an ILI9325C display to an STM32F401RET6 microcontroller Yes this is related to my previous post. After writing the code correctly and connecting the display, it doesn't respond and only has the backlight on (from the power supply). I think my code is correct I compare it to the documentation of my display. Any advice appreciate it.

Display: https://www.waveshare.com/wiki/3.2inch_320x240_Touch_LCD_(C)

My code LCD.C for 16bit-Parrarel

#include "stm32f4xx_hal.h" #include "stm32f4xx_hal_spi.h" #include "lcd.h" SPI_HandleTypeDef hspi1; // SPI do dotyku // Ustawienie danych na pinach D0–D15 void LCD_SetDataPins(uint16_t data) { // Maska: PB0–PB10, PB12–PB15 (bez PB11 = D11, bo ten jest na PA11) uint16_t mask = 0b1111011111111111; // 0xF7FF // Najpierw wyczyść i ustaw dane na GPIOB GPIOB->ODR = (GPIOB->ODR & ~mask) | (data & mask); // Osobno ustaw PA11 (D11) if (data & (1 << 11)) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET); } } // Wysłanie komendy do LCD void LCD_WriteCommand(uint16_t cmd) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET); // RS = 0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); // CS = 0 LCD_SetDataPins(cmd); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); // WR = 0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); // WR = 1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); // CS = 1 } // Wysłanie danych do LCD void LCD_WriteData(uint16_t data) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET); // RS = 1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); // CS = 0 LCD_SetDataPins(data); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); // WR = 0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); // WR = 1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); // CS = 1 } // Inicjalizacja wyświetlacza LCD void LCD_Init(void) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET); // RST = 0 HAL_Delay(50); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET); // RST = 1 HAL_Delay(10); LCD_WriteCommand(0x01); // Soft Reset HAL_Delay(10); LCD_WriteCommand(0x28); // Display OFF HAL_Delay(10); LCD_WriteCommand(0xCF); // Power control LCD_WriteData(0x00); LCD_WriteData(0xC1); LCD_WriteData(0x30); } // Inicjalizacja SPI1 (dla dotyku) void SPI_Init(void) { hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; HAL_SPI_Init(&hspi1); } // Odczyt danych z kontrolera dotyku uint16_t Touch_ReadData(uint8_t cmd) { uint16_t result = 0; uint8_t recv[2] = {0}; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); // TP_CS = 0 HAL_SPI_Transmit(&hspi1, &cmd, 1, 1000); HAL_SPI_Receive(&hspi1, recv, 2, 1000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); // TP_CS = 1 result = ((recv[0] << | recv[1]) >> 4; return result; } // Wypełnianie całego ekranu kolorem void LCD_FillScreen(uint16_t color) { uint32_t i; LCD_WriteCommand(0x2A); // Column address set LCD_WriteData(0x00); LCD_WriteData(0x00); LCD_WriteData(0x00); LCD_WriteData(0xEF); // 240 columns LCD_WriteCommand(0x2B); // Page address set LCD_WriteData(0x00); LCD_WriteData(0x00); LCD_WriteData(0x01); LCD_WriteData(0x3F); // 320 rows LCD_WriteCommand(0x2C); // Memory write for (i = 0; i < 320 * 240; i++) { LCD_WriteData(color >> 8); // High byte LCD_WriteData(color & 0xFF); // Low byte } }
View more

3. And my pin connection:

display  -- stm
5v-in -- 5v
gnd -- gnd
d0 -- pb0
d1 -- pb1
d2 -- pb2
d3 -- pb3
d4 -- pb4
d5 -- pb5
d6 -- pb6
d7 -- pb7
d8 -- pb8
d9 -- pb9
d10 -- pb10
d11 -- pa11
d12 -- pb12
d13 -- pb13
d14 -- pb14
d15 -- pb15
lcd-cs -- pc0
rs -- pc1
wr -- pc2
rd -- vdd
rst -- pc3
bl-vcc -- 3v
gnd -- gnd
bl-ctrl -- pa5
tp-irq -- pa9
tp-cs -- pa8
tp-sck -- pc10
tp-sdi -- pc12
tp-sdo -- pc11

Thank you in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
kiwiosek2007
Associate II

I have made it. Yes that was code issue.
I have wrote code I think that the previous one what I wrote was for ILI9341 what has diffrent commands, but after a long time of debuging and looking for mistakes I have done it and the display is correctly initializating and showing colors.
Here is my code maybe someone will need it, 

#include "stm32f4xx_hal.h" #include "stm32f4xx_hal_spi.h" #include "lcd.h" extern SPI_HandleTypeDef hspi3; // Ustawienie danych na pinach D0–D15 void LCD_SetDataPins(uint16_t data) { uint16_t mask = 0b1111011111111111; // PB0–PB10, PB12–PB15 GPIOB->ODR = (GPIOB->ODR & ~mask) | (data & mask); // PA11 = D11 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, (data & (1 << 11)) ? GPIO_PIN_SET : GPIO_PIN_RESET); } // Wysyłanie komend i danych void LCD_WriteCommand(uint16_t cmd) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET); // RS=0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); // CS=0 LCD_SetDataPins(cmd); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); // WR=0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); // WR=1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); // CS=1 } void LCD_WriteData(uint16_t data) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET); // RS=1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); // CS=0 LCD_SetDataPins(data); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); // WR=0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); // WR=1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); // CS=1 } // Ustawienie kursora (GRAM address) void LCD_SetCursor(uint16_t x, uint16_t y) { LCD_WriteCommand(0x20); LCD_WriteData(x); // kolumna LCD_WriteCommand(0x21); LCD_WriteData(y); // wiersz LCD_WriteCommand(0x22); // RAM write } // Wpis danych do pamięci GRAM (jeden piksel) void LCD_WriteRAM(uint16_t color) { LCD_WriteData(color); } // Reset i inicjalizacja void LCD_Init(void) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET); // RST = 0 HAL_Delay(150); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET); // RST = 1 HAL_Delay(150); // Inicjalizacja ILI9325 — wybrane rejestry (skrót wersji) LCD_WriteCommand(0x00E5); LCD_WriteData(0x78F0); LCD_WriteCommand(0x0001); LCD_WriteData(0x0100); LCD_WriteCommand(0x0002); LCD_WriteData(0x0700); LCD_WriteCommand(0x0003); LCD_WriteData(0x1030); // BGR=1, Scan direction LCD_WriteCommand(0x0004); LCD_WriteData(0x0000); LCD_WriteCommand(0x0008); LCD_WriteData(0x0202); LCD_WriteCommand(0x0009); LCD_WriteData(0x0000); LCD_WriteCommand(0x000A); LCD_WriteData(0x0000); LCD_WriteCommand(0x000C); LCD_WriteData(0x0000); LCD_WriteCommand(0x000D); LCD_WriteData(0x0000); LCD_WriteCommand(0x000F); LCD_WriteData(0x0000); // Power On LCD_WriteCommand(0x0010); LCD_WriteData(0x0000); LCD_WriteCommand(0x0011); LCD_WriteData(0x0007); LCD_WriteCommand(0x0012); LCD_WriteData(0x0000); LCD_WriteCommand(0x0013); LCD_WriteData(0x0000); HAL_Delay(200); LCD_WriteCommand(0x0010); LCD_WriteData(0x17B0); LCD_WriteCommand(0x0011); LCD_WriteData(0x0037); HAL_Delay(50); LCD_WriteCommand(0x0012); LCD_WriteData(0x0138); HAL_Delay(50); LCD_WriteCommand(0x0013); LCD_WriteData(0x1700); LCD_WriteCommand(0x0029); LCD_WriteData(0x000D); HAL_Delay(50); // Gamma LCD_WriteCommand(0x0030); LCD_WriteData(0x0001); LCD_WriteCommand(0x0031); LCD_WriteData(0x0606); LCD_WriteCommand(0x0032); LCD_WriteData(0x0003); LCD_WriteCommand(0x0035); LCD_WriteData(0x0206); LCD_WriteCommand(0x0036); LCD_WriteData(0x0008); LCD_WriteCommand(0x0037); LCD_WriteData(0x0504); LCD_WriteCommand(0x0038); LCD_WriteData(0x0007); LCD_WriteCommand(0x0039); LCD_WriteData(0x0000); LCD_WriteCommand(0x003C); LCD_WriteData(0x0007); LCD_WriteCommand(0x003D); LCD_WriteData(0x0000); // Window LCD_WriteCommand(0x0050); LCD_WriteData(0x0000); LCD_WriteCommand(0x0051); LCD_WriteData(0x00EF); LCD_WriteCommand(0x0052); LCD_WriteData(0x0000); LCD_WriteCommand(0x0053); LCD_WriteData(0x013F); LCD_WriteCommand(0x0060); LCD_WriteData(0xA700); LCD_WriteCommand(0x0061); LCD_WriteData(0x0001); LCD_WriteCommand(0x006A); LCD_WriteData(0x0000); // Display ON LCD_WriteCommand(0x0007); LCD_WriteData(0x0133); HAL_Delay(50); } // Wypełnienie całego ekranu kolorem void LCD_FillScreen(uint16_t color) { LCD_SetCursor(0, 0); uint32_t i; for (i = 0; i < 320 * 240; i++) { LCD_WriteRAM(color); } }
View more

Thanks to @Ozone @Andrew Neil for advices and trying to help.

View solution in original post

6 REPLIES 6

@kiwiosek2007 wrote:

Yes this is related to my previous post.


You mean this:

https://community.st.com/t5/others-stm32-mcus-related/problem-with-ili9325c-display-and-stm32f401ret6/td-p/788495

 


@kiwiosek2007 wrote:

I think my code is correct I compare it to the documentation of my display.


What about when you look at the actual interface lines; eg, with a logic analyser?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Yes and I have changed the spi to the 16bit-parrarel. 
I don't have right now the analyzer. When I'll get back I'll test it, but also my anaylzer don't have so much channels to get all pins to checked.
When i was in debug my display doesn't response the connection in neither way. I thought that is problem with my code. 


@kiwiosek2007 wrote:

my anaylzer don't have so much channels to get all pins to checked. 


At least start by looking at a selection of lines - the control lines and as many data lines as you can.

 


@kiwiosek2007 wrote:

I thought that is problem with my code. 


A logic analyser will be the easiest way to see what your code is actually doing.

Knowing what it's actually doing, you can then compare that to what it should be doing.

That should lead you to the part(s) of your code that are not working correctly.

It may, of course, show that you (also) have hardware problem(s)...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

What you at least should do is to check all connections statically for correctness.
By that I mean e.g. with an ohmmeter. All the data connections and especially the control signals.

For a logic analyzer, you don't need to spend a fortune. I'm using the sigrok tool (under Linux), which supports the  rather cheap 8-channel Salae Logic clones you get for a few bucks.
Her a link to the software, which AFAIK also supports Windows : https://sigrok.org/wiki/Main_Page

And I think it's understood you need the ILI9325C datasheet, to check for a proper signal sequence, timing and levels.

kiwiosek2007
Associate II

I have made it. Yes that was code issue.
I have wrote code I think that the previous one what I wrote was for ILI9341 what has diffrent commands, but after a long time of debuging and looking for mistakes I have done it and the display is correctly initializating and showing colors.
Here is my code maybe someone will need it, 

#include "stm32f4xx_hal.h" #include "stm32f4xx_hal_spi.h" #include "lcd.h" extern SPI_HandleTypeDef hspi3; // Ustawienie danych na pinach D0–D15 void LCD_SetDataPins(uint16_t data) { uint16_t mask = 0b1111011111111111; // PB0–PB10, PB12–PB15 GPIOB->ODR = (GPIOB->ODR & ~mask) | (data & mask); // PA11 = D11 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, (data & (1 << 11)) ? GPIO_PIN_SET : GPIO_PIN_RESET); } // Wysyłanie komend i danych void LCD_WriteCommand(uint16_t cmd) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET); // RS=0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); // CS=0 LCD_SetDataPins(cmd); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); // WR=0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); // WR=1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); // CS=1 } void LCD_WriteData(uint16_t data) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET); // RS=1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); // CS=0 LCD_SetDataPins(data); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); // WR=0 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); // WR=1 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); // CS=1 } // Ustawienie kursora (GRAM address) void LCD_SetCursor(uint16_t x, uint16_t y) { LCD_WriteCommand(0x20); LCD_WriteData(x); // kolumna LCD_WriteCommand(0x21); LCD_WriteData(y); // wiersz LCD_WriteCommand(0x22); // RAM write } // Wpis danych do pamięci GRAM (jeden piksel) void LCD_WriteRAM(uint16_t color) { LCD_WriteData(color); } // Reset i inicjalizacja void LCD_Init(void) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET); // RST = 0 HAL_Delay(150); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET); // RST = 1 HAL_Delay(150); // Inicjalizacja ILI9325 — wybrane rejestry (skrót wersji) LCD_WriteCommand(0x00E5); LCD_WriteData(0x78F0); LCD_WriteCommand(0x0001); LCD_WriteData(0x0100); LCD_WriteCommand(0x0002); LCD_WriteData(0x0700); LCD_WriteCommand(0x0003); LCD_WriteData(0x1030); // BGR=1, Scan direction LCD_WriteCommand(0x0004); LCD_WriteData(0x0000); LCD_WriteCommand(0x0008); LCD_WriteData(0x0202); LCD_WriteCommand(0x0009); LCD_WriteData(0x0000); LCD_WriteCommand(0x000A); LCD_WriteData(0x0000); LCD_WriteCommand(0x000C); LCD_WriteData(0x0000); LCD_WriteCommand(0x000D); LCD_WriteData(0x0000); LCD_WriteCommand(0x000F); LCD_WriteData(0x0000); // Power On LCD_WriteCommand(0x0010); LCD_WriteData(0x0000); LCD_WriteCommand(0x0011); LCD_WriteData(0x0007); LCD_WriteCommand(0x0012); LCD_WriteData(0x0000); LCD_WriteCommand(0x0013); LCD_WriteData(0x0000); HAL_Delay(200); LCD_WriteCommand(0x0010); LCD_WriteData(0x17B0); LCD_WriteCommand(0x0011); LCD_WriteData(0x0037); HAL_Delay(50); LCD_WriteCommand(0x0012); LCD_WriteData(0x0138); HAL_Delay(50); LCD_WriteCommand(0x0013); LCD_WriteData(0x1700); LCD_WriteCommand(0x0029); LCD_WriteData(0x000D); HAL_Delay(50); // Gamma LCD_WriteCommand(0x0030); LCD_WriteData(0x0001); LCD_WriteCommand(0x0031); LCD_WriteData(0x0606); LCD_WriteCommand(0x0032); LCD_WriteData(0x0003); LCD_WriteCommand(0x0035); LCD_WriteData(0x0206); LCD_WriteCommand(0x0036); LCD_WriteData(0x0008); LCD_WriteCommand(0x0037); LCD_WriteData(0x0504); LCD_WriteCommand(0x0038); LCD_WriteData(0x0007); LCD_WriteCommand(0x0039); LCD_WriteData(0x0000); LCD_WriteCommand(0x003C); LCD_WriteData(0x0007); LCD_WriteCommand(0x003D); LCD_WriteData(0x0000); // Window LCD_WriteCommand(0x0050); LCD_WriteData(0x0000); LCD_WriteCommand(0x0051); LCD_WriteData(0x00EF); LCD_WriteCommand(0x0052); LCD_WriteData(0x0000); LCD_WriteCommand(0x0053); LCD_WriteData(0x013F); LCD_WriteCommand(0x0060); LCD_WriteData(0xA700); LCD_WriteCommand(0x0061); LCD_WriteData(0x0001); LCD_WriteCommand(0x006A); LCD_WriteData(0x0000); // Display ON LCD_WriteCommand(0x0007); LCD_WriteData(0x0133); HAL_Delay(50); } // Wypełnienie całego ekranu kolorem void LCD_FillScreen(uint16_t color) { LCD_SetCursor(0, 0); uint32_t i; for (i = 0; i < 320 * 240; i++) { LCD_WriteRAM(color); } }
View more

Thanks to @Ozone @Andrew Neil for advices and trying to help.

I had done the same thing about 10 years ago, although for another MCU.
And also without scope or logic analyser.

A bit of persistence and a proper incremental approach are helpful...