// Главный итоговый проект для ili9341

#define F_CPU 1000000UL

#include <avr/io.h>
#include <stdint.h> // Заголовочный файл объявляет целочисленные типы
#include <stdlib.h> // функции, занимающиеся выделением памяти, контроль процесса выполнения программы, преобразования типов и другие.
#include <string.h> //строковаые типы.
#include <util/delay.h> //Задержка
#include <avr/interrupt.h>//Прерывания

// Инициализация портов по коротким коммандам..
//#define PIN_SPI_1		PORTA=PORTA|(1<<PORTA0); //PA0 // переключатель SPI.
#define PIN_RST_1		PORTB=PORTB|(1<<PORTB1); //PA1 // сброс.
#define PIN_LED_1		PORTB=PORTB|(1<<PORTB2); //PA2 // подсветка.
#define PIN_DC_1_data   PORTB=PORTB|(1<<PORTB3); //PA3 // выбор комманды0 или данные1.
#define PIN_CS_1		PORTB=PORTB|(1<<PORTB4); //PA4 // выбор чипа.


//#define PIN_SPI_0		PORTA^=(1<<PORTA0); //PA0 // переключатель  SPI.
#define PIN_RST_0		PORTB^=(1<<PORTB1); //PA1 // сброс.
#define PIN_LED_0		PORTB^=(1<<PORTB2); //PA2 // подсветка.
#define PIN_DC_0_cmd    PORTB^=(1<<PORTB3); //PA3 // выбор комманды0 или данные1.
#define PIN_CS_0		PORTB^=(1<<PORTB4); //PA4 // выбор чипа.


int main(void)
{   //char Flag0=1; // флаг если пин включен то работаем иначе пропускаем код.
	unsigned char Flag1=0; // флаш чтобы запустить программу только 1 раз.
	//unsigned char mi=0;
	//unsigned char zn=0;
	
	init_port(); //Инициализируем порт A и B.
	spi_settings(); // Настройка SPI

	while (1){
		
		//Если на ноге PORTB0 ноль то выполним условие.
		if (!(PINB & (1<<PORTB0))) {
		
		//Если на ноге PORTB0 один то выполним условие.
		//if (PINB & (1<<PORTB0)) { //Работает если PINB0 = 1 то выполняется.
				if (Flag1==0){
					PIN_LED_0;
					_delay_ms ( 1000 );
					PIN_LED_1;
					_delay_ms ( 1000 );
					PIN_LED_0;
					_delay_ms ( 1000 );
					PIN_LED_1;
					_delay_ms ( 1000 );
					PIN_LED_0;
					_delay_ms ( 1000 );
					PIN_LED_1;
					_delay_ms ( 1000 );
					PIN_LED_0;
					_delay_ms ( 1000 );
					PIN_LED_1;
					_delay_ms ( 1000 );
					PIN_LED_0;
					
					
					
					ili9341_init();

					
					PIN_LED_1;
					
					
					
					
			Flag1=1;}
			
			//ЗДЕСЬ ДОЛЖНА БЫТЬ Ф-ЦИЯ инициализации Дисплея.
			//i+=1;
			//spi_SPDR_otpravit(0b00001010);
			//_delay_ms ( 1000 );
			/*spi_prinyat();
			sei();
			while(1);
		
*/
/*
					LCD_Fill(0x10);
					_delay_ms (1000);
					
					LCD_Fill(0x50);
					_delay_ms (3000);
					
					LCD_Fill(0x80);
					_delay_ms (3000);
					
					LCD_Fill(0xA0);
					_delay_ms (3000);
					
					LCD_Fill(0xFF);
					_delay_ms (3000);
*/
		}

	}
}


void init_port()
{
	PORTB= 0b00000001;
	DDRB = 0b11111110;
	PORTA= 0b00000000;
	DDRA = 0xFF;
	
}

void spi_settings(void)
{
	//регистр SPCR. $2D ($4D)
	
	//7-Разрешение прерывания от SPI
	SPCR^=(1<<SPIE);// SPIE=0;
	//6-Включение/выключение SPI
	SPCR|=(1<<SPE);// SPE=1;
	//5-Порядок передачи данных
	SPCR^=(1<<DORD);// DORD=0;
	//4-Выбор режима работы (Master/Slave)
	SPCR^=(1<<MSTR);//MSTR=0;
	//3-Полярность тактового сигнала
	SPCR^=(1<<CPOL);// CPOL=0;
	/*Полярность тактового сигнала.
	0 —генерируются импульсы положительной полярности, при отсутствии импульсов на выводе присутствует НИЗКИЙ уровень;
	1 —генерируются импульсы отрицательной полярности, при отсутствии импульсов на выводе присутствует ВЫСОКИЙ уровень*/

	//2-Фаза тактового сигнала
	SPCR^=(1<<CPHA);// CPHA=0;
	/* Фаза тактового сигнала.
	0 —обработка данных производится по переднему фронту импульсов сигнала SCK (для CPOL =0 —по нарастающему фронту, а для CPOL =1 —по спадающему фронту);
	1 —обработка производится по заднему фронту импульсов сигнала SCK(для CPOL =0 —по спадающему фронту, а для CPOL =1 —по нарастающему фронту) */

	//1,0-Скорость передачи
	SPCR^=(1<<SPR1);// SPR1=0
	SPCR^=(1<<SPR0);// SPR0=0

	//Формат регистра SPSR



	/*
	7 SPIF
	Флаг прерывания от SPI. Данный флаг устанавливается в 1 по окончании
	передачи очередного байта. Если флаг SPIE регистра SPCR установлен в 1 и
	прерывания разрешены, то одновременно с установкой флага генерируется
	прерывание от SPI. Также флаг SPIF устанавливается в 1 при переводе_мик-
	роконтроллера из режима Master в режим Slave посредством вывода SS (см.
	раздел 10.4). Флаг сбрасывается аппаратно либо при старте подпрограммы
	обработки прерывания, либо после чтения регистра состояния SPI с
	последующим обращением к регистру данных SPI (SPDR)

	6 WCOL
	Флаг конфликта записи. Данный флаг устанавливается в 1 при попытке
	записи в регистр данных (SPDR) во время передачи очередного байта. Флаг
	сбрасывается аппаратно после чтения регистра состояния SPI с последующим
	обращением к регистру данных SPI

	5...1 -

	0 */
	SPSR^=(1<<SPI2X);// SPI2X=0
	/*Зарезервированы, читаются как 0
	Удвоение скорости обмена. При установке этого бита в 1 и работе
	микроконтроллера в режиме Master частота сигнала SCK удваивается


	Передаваемые данные записываются, а принимаемые — считываются из регистра данных SPDR. по адресу $0F ($2F),
	*/
}


// spi_SPDR_otpravit(i);  Эта функция передает код по SPI. то что в переменной idat.
void spi_SPDR_otpravit(char idat)  //функция с примера SPI server2
{	SPDR = idat; // Начало передачи
	while(!(SPSR & (1<<SPIF))) ; // Ожидание окончания передачи
	//return;// SPDR; //возвращаем принятый байт
}



/*char spi_SPDR_prinyat(void){ // Чтение из SPI
//Включение SPI, режима ведомого, разрешаем прерывани¤
	//7-Разрешение прерывания от SPI // SPIE=1;
	//6-Включение/выключение SPI // SPE=1;
	SPCR = (1<<SPE)|(1<<SPIE);

ISR(SPI_STC_vect) //прерывание по приему байта
{ 
if (SPDR!=(0x00)) {PORTA=SPDR; _delay_ms(1000);}//выводим байт на PORTA
}

}*/

/*
char spi_SPIF(void){ //Флаг прерывания от SPI
	return SPIF;
}

char spi_WCOL(void){//Флаг конфликта записи SPI
	return WCOL;
}
*/


//Отправить комманду.
void SPI_CMD_otpravit(char data0) // ЭТО ОТПРАВИТЬ ВЕРХНЮЮ КОММАНДУ 1 БИТ(8байт).
{
PIN_DC_0_cmd;
PIN_CS_0;
spi_SPDR_otpravit(data0);
PIN_CS_1;
	//if (spi_SPDR_otpravit(data) > 0b00000000)  {return 0b11111111;} else {return 0b00000000;}
}

//Отправить данные
void SPI_DATA_otpravit(char data1) // "ЭТО ОТПРАВКА ПАРАМЕТРОВ из может быть несколько"
//Также ты можешь и передавать после отправки комманды.
{
PIN_DC_1_data;
PIN_CS_0;
spi_SPDR_otpravit(data1);
PIN_CS_1;
	//if (spi_SPDR_otpravit(data) > 0b00000000) {return 0b11111111;} else {return 0b00000000;}
}


//uint8_t тип другой.
// Инициализация
void ili9341_init(void)
{
     
  PIN_CS_1;
     
  // сброс дисплея
  PIN_RST_1;
  
  SPI_CMD_otpravit(0x01); //ILI9341_RESET);
    /*приводит к программному сбросу. Она возвращает команды и параметры их S/W Reset значения по умолчанию.
(См таблиц по умолчанию в каждом описании команды.)
Примечание: Содержание кадровой памяти не затрагиваются этой командой
Надо будет подождать  5msec  перед отправкой новой команды следующие программного
сброса. Дисплейный модуль загружает все дисплей поставщиком заводским значениям к
регистрам в течение этого 5msec. Если Software Reset применяется в режиме Sleep Out,
надо будет ждать 120msec перед отправкой Sleep out команды. Software Reset Command не
может быть отправлено во время выполнения последовательности Sleep Out .
Примечание мое. 1msec=0,001sec*/

  _delay_ms(100);
   

   /// настраиваем дисплей

  //Power control A (CBh)
  SPI_CMD_otpravit(0xCB); 
  // EXTC должен быть высоким, чтобы включить эту команду
  SPI_DATA_otpravit(0x39); //по умолчанию
  SPI_DATA_otpravit(0x2C); //по умолчанию
  SPI_DATA_otpravit(0x00); //по умолчанию
  SPI_DATA_otpravit(0x34); //по умолчанию Vcore 1,6V
  SPI_DATA_otpravit(0x02); //по умолчанию ddvdh 5,6V
 
  
  SPI_CMD_otpravit(0xCF); //Power control B (CFh)
  /*
  Параметр 2-й: управление мощностью [1: 0] Только установка
управления мощностью [1:0] = 11, уровень напряжения VGH и VGL приведены в табл.
bit[5]: DRV_ena : Для VCOM ведущее улучшение возможности, DRV_ena = 1: Включите, и наоборот
bit[6]: PCEQ: PC и EQ операция для экономии электроэнергии 
0:disable эта функция 
1:enable эта функция

rd параметр: значение по умолчанию: 30h
bit[2:0]: DRV_vmh[2:0] 3’b000 корректируются по ширине диска для VMH(000: 1 op_clk ~111: 8 op_clk)
bit[3]: DRV_vml[0] 1’b0
bit[4]: DC_ena: Разряд путь включения. Включите высоко для защиты ESD, 1: включено и наоборот
bit[7:6] : DRV_vml[2:1] 2’b00
EXTC должен быть высоким, чтобы включить эту команду*/

  SPI_DATA_otpravit(0x00); //по умолчанию
  SPI_DATA_otpravit(0xC1); //0b11000001  DRV_ena : Для VCOM=0 ведущее улучшение возможности выкл/экономии электроэнергии вкл / 
  SPI_DATA_otpravit(0x30); //по умолчанию   ESD=1: вкл для защиты
  
  SPI_CMD_otpravit(0xE8); //Driver timing control A (E8h)
  SPI_DATA_otpravit(0x85); 
  /*
  1 parameter : gate управление синхронизацией неперекрытия драйвера.
  1:default + 1unit
  */
  SPI_DATA_otpravit(0x00);
  /*
  2 parameter : EQ timing control
0: default – 1unit

parameter : CR timing control
0: default – 1unit
  */
  
  SPI_DATA_otpravit(0x78);
/*
3 parameter : управление синхронизацией перед обвинением
00:default – 2unit
*/
  
  SPI_CMD_otpravit(0xEA);//Driver timing control B (EAh)
// 1 parameter:gate управление синхронизацией драйвера
  
  SPI_DATA_otpravit(0x00);
/*VG_SW_T1[1:0]:EQ to GND   00: 0 unit
  VG_SW_T2[1:0]:EQ to DDVDH 00: 0 unit
  VG_SW_T3[1:0]:EQ to DDVDH 00: 0 unit
  VG_SW_T4[1:0]:EQ to GND   00: 0 unit */
  SPI_DATA_otpravit(0x00); //по умолчанию

  
  SPI_CMD_otpravit(0xED); //Power on sequence control (EDh)
/*
кадры
1кадр и 3кадра
1кадр и 4кадра
2кадра и 3кадра

Ограничение EXTC должен быть высоким, чтобы включить эту команду
*/
  SPI_DATA_otpravit(0x64); //0b01(CP1 soft start =10) 01(CP23 soft start =00) 0b01100100
  /*1 st parameter:soft start control
00:soft start keep 3 frame
01:soft start keep 2 frame
10:soft start keep 1 frame
11:disable*/

  SPI_DATA_otpravit(0x03); //0b00000011
  SPI_DATA_otpravit(0x12); //0b00010010
/*
2nd/ 3rd parameter:включите управление последовательностью
00:1st frame enable
01:2nd frame enable
10:3rd frame enable
11:4th frame enable
*/
  SPI_DATA_otpravit(0x81); // 0b10000001
  /*
  4th parameter:DDVDH улучшите режим (только для 8 внешних конденсаторов)
1: enable
  */
  
  
  SPI_CMD_otpravit(0xF7);  //Pump ratio control (F7h)
  //EXTC должен быть высоким, чтобы включить эту команду
  SPI_DATA_otpravit(0x20); //0b00100000
  /*1 st parameter:ratio control
10:DDVDH=2xVCI*/
  
  
  SPI_CMD_otpravit(0xC0); //Power Control 1 (C0h) 
  /*VRH [5:0]: Установите уровень GVDD, который является контрольным уровнем для
уровня VCOM и полутонового уровня напряжения.*/
  SPI_DATA_otpravit(0x23); // 0b00100011  4.6V (5v это 0b00101011=0x2B) см табл.
  /*Примечание1: Удостоверьтесь что VC и VRH урегулирование ограничения: GVDD (DDVDH -  ?
0.2) V.*/
  
  SPI_CMD_otpravit(0xC1); //Power Control 2 (C1h)
  SPI_DATA_otpravit(0x10); // по умолчанию 0b00010(000)
  /*
  BT [2:0]: Устанавливает фактор, используемый в схемах повышения.
Выберите оптимальный фактор повышения для рабочего напряжения. Чтобы уменьшить
потребляемую мощность, установите меньший фактор.
BT [2:0]  = 000  DDVDH=VCIx2    VGH=VCIx7    VGL=-VCIx4   

Примечание 
1: Удостоверьтесь что DDVDH урегулирование ограничения: DDVDH ? 5.8 В. 
2: Удостоверьтесь что VGH и VGL урегулирование ограничения: VGH-VGL ? 28 В

EXTC должен быть высоким, чтобы включить эту команду
  */
  
  
  
  SPI_CMD_otpravit(0xC5); //VCOM Control 1(C5h)
//EXTC должен быть высоким, чтобы включить эту команду
  //VMH [6:0] : Установите напряжение VCOMH.
  SPI_DATA_otpravit(0x3E); //0 VMH[6:0]  = 00111110 = 4.250V(VCOMH)
  //VML [6:0] : Установите напряжение VCOML.
  SPI_DATA_otpravit(0x28); //0 VML[6:0]  = 00101000 = -1.500V(VCOML)
  
  SPI_CMD_otpravit(0xC7); //VCOM Control 2(C7h)
  SPI_DATA_otpravit(0x86); //0b10000110  (nVM[7] VMF[6:0]) 
/*
nVM: nVM равняется “0” после включают сброс и VCOM смещение равняется значению MTP программы.
Когда набор nVM к “1”, урегулирование VMF [6:0] становится допустимым и VCOMH/VCOML может быть скорректирован.
VMF [6:0]: Установите Напряжение смещения VCOM.

VMF=0000110  VCOMH=VMH -58    VCOML = VML -58
*/  
  
  SPI_CMD_otpravit(0x36);//Memory Access Control (36h)
  /*Эта команда определяет направление сканирования чтения-записи памяти фрейма.
Эта команда не вносит изменения на другом состоянии драйвера..*/
  SPI_DATA_otpravit(0x48); //0b01001000

/*  Эти 3 бита управления MCU на к памяти записи-чтения направления.
7 MY Row Address Order  
6 MX Column Address Order
5 MV Row / Column Exchange (обрезка экрана выкл)
4 ML Vertical Refresh Order  LCD вертикаль обновляет управление направлением. (сверху вниз вкл)
3 BGR RGB-BGR Order  Цветное управление селектором (0=RGB панель цветового фильтра, 1=BGR панель цветового фильтра) (RGB вкл)
2 MH Horizontal Refresh ORDER  LCD горизонталь освежающее управление направлением.(слево на право вкл.)
[1:0]=00

Примечание: то, Когда BGR бит, изменено, новое урегулирование сразу активно без
обновления содержание в Памяти Фрейма снова.
X = Не заботиться.

*/

  SPI_CMD_otpravit(0x3A);// COLMOD: Pixel Format Set (3Ah)
  
  /*
  Это наборы команд пиксельный формат для RGB отображает данные, используемые
интерфейсом. DPI [2:0] является пиксельным выбором формата RGB
интерфейс и DBI [2:0] являются пиксельным форматом интерфейса MCU.
Если определенный интерфейс, или интерфейс RGB или интерфейс MCU,
не используемый тогда соответствующие биты в параметре проигнорированы.
Пиксельный формат показан в таблице ниже.

Если использование Интерфейса RGB должно последовательный интерфейс выбора.
X = Не заботиться
  */
  SPI_DATA_otpravit(0x55); //0b01010101   0b0(101)0(101)   0b0(DPI[2:0])0(DBI[2:0])
/*
DPI 16 bits / pixel  
DBI 16 bits / pixel  
*/  


  SPI_CMD_otpravit(0xB1); //Frame Rate Control (In Normal Mode/Full Colors) (B1h)
  /* их 3 вида
  Frame Rate Control (In Normal Mode/Full Colors) (B1h)
  Frame Rate Control (In Idle Mode/8 colors) (B2h)
  Frame Rate control (In Partial Mode/Full Colors) (B3h)
 
 Формула, чтобы вычислить кадровую частоту:
Frame Rate= ( fosc )/(Clocks per line x Division ratio x (Lines + VBP + VFP) )
Устанавливает отношение подразделения для внутренних часов Normal режима в
интерфейсе MCU.
fosc: внутренняя частота осциллятора
Часы за строку:RTNA настройки
Отношение подразделения: DIVA настройки.
Строки: общий ведущий номер строки
VBP: номер строки задней porch
VFP: передний номер строки porch

 */
  
  SPI_DATA_otpravit(0x00); // 0b00000000  0b000000(00) 0b000000(DIVA[1:0])  = fosc (без предделителя)
  SPI_DATA_otpravit(0x18); //0b00011000     0b000(11000)  000(RTNA[0:4])  установл 79Hz  
  //  70Hz Default = 0b00011011
  
  
  SPI_CMD_otpravit(0xB6);//Display Function Control (B6h)
  //EXTC должен быть высоким, чтобы включить эту команду.
  SPI_DATA_otpravit(0x08);  //0b00001000   0b0000(10)(00)    0b0000(PTG[1:0])(PT[1:0]) 
  /*
  PTG [1:0]: Установите режим сканирования в области недисплея.
  Выводы логического элемента в области недисплея = Сканирование интервала
  Исходные выводы в области недисплея = Набор с PT [2:0] биты
  Вывод VCOM пусто.
  PT [1:0]: Определите вывод источник /VCOM в области недисплея в partial режиме отображения.
  Источник Вывод на области недисплея Положительная полярность = V63  
  Источник Вывод на области недисплея Отрицательная полярность = V0  
  Вывод VCOM на область недисплея Положительная полярность = VCOML
  Вывод VCOM на область недисплея Отрицательная полярность =VCOMH
  */
  SPI_DATA_otpravit(0x82);  //0b10000010   0b(1)(0)(0)(0)(0010)    0b(REV)(GS)(SS)(SM)(ISC[3:0])
  
  /*
  
  REV: Выберите, является ли жидкокристаллический тип обычно белым типом или
Нормальный черный тип .
Жидкокристаллический тип 
= 0 Нормальный белый
= 1 Нормальный черный

GS: Устанавливает направление сканирования драйвером логического элемента в
диапазоне, определенном SCN [4:0] и NL [4:0].
Направление сканирования определяется GS = 0 может быть отменено установкой GS = 1.
Gate Output Scan Direction
Пропустите выходное направление сканирования
=0 это G1 -> G320
=1 это G320 -> G1

  SS: Выберите направление сдвига выводов от исходного драйвера.
SS Исходное выходное направление сканирования =0 т.е S1 -> S720
В дополнение к направлению сдвига параметры настройки и для SS и для битов BGR
требуются, чтобы изменять присвоение R, G, и точки B к исходным контактам драйвера.
Чтобы присвоить R, G, B точки к исходным контактам драйвера от S1 до S720,
устанавливают SS = 0.
Чтобы присвоить R, G, B точки к исходным контактам драйвера от S720 до S1,
устанавливают SS = 1.


SM: Устанавливает расположение контакта драйвера логического элемента в сочетании с
битом GS выбирать оптимальный режим сканирования для модуля.

SM=0 GS=0 
Scan Direction
Направление сканирования
сверху вниз
G2 to G320
G1 to G318

Gate Output Sequence
Пропустите выходную
последовательность
G1 -> G2 -> G3 -> G4 ………………… G317 -> G318 -> G319 -> G320

ISC [3:0]: Определите интервал цикла сканирования драйвера логического элемента в
области недисплея когда PTG [1:0] =” 10”, чтобы выбрать сканирование интервала.
Тогда цикл сканирования установлен как нечетное число с 0~29 периодов фрейма.
Полярность инвертирована каждый цикл сканирования.

0010 (ISC [3:0]  )
5frame (Цикл сканирования ) 
85 ms(fFLM = 60Hz)

  */
  
  
  SPI_DATA_otpravit(0x27);  //0b00100111   0b00(100111)    0b00(NL[5:0])
  
  /*
  NL [5:0]: Определяет номер строк, чтобы управлять жидкокристаллическим дисплеем в
интервале 8 строк. Отображение GRAM адресов не затронуто числом строк,
установленных NL [5:0]. Число строк должно быть тем же или больше, чем число
необходимых строк для размера жидкокристаллической панели.

NL [5:0] = 100111 это 320 строк


  */
  
  /*PCDIV [5:0]: Которого нет  external fosc= (DOTCLK) /(2x (PCDIV+1))*/
  
  SPI_CMD_otpravit(0xF2);//Enable 3G (F2h) 
  /*
  1 st Parameter: Enable 3 гамма управления
3G_enb high для 3 гамма управления enable
Ограничение EXTC должен быть высоким, чтобы включить эту команду
  */
  SPI_DATA_otpravit(0x00); // 3GAMMA_EN выкл.
  
  
  
  SPI_CMD_otpravit(0x2A); //Column Address Set (2Ah)
  /*
  Эта команда используется, чтобы определить область столбца памяти фрейма Frame
Memory , где MCU может получить доступ.
Эта команда не вносит изменения на другом состоянии драйвера.
Значения SC [15:0] и EC [15:0] отнесены, когда команда RAMWR прибывает.
Каждое значение представляет строку на один столбец в Памяти Фрейма
  
  
  SC [15:0] всегда должен быть равен или меньше, чем EC [15:0].
Отметьте 1: Когда SC [15:0] или EC [15:0] будет больше, чем 00EFh (Когда MADCTL's B5
= 0) или 013Fh (Когда MADCTL's B5 = 1), данные из диапазона будут проигнорированы.

*/
  SPI_DATA_otpravit(0x00);//(SC15 SC14 SC13 SC12 SC11 SC10 SC9 SC8)
  SPI_DATA_otpravit(0x00);//(SC7 SC6 SC5 SC4 SC3 SC2 SC1 SC0)
  SPI_DATA_otpravit(0x00);//(EC15 EC14 EC13 EC12 EC11 EC10 EC9 EC8)
  SPI_DATA_otpravit(0xEF);// 0b11101111 (EC7 EC6 EC5 EC4 EC3 EC2 EC1 EC0)
  
  SPI_CMD_otpravit(0x2B);//Page Address Set (2Bh)
  /*
  Эта команда используется для определения области строк Frame Memory памяти кадров,
где MCU может получить доступ. Эта команда не делает никаких изменений на другой
статус драйвера. Значения SP [15: 0] и EP [15: 0] называются, когда команда RAMWR
приходит. Каждое значение представляет собой одну строку страницы в памяти кадров.

SP [15:0] всегда должен быть равен или меньше, чем EP [15:0]
Отметьте 1: Когда SP [15:0] или EP [15:0] больше, чем 013Fh (Когда MADCTL's B5 = 0)
или 00EFh (Когда MADCTL's B5 = 1), данные из диапазона будут проигнорированы.

  */
  SPI_DATA_otpravit(0x00); //(SP15 SP14 SP13 SP12 SP11 SP10 SP9 SP8 )
  SPI_DATA_otpravit(0x00); //(SP7 SP6 SP5 SP4 SP3 SP2 SP1 SP0)
  SPI_DATA_otpravit(0x01); //(EP15 EP14 EP13 EP12 EP11 EP10 EP9 EP8)
  SPI_DATA_otpravit(0x3F); // 0b00111111 (EP7 EP6 EP5 EP4 EP3 EP2 EP1 EP0)
  
  SPI_CMD_otpravit(0x26);//Gamma Set (26h)
  SPI_DATA_otpravit(0x01); // По умолчанию. других вариантов нет
  
  SPI_CMD_otpravit(0xE0);// Positive Gamma Correction (E0h)
  //Установите полутоновое напряжение корректировать гамма характеристики панели TFT.  EXTC должен быть высоким, чтобы включить эту команду
  SPI_DATA_otpravit(0x0F); // 0b00001111  0b0000(1111) 0b0000(VP63[3:0])
  SPI_DATA_otpravit(0x31); // 0b00110001  0b00(110001) 0b00(VP62 [5:0])
  SPI_DATA_otpravit(0x2B); // 0b00101011  0b00(101011) 0b00(VP61 [5:0])
  SPI_DATA_otpravit(0x0C); // 0b00001100  0b0000(1100) 0b0000(VP59 [3:0])
  SPI_DATA_otpravit(0x0E); // 0b00001110 0b000(01110) 0b000(VP57 [4:0])
  SPI_DATA_otpravit(0x08); // 0b00001000 0b0000(1000) 0b0000(VP50 [3:0])
  SPI_DATA_otpravit(0x4E); // 0b01001110 0b0(1001110) 0b0(VP43 [6:0])
  SPI_DATA_otpravit(0xF1); // 0b11110001 0b(1111)(0001) 0b(VP27 [3:0])(VP36 [3:0])
  SPI_DATA_otpravit(0x37); // 0b00110111 0b0(0110111) 0b0(VP20 [6:0])
  SPI_DATA_otpravit(0x07); // 0b00000111 0b0000(0111) 0b0000(VP13 [3:0])
  SPI_DATA_otpravit(0x10); // 0b00010000 0b000(10000) 0b000(VP6 [4:0])
  SPI_DATA_otpravit(0x03); // 0b00000011 0b0000(0011) 0b0000(VP4 [3:0])
  SPI_DATA_otpravit(0x0E); // 0b00001110 0b00(001110) 0b00(VP2 [5:0])
  SPI_DATA_otpravit(0x09); // 0b00001001 0b00(001001) 0b00(VP1 [5:0])
  SPI_DATA_otpravit(0x00); // 0b00000000 0b0000(0000) 0b0000(VP0 [3:0])
  
  SPI_CMD_otpravit(0xE1);//Negative Gamma Correction (E1h)
 //Установите шкалы серого напряжения для регулировки гамма-характеристики панели TFT. EXTC должен быть высоким, чтобы включить эту команду
  SPI_DATA_otpravit(0x00); //0b00000000 0b0000(0000) 0b0000(VN63 [3:0])
  SPI_DATA_otpravit(0x0E); //0b00001110 0b00(001110) 0b00(VN62 [5:0])
  SPI_DATA_otpravit(0x14); //0b00010100 0b00(010100) 0b00(VN61 [5:0])
  SPI_DATA_otpravit(0x03); //0b00000011 0b0000(0011) 0b0000(VN59 [3:0])
  SPI_DATA_otpravit(0x11); //0b00010001 0b000(10001) 0b000(VN57 [4:0])
  SPI_DATA_otpravit(0x07); //0b00000111 0b0000(0111) 0b0000(VN50 [3:0])
  SPI_DATA_otpravit(0x31); //0b00110001 0b0(0110001) 0b0(VN43 [6:0])
  SPI_DATA_otpravit(0xC1); //0b11000001 0b(1100)(0001) 0b(VN27 [3:0])(VN36 [3:0])
  SPI_DATA_otpravit(0x48); //0b01001000 0b0(1001000) 0b0(VN20 [6:0])
  SPI_DATA_otpravit(0x08); //0b00001000 0b0000(1000) 0b0000(10VN13 [3:0]  00)
  SPI_DATA_otpravit(0x0F); //0b00001111 0b000(01111) 0b000(VN6 [4:0])
  SPI_DATA_otpravit(0x0C); //0b00001100 0b0000(1100) 0b0000(VN4 [3:0])
  SPI_DATA_otpravit(0x31); //0b00110001 0b00(110001) 0b00(VN2 [5:0])
  SPI_DATA_otpravit(0x36); //0b00110110 0b00(110110) 0b00(VN1 [5:0])
  SPI_DATA_otpravit(0x0F); //0b00001111 0b0000(1111) 0b0000(VN0 [3:0])
  
  SPI_CMD_otpravit(0x11);//Sleep Out (11h)
  /*
  Эта команда заставляет LCD модуль вводить минимальный режим потребляемой
мощности. В этом режиме, например, преобразователе DC/DC остановлен, Внутренний
осциллятор остановлен, и сканирование панели остановлено.
Интерфейс MCU и память все еще работают, и память сохраняет свое содержание.
X = Не заботиться
Ограничение Эта команда не имеет никакого эффекта, когда модуль уже находится в режиме Sleep In.
Sleep In режим может только оставить сон (Sleep Out) команда (11h) . Будет необходимо
ожидать 5msec прежде, чем отправить следующий за командой, это должно позволить
время для поставки напряжения и схемы часов, чтобы стабилизироваться.
Будет необходимо ожидать 120msec после передающей команды Sleep Out (когда во Sleep
In режиме), прежде чем команда Sleep In может быть отправлена.
  */
   
   _delay_ms(100);
  SPI_CMD_otpravit(0x29);//Display ON (29h)
  /*
  Эта команда используется, чтобы восстановиться с режима DISPLAY OFF. Вывод от
Frame Memory включена.
Эта команда не вносит изменения содержания памяти фрейма.
Эта команда не изменяет никакое другое состояние
  */


  SPI_CMD_otpravit(0x2C); //Memory Write (2Ch)
  //ILI9341_GRAM - это команда Memory Write (2Ch)
}	
	
void LCD_SetCursorPosition(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
    SPI_CMD_otpravit(0x2A); //Column Address Set (2Ah)
    SPI_DATA_otpravit(x1 >> 8);
    SPI_DATA_otpravit(x1 & 0xFF);
    SPI_DATA_otpravit(x2 >> 8);
    SPI_DATA_otpravit(x2 & 0xFF);
 
    SPI_CMD_otpravit(0x2B); //Page Address Set (2Bh)
    SPI_DATA_otpravit(y1 >> 8);
    SPI_DATA_otpravit(y1 & 0xFF);
    SPI_DATA_otpravit(y2 >> 8);
    SPI_DATA_otpravit(y2 & 0xFF);
}

void LCD_DrawPixel(uint16_t x, uint16_t y, uint16_t color) {
    LCD_SetCursorPosition(x, y, x, y);
    SPI_CMD_otpravit(0x2C); //Memory Write (2Ch)
    SPI_DATA_otpravit(color >> 8);
    SPI_DATA_otpravit(color & 0xFF);
}

void LCD_Fill(uint16_t color) {
unsigned int n, i, j;
i = color >> 8;
j = color & 0xFF;
LCD_SetCursorPosition(0, 0, 240 - 1, 320 - 1);

SPI_CMD_otpravit(0x2C);

for (n = 0; n < 38400; n++) {
SPI_DATA_otpravit(i);
SPI_DATA_otpravit(j);
}
}


/*void LCD_Image(unsigned char const *img) {
        uint32_t n;
         
    LCD_SetCursorPosition(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1);
 
    SPI_CMD_otpravit(ILI9341_GRAM);
 
    for (n = 0; n < LCD_PIXEL_COUNT; n++) {
                u8 color = *img;
                img++;
        SPI_DATA_otpravit(*img);
        SPI_DATA_otpravit(color);
                img++;
    }
}*/






