#define Software_Reset 0x01 #define Power_Control_A 0xCB #define Power_Control_B 0xCF #define Driver_Timing_Control_A 0xE8 #define Driver_Timing_Control_B 0xEA #define Power_On_Sequence_Control 0xED #define Pump_Ratio_Control 0xF7 #define Power_Control_1 0xC0 #define Power_Control_2 0xC1 #define VCOM_Control_1 0xC5 #define VCOM_Control_2 0xC7 #define Memory_Access_Control 0x36 #define Pixel_Format_Set 0x3A #define Frame_Rate_Control 0xB1 #define Display_Function_Control 0xB6 #define Enable_3G 0xF2 #define Column_Address_Set 0x2A #define Page_Address_Set 0x2B #define Gamma_Set 0x26 #define Positive_Gamma_Correction 0xE0 #define Negative_Gamma_Correction 0xE1 #define Sleep_Out 0x11 #define Display_ON 0x29 #define Memory_Write 0x2C #define TFT_DC_SET() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); #define TFT_DC_RESET() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); #define TFT_RST_SET() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); #define TFT_RST_RESET() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); #define TFT_CS_SET() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); #define TFT_CS_RESET() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); void TFT_SendCommand(uint8_t command) { TFT_DC_RESET(); TFT_CS_RESET(); HAL_SPI_Transmit(&hspi2, &command,1,1000); TFT_CS_SET(); } void TFT_SendData(uint8_t data) { TFT_DC_SET(); TFT_CS_RESET(); HAL_SPI_Transmit(&hspi2, &data,1,1000); TFT_CS_SET(); } void TFT_SetCursorPosition(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { TFT_SendCommand(Column_Address_Set); TFT_SendData(x1 >> 8); TFT_SendData(x1 & 0xFF); TFT_SendData(x2 >> 8); TFT_SendData(x2 & 0xFF); TFT_SendCommand(Page_Address_Set); TFT_SendData(y1 >> 8); TFT_SendData(y1 & 0xFF); TFT_SendData(y2 >> 8); TFT_SendData(y2 & 0xFF); } void TFT_Init() { TFT_CS_RESET(); TFT_RST_RESET(); HAL_Delay(10); TFT_RST_SET(); TFT_SendCommand(Software_Reset); HAL_Delay(1000); TFT_SendCommand(Power_Control_A); TFT_SendData(0x39); TFT_SendData(0x2C); TFT_SendData(0x00); TFT_SendData(0x34); TFT_SendData(0x02); TFT_SendCommand(Power_Control_B); TFT_SendData(0x00); TFT_SendData(0xC1); TFT_SendData(0x30); TFT_SendCommand(Driver_Timing_Control_A); TFT_SendData(0x85); TFT_SendData(0x00); TFT_SendData(0x78); TFT_SendCommand(Driver_Timing_Control_B); TFT_SendData(0x00); TFT_SendData(0x00); TFT_SendCommand(Power_On_Sequence_Control); TFT_SendData(0x64); TFT_SendData(0x03); TFT_SendData(0x12); TFT_SendData(0x81); TFT_SendCommand(Pump_Ratio_Control); TFT_SendData(0x20); TFT_SendCommand(Power_Control_1); TFT_SendData(0x23); TFT_SendCommand(Power_Control_2); TFT_SendData(0x10); TFT_SendCommand(VCOM_Control_1); TFT_SendData(0x3E); TFT_SendData(0x28); TFT_SendCommand(VCOM_Control_2); TFT_SendData(0x86); TFT_SendCommand(Memory_Access_Control); TFT_SendData(0x48); TFT_SendCommand(Pixel_Format_Set); TFT_SendData(0x55); TFT_SendCommand(Frame_Rate_Control); TFT_SendData(0x00); TFT_SendData(0x18); TFT_SendCommand(Display_Function_Control); TFT_SendData(0x08); TFT_SendData(0x82); TFT_SendData(0x27); TFT_SendCommand(Enable_3G); TFT_SendData(0x00); TFT_SendCommand(Column_Address_Set); TFT_SendData(0x00); TFT_SendData(0x00); TFT_SendData(0x00); TFT_SendData(0xEF); TFT_SendCommand(Page_Address_Set); TFT_SendData(0x00); TFT_SendData(0x00); TFT_SendData(0x01); TFT_SendData(0x3F); TFT_SendCommand(Gamma_Set); TFT_SendData(0x01); TFT_SendCommand(Positive_Gamma_Correction); TFT_SendData(0x0F); TFT_SendData(0x31); TFT_SendData(0x2B); TFT_SendData(0x0C); TFT_SendData(0x0E); TFT_SendData(0x08); TFT_SendData(0x4E); TFT_SendData(0xF1); TFT_SendData(0x37); TFT_SendData(0x07); TFT_SendData(0x10); TFT_SendData(0x03); TFT_SendData(0x0E); TFT_SendData(0x09); TFT_SendData(0x00); TFT_SendCommand(Negative_Gamma_Correction); TFT_SendData(0x00); TFT_SendData(0x0E); TFT_SendData(0x14); TFT_SendData(0x03); TFT_SendData(0x11); TFT_SendData(0x07); TFT_SendData(0x31); TFT_SendData(0xC1); TFT_SendData(0x48); TFT_SendData(0x08); TFT_SendData(0x0F); TFT_SendData(0x0C); TFT_SendData(0x31); TFT_SendData(0x36); TFT_SendData(0x0F); TFT_SendCommand(Sleep_Out); HAL_Delay(100); TFT_SendCommand(Display_ON); HAL_Delay(100); //--------------------------- TFT_SendCommand(0x36); TFT_SendData(72); TFT_SendCommand(Memory_Write); } int main() { TFT_Init(); TFT_SetCursorPosition(0,0,239,319); TFT_SendCommand(Memory_Write); //Memory_Write for(int i=0; i<(239*319); i++) { TFT_SendData(0xbb); TFT_SendData(0xbb); } }
Совершенно не понимаю зачем в инициализации выставляется адрес курсора:
TFT_SendCommand(Column_Address_Set); TFT_SendData(0x00); TFT_SendData(0x00); TFT_SendData(0x00); TFT_SendData(0xEF); TFT_SendCommand(Page_Address_Set); TFT_SendData(0x00); TFT_SendData(0x00); TFT_SendData(0x01); TFT_SendData(0x3F);
Действие никакое не производится с этими данными курсора.
Если этот код убрать, то ничего не изменится.
Это тоже какая то ерунда
TFT_SendCommand(0x36); TFT_SendData(0x48); TFT_SendCommand(Memory_Write);
Не нужно при инициализации.
TFT_SendCommand(0x36); вообще повторение Memory Access Control.
TFT_CS_RESET(); в самом начале TFT_Init тоже не нужен.
Все действия с чип селектом находятся в функциях, например в TFT_SendCommand.
В начале надо просто сбросить дисплей
Сначала аппаратный резет
TFT_RST_RESET(); HAL_Delay(10); TFT_RST_SET();
Потом программный резет.
TFT_SendCommand(Software_Reset); HAL_Delay(1000);
Или надо сначала выбрать чип CS, чтоб на нём сделать аппаратный сброс?
Непонятно с этим TFT_CS_RESET(); вначале TFT_Init.
Я видел драйверы где стоит TFT_CS_RESET(); видел драйверы где стоит TFT_CS_SET();
На яндекс диске TFT_CS_SET();
Непонятно зачем он нужен здесь.
Проверил.
Аппаратный RESET срабатывает и с выбранным чипом TFT_CS_RESET(); и без выбранного чипа TFT_CS_SET();
То есть всё равно. Выбор чипа для аппаратного сброса не нужен.
Присутствие "TFT_CS_RESET();" в начале TFT_Init непонятно.
Присутствие "TFT_CS_RESET();" в начале TFT_Init непонятно.
Бывает люди пишут. Пробуют. Потом убрать забывают.
TFT_RST_SET();
Это обязательно для запуска дисплея.
TFT_RST_RESET(); не обязательно, но желательно.
---------------------------
Чаще всего я видел это
TFT_CS_SET();
Может это тоже необходимо. Ну стандартное состояние дисплея, когда CS не выбран и дисплей находится в бездействии.
Сейчас мне кажется, что это просто для порядка надо.
Во всех драйверах это пишут, не думаю, что везде забыли убрать.
А вот для чего пишут Column_Address_Set и Page_Address_Set в инициализации, мне непонятно.
Может это надо для гаммы цветов, ну на какой области надо применить настройки гаммы цветов.
Например команда Memory Write использует всё доступное пространство, которое было выбрано координатами курсора.
Но если убрать из инициализации Column_Address_Set и Page_Address_Set, то ничего не изменится.
Не во всех драйверах есть Column_Address_Set и Page_Address_Set, но в некоторых видел.
Может если нет Column_Address_Set и Page_Address_Set, то идёт как то автоматическое определение границ дисплея, а если есть Column_Address_Set и Page_Address_Set, то границы дисплея указываются для настроек гаммы цветов.
Ведь сразу после Column_Address_Set и Page_Address_Set идёт команда Gamma_Set.
команда Gamma_Set
Гамма применяется для TFT матрицы. На "окно" влиять не должна.
https://microtechnics.ru/profilegrid_blogs/rabota-s-tft-displeyami-na-primere-kontrollera-ili9341/
TFT_SetCursorPosition(0,0,200,200); TFT_SendCommand(Memory_Write); for(int i=0; i<(239*319); i++) { TFT_SendData(0x68); TFT_SendData(0x97); }
TFT_SendCommand(Memory_Write); for(int i=0; i<(239*319); i++) { TFT_SendData(0x68); TFT_SendData(0x97); }
Количество заполняемых пикселей здесь определяется циклом for(int i=0; i<(239*319); i++)
@stm Если я не ошибаюсь, если после инициализации не вводить "окно", оно равно левому верхнему углу и правому нижнему.
Если указать окно 10х10 и записать 100 раз цвет, а после этого 50 раз другой, то прорисовка будет в том же окне. И мы должны получить нижнюю половину квадрата первым цветом, верхнюю вторым.
Проверить нужно.
Можно было бы проверить влияет ли Column_Address_Set и Page_Address_Set на команды Gamma_Set, Positive_Gamma_Correction, Negative_Gamma_Correction.
Но проблема в том, что я не вижу разницы если я вообще удалю Gamma_Set, Positive_Gamma_Correction, Negative_Gamma_Correction из кода.
Если б что то менялось при удалении Gamma_Set, Positive_Gamma_Correction, Negative_Gamma_Correction, то можно было бы проверить влияние Column_Address_Set и Page_Address_Set на гамму.
Я изменил параметры Positive_Gamma_Correction, Negative_Gamma_Correction так что цвета дисплея изменились.
Column_Address_Set и Page_Address_Set не влияют на Positive_Gamma_Correction, Negative_Gamma_Correction.
Но если Column_Address_Set и Page_Address_Set нужны, то думаю они нужны для команды Gamma_Set.
А при изменении параметров этой команды ничего на дисплее не меняется.
Проверить не могу необходимы ли для Gamma_Set координаты курсора.
https://microtechnics.ru/profilegrid_blogs/rabota-s-tft-displeyami-na-primere-kontrollera-ili9341/
>если что, регистры этого контроллера 18-ти битные
Я тоже заметил в докумментации, что биты идут от D0 до D17
Допустим при передаче данных дисплею командой Memory Write
Я передаю ПАРАМЕТРЫ для команды Memory Write через SPI, эти параметры должны заполнить полностью весь регистр от D0 до D17.
Пространство для кодирования пикселя 16 битное, а регистр 18 битный? Это как?
Я об этом в статье писал.
В командах используется только 8 бит.
Остальные отбрасываются.
В заполнении экрана цветом используется от 3х, до 18 бит.
Потому регистры там и 18 битные.