Сейчас вожусь с таким дисплеем:
https://www.ozon.ru/product/3-5-dyuymovyy-tft-zhk-ekran-spi-serial-lcd-module-480x320-driver-ic-ili9488-podderzhka-emkostnogo-1949028523/
На самом изделии тип контроллера не указан, но продавец утверждает, что это ILI9488.
В рабочий режим его вогнать можно, т.е. последовательность команд инициализации для ILI9488 приводит этот дисплей в чувство.
Но!
По дэйташиту дисплей должен поддерживать следующие режимы:
- 24-разрядная глубина цвета, 16 млн. цветов.
- 18-разрядная глубина цвета, 262 тыс. цветов.
- 16-разрядная глубина цвета, 65 тыс. цветов.
- 3-разрядная глубина цвета, 8 цветов.
24-разрядный режим я не пробовал, поддерживаются 18-разрядный и 3-разрядный, а в режим 64к цветов мне его вогнать не удалось.
Исходник - ниже, написан для Blue Pill, т.к. приемлемую скорость работы с таким количеством точек на AVR получить невозможно.
В строках 4-7 устанавливается режим работы. Две из трех этих строк должны быть закомментированы.
Подключение описано в строках 8-13.
Убрал из исходника все лишнее, оставил только заливку экрана: белым, красным, зеленым, синим и черным цветами.
В функции Lcd_Init много строк закомментировано. Если их все или поблочно раскомментировать, визуальных изменений не происходит. Если заменить данные команд на то, что указано в комментариях к соответствующей строке - тоже.
Время заливки экрана на максимальной скорости SPI в режиме 24 разрядов составляет почти 0.6 с. При максимально оптимизированном soft-SPI - примерно столько же.
Хотелось все-таки перевести дисплей в 16-разрядный режим, чтобы уменьшить это время в полтора раза.
Можно, конечно, установить и 8-цветный режим, у него заливка составляет менее 0.1 с. Но с одной стороны, 8 цветов - это отнюдь не предел мечтаний, а с другой - в одном байте содержится 2 пикселя, что очень неудобно для пиксельной графики.
// ILI9488 + stm32f103 (BluePill)
#include <SPI.h>
//#define COLORS_8 // режим 3-разрядного цвета (два пикселя на байт, 8 цветов)
//#define COLORS_64K // режим 16-разрядного цвета (2 байта на пиксель, 65536 цветов)
#define COLORS_262K // режим 18-разрядного цвета (3 байта на пиксель, 262144 цвета)
#define CS PB11 // yellow
#define RESET PB10 // green
#define RS PB1 // blue
#define MOSI PA7 // grey
#define SCK PA5 // black
#define LED_L PB7 // orange
#define LED_B PC13 // blink
#ifdef COLORS_262K // блок задания констант для 18-разрядного цвета (3 байта на пиксель)
#define WHITE 0xFFFFFF
#define RED 0xFF0000
#define GREEN 0x00FF00
#define BLUE 0x0000FF
#define BLACK 0
#define SIZE (480*320)
#define DATA3A 0x66
#else
#ifdef COLORS_64K // блок задания констант для 16-разрядного цвета (2 байта на пиксель)
#define WHITE 0xFFFF
#define RED 0xF800
#define GREEN 0x07E0
#define BLUE 0x001F
#define BLACK 0
#define SIZE (480*320)
#define DATA3A 0x55
#else
#ifdef COLORS_8 // блок задания констант для 3-разрядного цвета (два пикселя на байт)
#define WHITE 0x3F
#define RED 0x24
#define GREEN 0x12
#define BLUE 0x09
#define BLACK 0
#define SIZE (480*320/2)
#define DATA3A 0x11
#endif // COLORS_8
#endif // COLORS_64K
#endif // COLORS_262K конец блока задания констант
void Lcd_Write_Bus(unsigned char d)
{
SPI.transfer(d);
}
void Lcd_Write_Com(unsigned char c)
{
GPIOB_BASE->BRR = 0x0002; // пин PB1 : RS - LOW
Lcd_Write_Bus(c);
GPIOB_BASE->BSRR = 0x0002; // пин PB1 : RS - HIGH
}
inline void Lcd_Write_Data(unsigned char d)
{
Lcd_Write_Bus(d);
}
/*void Lcd_Write_Com_Data(unsigned char c,unsigned char d)
{
Lcd_Write_Com(c);
Lcd_Write_Data(d);
}*/
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
Lcd_Write_Com(0x2a);
Lcd_Write_Data(x1>>8);
Lcd_Write_Data(x1);
Lcd_Write_Data(x2>>8);
Lcd_Write_Data(x2);
Lcd_Write_Com(0x2b);
Lcd_Write_Data(y1>>8);
Lcd_Write_Data(y1);
Lcd_Write_Data(y2>>8);
Lcd_Write_Data(y2);
Lcd_Write_Com(0x2c);
}
void Lcd_Init(void)
{
digitalWrite(RESET,HIGH);
delay(5);
digitalWrite(RESET,LOW);
delay(15);
digitalWrite(RESET,HIGH);
delay(15);
digitalWrite(CS,LOW); //CS
Lcd_Write_Com(0x28); // display off
delay(20);
Lcd_Write_Com(0x3A); // interface pixel format
Lcd_Write_Data(DATA3A); // (0x66);
Lcd_Write_Com(0xF7); // adjust control 3
Lcd_Write_Data(0xA9);
Lcd_Write_Data(0x51);
Lcd_Write_Data(0x2C);
Lcd_Write_Data(0x82);
Lcd_Write_Com(0xC0); // power control 1
Lcd_Write_Data(0x10); // 0x11
Lcd_Write_Data(0x10); // 0x09
Lcd_Write_Com(0xC1); // power control 2
Lcd_Write_Data(0x41);
Lcd_Write_Com(0xC5); // VCOM control
Lcd_Write_Data(0x00);
Lcd_Write_Data(0x22); // 0x0A
Lcd_Write_Data(0x80);
Lcd_Write_Data(0x40); // этого не было
Lcd_Write_Com(0xB0); //
Lcd_Write_Data(0x00);
Lcd_Write_Com(0xB1); // frame rate control (in normal mode/full colors)
Lcd_Write_Data(0xB0);
Lcd_Write_Data(0x11);
Lcd_Write_Com(0xB4); // Display invertion contrjl
Lcd_Write_Data(0x02);
Lcd_Write_Com(0xB6); // display function control
Lcd_Write_Data(0x02);
Lcd_Write_Data(0x02); // 0x22
Lcd_Write_Data(0x3B); // этого не было
Lcd_Write_Com(0xB7); // entry mode set
Lcd_Write_Data(0xC6);
// Lcd_Write_Com(0xBE); // HS Lanes control
// Lcd_Write_Data(0x00);
// Lcd_Write_Data(0x04);
// Lcd_Write_Com(0xE9); // set image function
// Lcd_Write_Data(0x00);
Lcd_Write_Com(0x36); // memory access control
Lcd_Write_Data(0x08); // 0x08 - ориентация дисплея
/*
Lcd_Write_Com(0xE0); // positive gamma control
Lcd_Write_Data(0x00);
Lcd_Write_Data(0x07);
Lcd_Write_Data(0x10);
Lcd_Write_Data(0x09);
Lcd_Write_Data(0x17);
Lcd_Write_Data(0x0B);
Lcd_Write_Data(0x41);
Lcd_Write_Data(0x89);
Lcd_Write_Data(0x4B);
Lcd_Write_Data(0x0A);
Lcd_Write_Data(0x0C);
Lcd_Write_Data(0x0E);
Lcd_Write_Data(0x18);
Lcd_Write_Data(0x1B);
Lcd_Write_Data(0x0F);
Lcd_Write_Com(0xE1); // negative gamma control
Lcd_Write_Data(0x00);
Lcd_Write_Data(0x17);
Lcd_Write_Data(0x1A);
Lcd_Write_Data(0x04);
Lcd_Write_Data(0x0E);
Lcd_Write_Data(0x06);
Lcd_Write_Data(0x2F);
Lcd_Write_Data(0x45);
Lcd_Write_Data(0x43);
Lcd_Write_Data(0x02);
Lcd_Write_Data(0x0A);
Lcd_Write_Data(0x09);
Lcd_Write_Data(0x32);
Lcd_Write_Data(0x36);
Lcd_Write_Data(0x0F);
*/
Lcd_Write_Com(0x11); //Exit Sleep
delay(120);
Lcd_Write_Com(0x29); //Display on
digitalWrite(CS,HIGH);
}
void LCD_Clear(unsigned int c)
{
digitalWrite(CS,LOW);
Address_set(0,0,320,480);
for(unsigned int i = 0; i< SIZE; i++)
{
#ifdef COLORS_262K
Lcd_Write_Data((c >> 16) & 0xFF);
Lcd_Write_Data((c >> 8) & 0xFF);
Lcd_Write_Data((c) & 0xFF);
#else
#ifdef COLORS_64K
Lcd_Write_Data((c >> 8) & 0xFF);
Lcd_Write_Data((c) & 0xFF);
#else
#ifdef COLORS_8
Lcd_Write_Data((c) & 0x3F);
#endif
#endif
#endif
}
delay(300); // что можно было рассмотреть в 8-цветном режиме
digitalWrite(CS,HIGH);
}
void setup()
{
Serial.begin(115200);
Serial.print("Start");
Serial.print(" Phase 1 (PA7)");
pinMode(LED_L,OUTPUT);
pinMode(RS,OUTPUT);
pinMode(RESET,OUTPUT);
pinMode(CS,OUTPUT);
pinMode(MOSI,OUTPUT);
pinMode(SCK,OUTPUT);
pinMode(LED_B,OUTPUT);
// digitalWrite(LED_L, HIGH);
digitalWrite(RS, HIGH);
digitalWrite(RESET, HIGH);
digitalWrite(CS, HIGH);
digitalWrite(MOSI, HIGH);
digitalWrite(SCK, HIGH);
digitalWrite(LED_B, LOW);
delay(100);
digitalWrite(LED_B, HIGH);
delay(100);
digitalWrite(LED_B, LOW);
delay(100);
digitalWrite(LED_B, HIGH);
delay(100);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV2); // 4 MHz (half speed)
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
Serial.println("Before Init");
Lcd_Init();
Serial.print("After Init * ");
Serial.println(DATA3A);
}
void loop() {
LCD_Clear(WHITE);
digitalWrite(LED_B, LOW);
unsigned long t3 = millis();
LCD_Clear(RED);
unsigned long t4 = millis();
Serial.print("Draw ");
Serial.print(t4-t3-300);
Serial.print(" ms, ");
Serial.print((320*480)/(t4-t3-300));
Serial.print(" in 1 ms (");
Serial.print((DATA3A >> 4) & 0x0F);
Serial.print(DATA3A & 0x0F);
Serial.println(")");
digitalWrite(LED_B, HIGH);
LCD_Clear(GREEN);
digitalWrite(LED_B, LOW);
LCD_Clear(BLUE);
digitalWrite(LED_B, HIGH);
LCD_Clear(BLACK);
digitalWrite(LED_B, LOW);
digitalWrite(LED_B, HIGH);
}




