2025-03-31 1:19 AM - last edited on 2025-04-01 3:47 AM by Andrew Neil
Hello,
I am trying to connect an ILI9325C display to an STM32F401RET6 microcontroller. After writing the code correctly and connecting the display, it doesn't respond and only has the backlight on (from the power supply). I connected the STM32 to a logic analyzer and started an SPI analysis. I configured the CPHA and CPOL settings to match those of the STM32, but I keep getting the error: "The initial (idle) state of the CLK line does not match the settings." This error occurs during every test.
However, during one of the tests, I saw something start to display, some commands coming from MISO, but it was only once, and the display still didn't react.
I would appreciate any help since I have been working on this for a total of 20 hours.
Here are my attachments (comments in code are in polish):
1. Here is the link to my display: 3.2 inch 320x240 Touch LCD (C)
2. SPI configuration code:
/* USER CODE END SPI2_Init 1 */
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_1LINE;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
3. Here is the LCD code (lcd.c)
#include "lcd.h"
#include "spi.h"
#define ILI9325C_SLPOUT 0x11 // Sleep Out
#define ILI9325C_DISPOFF 0x28 // Display OFF
#define ILI9325C_DISPON 0x29 // Display ON
#define ILI9325C_CASET 0x2A // Column Address Set
#define ILI9325C_RASET 0x2B // Row Address Set
#define ILI9325C_RAMWR 0x2C // Memory Write
#define ILI9325C_MADCTL 0x36 // Memory Access Control
#define ILI9325C_COLMOD 0x3A // Color Mode
#define ILI9325C_FRMCTR1 0xB1 // Frame Rate Control 1
#define ILI9325C_FRMCTR2 0xB2 // Frame Rate Control 2
#define ILI9325C_FRMCTR3 0xB3 // Frame Rate Control 3
#define ILI9325C_INVCTR 0xB4 // Inversion Control
#define ILI9325C_PWCTR1 0xC0 // Power Control 1
#define ILI9325C_PWCTR2 0xC1 // Power Control 2
#define ILI9325C_PWCTR3 0xC2 // Power Control 3
#define ILI9325C_PWCTR4 0xC3 // Power Control 4
#define ILI9325C_PWCTR5 0xC4 // Power Control 5
#define ILI9325C_VMCTR1 0xC5 // VCOM Control 1
#define ILI9325C_GAMCTRP1 0xE0 // Gamma Control Positive
#define ILI9325C_GAMCTRN1 0xE1 // Gamma Control Negative
// Funkcja wysyłająca komendę do wyświetlacza
static void lcd_cmd(uint8_t cmd)
{
// Ustawienie pinów: DC = 0 (komenda), CS = 0 (włączamy komunikację SPI)
HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET); // DC = 0 (komenda)
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET); // CS = 0 (aktywny)
// Wysłanie komendy do wyświetlacza przez SPI
HAL_SPI_Transmit(&hspi2, &cmd, 1, HAL_MAX_DELAY);
// Zakończenie komunikacji SPI
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET); // CS = 1 (dezaktywujemy SPI)
HAL_Delay(10);
}
// Funkcja wysyłająca dane do wyświetlacza
static void lcd_data(uint8_t data)
{
// Ustawienie pinów: DC = 1 (dane), CS = 0 (włączamy komunikację SPI)
HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET); // DC = 1 (dane)
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET); // CS = 0 (aktywny)
// Wysłanie danych do wyświetlacza przez SPI
HAL_SPI_Transmit(&hspi2, &data, 1, HAL_MAX_DELAY);
// Zakończenie komunikacji SPI
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET); // CS = 1 (dezaktywujemy SPI)
}
// Funkcja wysyłająca albo komendę, albo dane, w zależności od flagi
#define CMD(x) ((x) | 0x100) // Flaga wskazująca, że to komenda
static void lcd_send(uint16_t value)
{
// Oczyść ewentualne flagi SPI przed wysyłaniem komendy lub danych
SPI_ClearFlags(&hspi2); // Wywołaj funkcję czyszczącą flagi SPI
if (value & 0x100) {
lcd_cmd(value); // Jeśli flaga jest ustawiona, wysyłamy komendę
} else {
lcd_data(value); // W przeciwnym razie wysyłamy dane
}
}
static const uint16_t init_table[] = {
CMD(ILI9325C_SLPOUT), 0x00, // Software reset
CMD(ILI9325C_DISPOFF), 0x00, // Display OFF
CMD(ILI9325C_CASET), 0x00, 0x00, 0x00, 0x7F, // Column address set
CMD(ILI9325C_RASET), 0x00, 0x00, 0x00, 0x9F, // Row address set
CMD(ILI9325C_RAMWR), 0x00, // Write to RAM
CMD(ILI9325C_MADCTL), 0x48, // Memory Access Control
CMD(ILI9325C_COLMOD), 0x55, // Color Mode (16-bit)
CMD(ILI9325C_PWCTR1), 0x23, 0x70, // Power Control 1
CMD(ILI9325C_PWCTR2), 0x10, 0x10, // Power Control 2
CMD(ILI9325C_GAMCTRP1), 0x00, 0x10, 0x0E, 0x04, 0x14, 0x20, 0x0E, 0x20, // Gamma curve positive
CMD(ILI9325C_GAMCTRN1), 0x00, 0x10, 0x0E, 0x04, 0x14, 0x20, 0x0E, 0x20, // Gamma curve negative
};
void lcd_init(void)
{
int i;
// Resetowanie wyświetlacza
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(500); // Krótkie opóźnienie
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
HAL_Delay(500); // Krótkie opóźnienie
// Wysyłanie komend inicjalizacyjnych z tablicy
for (i = 0; i < sizeof(init_table) / sizeof(uint16_t); i++) {
lcd_send(init_table[i]);
}
// Po wysłaniu komend inicjalizacyjnych włączamy wyświetlacz
HAL_Delay(500); // Dajemy trochę czasu na ustawienie
lcd_cmd(ILI9325C_SLPOUT); // Komenda Sleep Out dla ILI9325C
HAL_Delay(500); // Czas na wyjście ze stanu uśpienia
// Włączamy wyświetlacz
lcd_cmd(ILI9325C_DISPON); // Komenda Display ON dla ILI9325C
}
void lcd_fill_red(void)
{
uint16_t color = 0xf800; // Kolor czerwony w 16-bitowym formacie RGB565
uint32_t i;
// Ustawienie obszaru pamięci RAM wyświetlacza (adresowanie całego ekranu)
lcd_cmd(ILI9325C_CASET); // Ustawienie kolumny
lcd_data(0x00); // Początek kolumny
lcd_data(0x00); // Koniec kolumny
lcd_cmd(ILI9325C_RASET); // Ustawienie wiersza
lcd_data(0x00); // Początek wiersza
lcd_data(0x00); // Koniec wiersza
lcd_cmd(ILI9325C_RAMWR); // Rozpoczęcie zapisu do RAMu
// Zapisujemy kolor do całego ekranu
for (i = 0; i < 320 * 240; i++) { // Zakładając, że ekran ma 320x240 pikseli
lcd_data(color >> 8); // Wyższe 8 bitów
lcd_data(color & 0xFF); // Niższe 8 bitów
}
}
4. Main.c code:
/* USER CODE BEGIN WHILE */
HAL_Init();
MX_GPIO_Init();
MX_SPI2_Init();
/* Inicjalizacja LCD */
lcd_init();
HAL_Delay(1000);
/* Testowanie wyświetlacza: Wypełnienie całego ekranu kolorem czerwonym */
lcd_fill_red();
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
5. and i am also attaching photos from the analyzer:
Any advice or tips would be greatly appreciated!
Thank you in advance!
Solved! Go to Solution.
2025-04-01 3:26 AM
Well, I hate to tell you this, but your display is not SPI, but 16-bit parallel.
The SPI is used to read out the touchscreen data.
2025-04-01 3:26 AM
Well, I hate to tell you this, but your display is not SPI, but 16-bit parallel.
The SPI is used to read out the touchscreen data.
2025-04-01 3:46 AM
@RobK1 wrote:your display is not SPI, but 16-bit parallel.
Indeed:
@kiwiosek2007 the datasheet is available from the page you linked:
https://files.waveshare.com/upload/6/65/3.2inch-320x240-Touch-LCD-C-UserManual.pdf
See also the schematics linked from that page.
There is also code:
2025-04-01 4:03 AM
Litterally I have to missed that. Thanks for the hint. @RobK1 @Andrew Neil