Ср мар 16, 2022 23:12:23
/*
* ili9488.c
*
* Created on: Mar 14, 2022
* Author: AVerzin
*/
#include "ili9488.h"
unsigned int X_SIZE = 320;
unsigned int Y_SIZE = 480;
unsigned long dtt = 0;
// что нужно доделать
// чтобы было незаметно глазу обновление экрана он это должен делать быстрее чем за
// 1с / 25 кадров в секунду = 0,04 секунды = 40 миллисекунд = 40 000 микросекунд
// сделать функцию перевода портов линии данных из состояния чтения в состояние вывода
// убрать упоминание портов во всех функицях, сделать все на метках DATA,CS и тп (+)
// отладить функцию чтения портов линии данных (+)
// сделать функцию чтения из регистров LCD (+)
// прочитать ID LCD (!!!!) (+)
// Функция установки нужных уровней на линии выбора дисплея PORTC4
void TFT9488_CS_Active(void) {
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, RESET);
}
void TFT9488_CS_Idle(void) {
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, SET);
}
// Функции установки состояния ножки RESET PORTC5
void TFT9488_RESET_Active(void) {
HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, RESET);
}
void TFT9488_RESET_Idle(void) {
HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, SET);
}
// Функции установки состояния ножки отвечающей за строб, о том что данные готовы к считыванию
// PORTC2
void TFT9488_WR_Active(void) {
HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, RESET);
}
void TFT9488_WR_Idle(void) {
HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, SET);
}
// Функции установки состояния ножки если уровень низкий то мы читаем данные из LCD
// PORTB2
void TFT9488_RD_Active(void) {
HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, RESET);
}
void TFT9488_RD_Idle(void) {
HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, SET);
}
// Функции установки состояния ножки отвечающий за то что будет передаваться данные или команда
// PORTС3
void TFT9488_RS_Command(void) {
HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, RESET);
}
void TFT9488_RS_Data(void) {
HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, SET);
}
// Функция чтения данных из портов на линии данных
char TFT9488_Port_Read(void) {
char dt; // переменнная для чтения данных
TFT9488_Set_Port_Read(); // Установка портов линии даннных на чтение
// чтение данных с портов линии данных начиная со старшего бита
dt = HAL_GPIO_ReadPin(DATA7_GPIO_Port, DATA7_Pin); // прочитали бит с пина
dt <<= 1; // сдвинули влево на 1 разряд
dt |= HAL_GPIO_ReadPin(DATA6_GPIO_Port, DATA6_Pin); // прочитали следующий пин и присоединили его к dt
dt <<= 1;
dt |= HAL_GPIO_ReadPin(DATA5_GPIO_Port, DATA5_Pin);
dt <<= 1;
dt |= HAL_GPIO_ReadPin(DATA4_GPIO_Port, DATA4_Pin);
dt <<= 1;
dt |= HAL_GPIO_ReadPin(DATA3_GPIO_Port, DATA3_Pin);
dt <<= 1;
dt |= HAL_GPIO_ReadPin(DATA2_GPIO_Port, DATA2_Pin);
dt <<= 1;
dt |= HAL_GPIO_ReadPin(DATA1_GPIO_Port, DATA1_Pin);
dt <<= 1;
dt |= HAL_GPIO_ReadPin(DATA0_GPIO_Port, DATA0_Pin);
TFT9488_Set_Port_Write();// Возврат портов линии данных на запись, так как этот режим применяется чаще соответственно он должен быть по умолчанию
return (dt);
}
// Функция записи данных в порты на линию данных
void TFT9488_Port_Write(char dt) {
// смысл этого (dt & 0b10000000)?1:0 в следующем. это тернарная операция if
// мы смотрим, есть ли в старшем бите dt единица и если она есть, то выдаем 1
// если в старшем бите 0, соотвественно выводим 0.
HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, (dt & 0b10000000) ? 1 : 0);
HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, (dt & 0b01000000) ? 1 : 0);
HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, (dt & 0b00100000) ? 1 : 0);
HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, (dt & 0b00010000) ? 1 : 0);
HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, (dt & 0b00001000) ? 1 : 0);
HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, (dt & 0b00000100) ? 1 : 0);
HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, (dt & 0b00000010) ? 1 : 0);
HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, (dt & 0b00000001) ? 1 : 0);
}
// Функция которая дает строб, который говорит что данные готовы
void TFT9488_WR_Strobe(void) {
TFT9488_WR_Active();
TFT9488_WR_Idle();
}
//—————————————————————
void TFT9488_SendCommand(unsigned char cmd) {
TFT9488_RS_Command(); //лапка в состоянии посылки команды
TFT9488_RD_Idle(); //отключим чтение
TFT9488_CS_Active(); //подали команду LCD чтобы он начал слушать
TFT9488_Port_Write(cmd); //выставили на нужных ножках данные
TFT9488_WR_Strobe(); //подаем строб, чтобы LCD забрал данные
TFT9488_CS_Idle(); //подаем команду на прекращение слушания LCD
}
//—————————————————————
void TFT9488_SendData(unsigned char dt) {
TFT9488_RS_Data(); //лапка в состоянии посылки данных
TFT9488_RD_Idle(); //отключим чтение
TFT9488_CS_Active(); //выбор дисплея
TFT9488_Port_Write(dt);
TFT9488_WR_Strobe();
TFT9488_CS_Idle();
}
//—————————————————————
void TFT9488_reset(void) {
TFT9488_CS_Idle();
TFT9488_WR_Idle();
TFT9488_RD_Idle();
TFT9488_RESET_Active();
HAL_Delay(2);
TFT9488_RESET_Idle();
TFT9488_CS_Active();
TFT9488_SendCommand(0x01); //Software Reset
for (uint8_t i = 0; i < 3; i++)
TFT9488_WR_Strobe();
TFT9488_CS_Idle();
}
//—————————————————————
void TFT9488_Write8(unsigned char dt) {
TFT9488_Port_Write(dt);
TFT9488_WR_Strobe();
}
//—————————————————————
unsigned long TFT9488_ReadReg(unsigned char r) {
unsigned long id;
unsigned char x;
TFT9488_CS_Active(); //выбор дисплея
TFT9488_RS_Command(); //лапка в состоянии посылки команды
TFT9488_Write8(r);
TFT9488_Set_Port_Read();
TFT9488_RS_Data();
// _delay_us(50);
HAL_Delay(1);
TFT9488_RD_Active();
// _delay_us(5);
HAL_Delay(1);
x = TFT9488_Port_Read();
TFT9488_RD_Idle();
id = x;
id <<= 8;
TFT9488_RD_Active();
// _delay_us(5);
HAL_Delay(1);
x = TFT9488_Port_Read();
TFT9488_RD_Idle();
id |= x;
id <<= 8;
TFT9488_RD_Active();
// _delay_us(5);
HAL_Delay(1);
x = TFT9488_Port_Read();
TFT9488_RD_Idle();
id |= x;
id <<= 8;
TFT9488_RD_Active();
// _delay_us(5);
HAL_Delay(1);
x = TFT9488_Port_Read();
TFT9488_RD_Idle();
id |= x;
if (r == 0xEF) {
id <<= 8;
TFT9488_RD_Active();
// _delay_us(5);
HAL_Delay(1);
x = TFT9488_Port_Read();
TFT9488_RD_Idle();
id |= x;
}
TFT9488_CS_Idle();
TFT9488_Set_Port_Write();
// _delay_us(150);//stabilization time
HAL_Delay(2);
return (id);
}
//—————————————————————
// Функции настройки портов к котормы подключены линии данных на чтение или запись
// линии данных подключены к портам G и A
void TFT9488_Set_Port_Read(void) {
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
// Каждый пин расписан индивидуально, без обьединенений для того чтобы при перенеосе этой библиотеки
// нужно было менять пины и порты только в файле .h
/*Configure GPIO pins : DATA7_Pin*/
GPIO_InitStruct.Pin = DATA7_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DATA7_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA6_Pin*/
GPIO_InitStruct.Pin = DATA6_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DATA6_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA5_Pin*/
GPIO_InitStruct.Pin = DATA5_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DATA5_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA4_Pin*/
GPIO_InitStruct.Pin = DATA4_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DATA4_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA3_Pin*/
GPIO_InitStruct.Pin = DATA3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DATA3_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA2_Pin*/
GPIO_InitStruct.Pin = DATA2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DATA2_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA1_Pin*/
GPIO_InitStruct.Pin = DATA1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DATA1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA0_Pin*/
GPIO_InitStruct.Pin = DATA0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DATA0_GPIO_Port, &GPIO_InitStruct);
}
void TFT9488_Set_Port_Write(void) {
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, GPIO_PIN_SET);
/*Configure GPIO pins : DATA7_Pin*/
GPIO_InitStruct.Pin = DATA7_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DATA7_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA6_Pin*/
GPIO_InitStruct.Pin = DATA6_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DATA6_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA5_Pin*/
GPIO_InitStruct.Pin = DATA5_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DATA5_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA4_Pin*/
GPIO_InitStruct.Pin = DATA4_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DATA4_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA3_Pin*/
GPIO_InitStruct.Pin = DATA3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DATA3_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA2_Pin*/
GPIO_InitStruct.Pin = DATA2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DATA2_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA1_Pin*/
GPIO_InitStruct.Pin = DATA1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DATA1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : DATA0_Pin*/
GPIO_InitStruct.Pin = DATA0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DATA0_GPIO_Port, &GPIO_InitStruct);
}
// конфигурирование портов данных и управления
void TFT9488_Port_ini(void) {
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
// Конфигурирование начальных уровней, в высокое положение
HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, GPIO_PIN_SET);
/*Configure GPIO pins : RS_Pin*/
GPIO_InitStruct.Pin = RS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(RS_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : WR_Pin*/
GPIO_InitStruct.Pin = WR_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(WR_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : CS_Pin */
GPIO_InitStruct.Pin = CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(CS_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : RST_Pin */
GPIO_InitStruct.Pin = RST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(RST_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : RD_pin */
GPIO_InitStruct.Pin = RD_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(RD_GPIO_Port, &GPIO_InitStruct);
TFT9488_Set_Port_Write();
}
// Функция установки ориентации дисплея
/*
* 0 — вертикальная обычная ориентация
1 — горизонтальная обычная ориентация
2 — вертикальная перевёрнутная ориентация
3 — горизонтальная перевёрнутная ориентация.
*
*/
void TFT9488_SetRotation(unsigned char r) {
TFT9488_SendCommand(0x36);
switch (r) {
case 0:
TFT9488_SendData(0x48);
X_SIZE = 320;
Y_SIZE = 480;
break;
case 1:
TFT9488_SendData(0x28);
X_SIZE = 480;
Y_SIZE = 320;
break;
case 2:
TFT9488_SendData(0x88);
X_SIZE = 320;
Y_SIZE = 480;
break;
case 3:
TFT9488_SendData(0xE8);
X_SIZE = 480;
Y_SIZE = 320;
break;
}
}
// Функция заливки области
void TFT9488_Flood(unsigned short color, unsigned long len)
{
unsigned short blocks;
unsigned char i, hi = color>>8, lo=color;
TFT9488_CS_Active();
TFT9488_RS_Command();
TFT9488_Write8(0x2C);
TFT9488_RS_Data();
TFT9488_Write8(hi);
TFT9488_Write8(lo);
len--;
blocks=(unsigned short)(len/64);//64 pixels/block
if (hi==lo)
{
while(blocks--)
{
i=16;
do
{
TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();//2bytes/pixel
TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();//x4 pixel
} while (--i);
}
//Fill any remaining pixels(1 to 64)
for (i=(unsigned char)len&63;i--;)
{
TFT9488_WR_Strobe();
TFT9488_WR_Strobe();
}
}
else
{
while(blocks--)
{
i=16;
do
{
TFT9488_Write8(hi);TFT9488_Write8(lo);TFT9488_Write8(hi);TFT9488_Write8(lo);
TFT9488_Write8(hi);TFT9488_Write8(lo);TFT9488_Write8(hi);TFT9488_Write8(lo);
} while (--i);
}
//Fill any remaining pixels(1 to 64)
for (i=(unsigned char)len&63;i--;)
{
TFT9488_Write8(hi);
TFT9488_Write8(lo);
}
}
TFT9488_CS_Idle();
}
// Функция записи в регистр 32 числа
void TFT9488_WriteRegister32(unsigned char r, unsigned long d)
{
TFT9488_CS_Active();
TFT9488_RS_Command();
TFT9488_Write8(r);
TFT9488_SendData;
HAL_Delay(1);
TFT9488_Write8(d>>24);
HAL_Delay(1);
TFT9488_Write8(d>>16);
HAL_Delay(1);
TFT9488_Write8(d>>8);
HAL_Delay(1);
TFT9488_Write8(d);
TFT9488_CS_Idle();
}
/*
* прежде чем отправлять в память байты, нам нужно объявить область памяти, в которую будет вся наша цепочка одинаковых пикселей отправляться. Для этого мы напишем специальную функцию
*/
void TFT9488_SetAddrWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
unsigned long t;
TFT9488_CS_Active();
TFT9488_SendCommand(0x2A);
TFT9488_SendData(x1 >> 8);
TFT9488_SendData(x1 & 0xFF); // XSTART
TFT9488_SendData(x2 >> 8);
TFT9488_SendData(x2 & 0xFF); // XEND
TFT9488_SendCommand(0x2C);
TFT9488_SendData(y1>>8);
TFT9488_SendData(y1 &0xff); // YSTART
TFT9488_SendData(y2>>8);
TFT9488_SendData(y2 &0xff); // YEND
TFT9488_SendCommand(0x2C); // write to RAM
//t = x1;
//t<<=16;
//t |= x2;
//TFT9488_WriteRegister32(0x2A,t);//Column Addres Set
//t = y1;
//t<<=16;
//t |= y2;
//TFT9488_WriteRegister32(0x2B,t);//Page Addres Set
TFT9488_CS_Idle();
}
void TFT9488_FillScreen(unsigned int color)
{
TFT9488_SetAddrWindow(0,0,X_SIZE-1,Y_SIZE-1);
TFT9488_Flood(color,(long)X_SIZE*(long)Y_SIZE);
}
// Заливка прямоугольника
void TFT9488_FillRectangle(unsigned int color,unsigned int x1, unsigned int y1,
unsigned int x2, unsigned int y2)
{
TFT9488_SetAddrWindow(x1, y1, x2, y2);
TFT9488_Flood(color, (long)(x2-x1+1) * (long)(y2-y1+1));
}
void TFT9488_ini(void) {
TFT9488_Port_ini();
TFT9488_reset();
HAL_Delay(1000);
dtt = TFT9488_ReadReg(0xD3);
TFT9488_CS_Active();
//Software Reset
TFT9488_SendCommand(0x01);
// Display OFF
TFT9488_SendCommand(0x28);
// Positive Gamma Correction
TFT9488_SendCommand(0xE0);
TFT9488_SendData(0x00);
TFT9488_SendData(0x03);
TFT9488_SendData(0x09);
TFT9488_SendData(0x08);
TFT9488_SendData(0x16);
TFT9488_SendData(0x0A);
TFT9488_SendData(0x3F);
TFT9488_SendData(0x78);
TFT9488_SendData(0x4C);
TFT9488_SendData(0x09);
TFT9488_SendData(0x0A);
TFT9488_SendData(0x08);
TFT9488_SendData(0x16);
TFT9488_SendData(0x1A);
TFT9488_SendData(0x0F);
//Negative Gamma Correction
TFT9488_SendCommand(0XE1);
TFT9488_SendData(0x00);
TFT9488_SendData(0x16);
TFT9488_SendData(0x19);
TFT9488_SendData(0x03);
TFT9488_SendData(0x0F);
TFT9488_SendData(0x05);
TFT9488_SendData(0x32);
TFT9488_SendData(0x45);
TFT9488_SendData(0x46);
TFT9488_SendData(0x04);
TFT9488_SendData(0x0E);
TFT9488_SendData(0x0D);
TFT9488_SendData(0x35);
TFT9488_SendData(0x37);
TFT9488_SendData(0x0F);
//Power Control 1
TFT9488_SendCommand(0XC0);
TFT9488_SendData(0x17); //Vreg1out
TFT9488_SendData(0x15); //Verg2out
//Power Control 2
TFT9488_SendCommand(0xC1);
TFT9488_SendData(0x41); //VGH,VGL
//Power Control 3
TFT9488_SendCommand(0xC5);
TFT9488_SendData(0x00);
TFT9488_SendData(0x12); //Vcom
TFT9488_SendData(0x80);
//Memory Access или это определение ориентации
TFT9488_SendCommand(0x36);
TFT9488_SendData(0x48); //01001000
TFT9488_SendCommand(0x3A); // Interface Pixel Format
TFT9488_SendData(0x55); //16 bit
TFT9488_SendCommand(0XB0); // Interface Mode Control
TFT9488_SendData(0x00); //SDO NOT USE
TFT9488_SendCommand(0xB1); //Frame rate
TFT9488_SendData(0xA0); //60Hz
TFT9488_SendCommand(0xB4); //Display Inversion Control
TFT9488_SendData(0x02); //2-dot
TFT9488_SendCommand(0XB6); //Display Function Control RGB/MCU Interface Control
TFT9488_SendData(0x02); //MCU
TFT9488_SendData(0x02); //Source,Gate scan dieection
TFT9488_SendData(0x3B); //480 линий
TFT9488_SendCommand(0XE9); // Set Image Functio
TFT9488_SendData(0x00); // Disable 24 bit data
TFT9488_SendCommand(0xF7); // Adjust Control
TFT9488_SendData(0xA9);
TFT9488_SendData(0x51);
TFT9488_SendData(0x2C);
TFT9488_SendData(0x82); // D7 stream, loose
//Выйдем из спящего режим
TFT9488_SendCommand(0x11);
HAL_Delay(2);
//Включение дисплея
TFT9488_SendCommand(0x29);
TFT9488_SendData(0x2C);
HAL_Delay(2);
}
/*
* ili9488.c
*
* Created on: Mar 16, 2022
* Author: AVerzin
*/
Ср мар 16, 2022 23:40:35
// Функция записи данных в порты на линию данных
void TFT9488_Port_Write(char dt) {
// смысл этого (dt & 0b10000000)?1:0 в следующем. это тернарная операция if
// мы смотрим, есть ли в старшем бите dt единица и если она есть, то выдаем 1
// если в старшем бите 0, соотвественно выводим 0.
HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, (dt & 0b10000000) ? 1 : 0);
HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, (dt & 0b01000000) ? 1 : 0);
HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, (dt & 0b00100000) ? 1 : 0);
HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, (dt & 0b00010000) ? 1 : 0);
HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, (dt & 0b00001000) ? 1 : 0);
HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, (dt & 0b00000100) ? 1 : 0);
HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, (dt & 0b00000010) ? 1 : 0);
HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, (dt & 0b00000001) ? 1 : 0);
}
Чт мар 17, 2022 06:32:52
Чт мар 17, 2022 06:38:37
Чт мар 17, 2022 07:23:18
Чт мар 17, 2022 20:55:35
AlanDrakes писал(а):замут чтобы линии на экран назначать любой порт, любой пин.
VladislavS писал(а):План действий такой:
1. Отказаться от HAL_GPIO_WritePin.
2. Сгруппировать записи по портам. У вас их три, вот и должно быть три записи.
3. Объединить запись линий data с сигналами RS и RW.
4. Посмотреть на код и перегруппировать ноги так, чтобы было как можно меньше логических операций при группировке данных для записи в порты.
На каждом шаге можно получить значительный прирост в скорости. Atmega8 так уж точно обойдём
uint16_t mask = 0x0000;
if (dt & 0b00000010) {
mask = 0x0080;
}
GPIOC->ODR = mask;
mask = 0x0000;
//7 бит данных на 8 порт
if(dt & 0b10000000) {
mask = 0x0100;
}
// 0бит данных на 9 порт
if(dt & 0b00000001){
mask |= 0x0200;
}
//2бит данных на 10 порт
if(dt & 0b00000100){
mask |= 0x0400;
}
GPIOA->ODR = mask;
mask = 0x0000;
//3бит данных на 3 порт
if(dt & 0b00001000){
mask |= 0x0008;
}
//4 бит данных на 5 порт
if(dt & 0b00010000){
mask |=0x0020 ;
}
//6 бит данных на 10 порту
if(dt & 0b01000000){
mask |= 0x0400;
}
GPIOB->ODR = mask;
Чт мар 17, 2022 21:37:11
Пт мар 18, 2022 00:15:46
if (dt & 0b10000000) maskA |= GPIO_PIN_8; // 7 бит данных на 8 пин порт А
if (dt & 0b01000000) maskB |= GPIO_PIN_10; // 6 бит данных на 10 пин порта В
if (dt & 0b00100000) maskB |= GPIO_PIN_4;// 5 бит данных на 4 пин порта В
if (dt & 0b00010000) maskB |= GPIO_PIN_5; // 4 бит данных на 5 пин порта В
if (dt & 0b00001000) maskB |= GPIO_PIN_3; // 3 бит данных на 3 пин порт В
if (dt & 0b00000100) maskA |= GPIO_PIN_10; // 2 бит данных на 10 пин порт А
if (dt & 0b00000010) maskC |= GPIO_PIN_7; // 1 бит данных на 7 пин порта С
if (dt & 0b00000001) maskA |= GPIO_PIN_9; // 0 бит данных на 9 пин порт А
GPIOA->BSRR = maskA;
GPIOB->BSRR = maskB;
GPIOC->BSRR = maskC;
Пт мар 18, 2022 00:21:22
Пт мар 18, 2022 00:27:36
Reflector писал(а):BSRR состоит из двух половинок, в одной сбрасываешь все биты пинов, в другой устанавливаешь нужные(установка имеет приоритет).
uint16_t masa = 0;
masa |= GPIO_PIN_5;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
// зажигаем 5 пин
GPIOA -> BSRR = masa;
HAL_Delay(150);
GPIOA -> BRR = masa;
HAL_Delay(150);
}
Пт мар 18, 2022 00:30:23
Пт мар 18, 2022 00:41:25
Пт мар 18, 2022 00:51:19
GPIOA->BSRR = (0x07 << 16) | 5;
Пт мар 18, 2022 01:25:35
if (dt & 0b10000000) maskA |= GPIO_PIN_8; // 7 бит данных на 8 пин порт А
if (dt & 0b01000000) maskB |= GPIO_PIN_10; // 6 бит данных на 10 пин порта В
if (dt & 0b00100000) maskB |= GPIO_PIN_4; // 5 бит данных на 4 пин порта В
if (dt & 0b00010000) maskB |= GPIO_PIN_5; // 4 бит данных на 5 пин порта В
if (dt & 0b00001000) maskB |= GPIO_PIN_3; // 3 бит данных на 3 пин порт В
if (dt & 0b00000100) maskA |= GPIO_PIN_10; // 2 бит данных на 10 пин порт А
if (dt & 0b00000010) maskC |= GPIO_PIN_7; // 1 бит данных на 7 пин порта С
if (dt & 0b00000001) maskA |= GPIO_PIN_9; // 0 бит данных на 9 пин порт А
GPIOA->BSRR = (GPIO_PIN_8|GPIO_PIN_10|GPIO_PIN_9) << 16 | maskA;
GPIOB->BSRR = (GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16 | maskB;
GPIOC->BSRR = GPIO_PIN_7 << 16 | maskC;
Пт мар 18, 2022 06:34:21
GPIOA->BSRR = ((GPIO_PIN_8|GPIO_PIN_10|GPIO_PIN_9) << 16)
| ((dt & 0b10000000) << 1) // 7 бит данных на 8 пин порт А
| ((dt & 0b00000100) << 8) // 2 бит данных на 10 пин порт А
| ((dt & 0b00000001) << 9); // 0 бит данных на 9 пин порт А
GPIOB->BSRR = ((GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16)
| ((dt & 0b01000000) << 4) // 6 бит данных на 10 пин порта В
| ((dt & 0b00100000) >> 1) // 5 бит данных на 4 пин порта В
| ((dt & 0b00010000) << 1) // 4 бит данных на 5 пин порта В
| (dt & 0b00001000); // 3 бит данных на 3 пин порт В
GPIOC->BSRR = (GPIO_PIN_7 << 16 )
| ((dt & 0b00000010) << 6); // 1 бит данных на 7 пин порта С
Пт мар 18, 2022 07:03:51
// Сброс пинов 0..7 порта B (шина напрямую сопоставлена D0 -> PB0, D1 -> PB1, ... D7 -> PB7
GPIOB->BSRR = GPIO_BSRR_BR0 | GPIO_BSRR_BR1 | GPIO_BSRR_BR2 <...> GPIO_BSRR_BR7;
// Выводим байт в порт. "Нижние" биты [0..15] вызвают установку соответствующих пинов порта.
GPIOB->BSRR = (uint8_t)NEXT_DATA_BYTE;
// Опускаем /CS, затем /WR
GPIOx->BSRR = GPIO_BSRR_BR_cs_pin_n;
GPIOx->BSRR = GPIO_BSRR_BR_wr_pin_n;
// Поднимаем /WR, затем /CS
GPIOx->BSRR = GPIO_BSRR_BS_cs_pin_n;
GPIOx->BSRR = GPIO_BSRR_BS_wr_pin_n;
// Запись байта данных
FSMC_REGION_DATA = (uint8_t)Next_Data_Byte;
// Запись команды
FSMC_REGION_CMD = (uint8_t)Command_Byte;
// PORTD[0,1,4,5,7,11,13,14,15] = D2, D3, Rd, Wr, Cs, A16, D0, D1
// PORTE[7-10] = D4, D5, D6, D7
Пт мар 18, 2022 09:43:24
// В глобальной области
#define MB(X) (((GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16)\
| ((X&1)?(1<<3):0)\
| ((X&2)?(1<<5):0)\
| ((X&4)?(1<<4):0)\
| ((X&8)?(1<<10):0))
const uint32_t MaskB[16] = { MB(0), MB(1), MB(2), MB(3),
MB(4), MB(5), MB(6), MB(7),
MB(8), MB(9), MB(10), MB(11),
MB(12), MB(13), MB(14), MB(15) };
GPIOB->BSRR = MaskB[(dt>>3)&0xF];
struct MASKS
{
uint32_t MaskA;
uint32_t MaskB;
uint32_t MaskC;
};
void TFT9488_Wr(MASKS *masks)
{
GPIOA->BSRR = masks->MaskA;
GPIOB->BSRR = masks->MaskB;
GPIOC->BSRR = masks->MaskC;
}
//void TFT9488_Wr(MASKS *masks)
//{
// GPIOA->BSRR = masks->MaskA;
LDR.N R1,??DataTable2
LDR R2,[R0, #+0]
STR R2,[R1, #+0]
// GPIOB->BSRR = masks->MaskB;
LDR R3,[R0, #+4]
STR R3,[R1, #+1024]
// GPIOC->BSRR = masks->MaskC;
LDR R0,[R0, #+8]
STR R0,[R1, #+2048]
//}
BX LR
Пт мар 18, 2022 19:03:08
VladislavS писал(а):На какой скорости работает процессор и какой уровень оптимизации?
VladislavS писал(а):Для начала вот так
VladislavS писал(а):С таблицей перекодировки как-то так
AlanDrakes писал(а):В случае же с записью через FSMC, будет ещё интереснее:
AlanDrakes писал(а):А вы можете использовать пины более... компактно? Или так разведено на плате?
Пт мар 18, 2022 19:05:36
В порт B пишутся 4 бита одной группой, но они переставленны местами. 4 бита дают 16 разных значений для записи в BSRR. Их можно вычислить заранее, положить в массив и из него выбирать ставя в соответствие.К сожалению, я вообще не понимаю что тут написано
Так вы ещё оптимизировать, по большому счёту, ещё не началиВроде как у меня экран уже с похожей скоростью перекрашивается
Пт мар 18, 2022 19:35:59
VladislavS писал(а):У F103 72 МГц штатная тактовая, включайте. Оптимизацию -О3 ставьте, ищите где.