TFT индикатор на ILI9341

ILI9341 микросхема с многими интерфейсами, но меня интересовал последовательный SPI ввиду меньшего числа проводов. Взял на пробу 2.2 Inch SPI TFT LCD Serial Port Module Display ILI9341. В качестве бонуса модуль оснащен SD слотом.



Намучался с ним предостаточно. Сперва пытался запустить на Ардуине, но как понял из чтения форумов, проблема в преобразователе уровней, которого у меня нет. Модулю нужны уровни 3.3 вольта. Потом возился с STM32 и пока не запитал плату от 3.3 вольт, не было мне счастья. Только надо закоротить перемычку J1 на плате модуля (модуль при этом питается от 5 вольт и на плате стоит стабилизатор). Ну вы поняли — хотим уровней 3.3 вольта, но плату надо питать от 5. Может в этом есть логика, но я не очень понял ее.



К сожалению, все работает в режиме ногодрыга. Запустить SPI пока не получилось. Может добрые люди посмотрят исходники и скажут в чем ошибка.


К второму SPI подключен nRF24L01, но о нем в другой раз ))

Сединения проводов
#define TFT_PORT	GPIOA

#define PIN_LED		GPIO_Pin_1
#define PIN_RST		GPIO_Pin_2
#define PIN_DC		GPIO_Pin_3
#define PIN_CS		GPIO_Pin_0
#define PIN_SCK		GPIO_Pin_5
#define PIN_MISO	GPIO_Pin_6
#define PIN_MOSI	GPIO_Pin_7


Из функций рисования релизована только setPixel, но остальное можно легко посмотреть в многочисленных библиотеках схожей тематики. Я лишь ставил целью запустить модуль. Написано по мотивам Ардуинской библиотеки TFTv2

Даташит на ILI9341.

Проект для Coocox.

upd: shilow прикрутил к моей библиотеке аппартатный SPI, а также попытался прикрутить ILI9341 к ChibiOS/RT + µGFX. См. файлы coocox-coocox-ili9341-hard.zip и stm32vld-ChibiOS-ili9341.zip
  • +1
  • 03 января 2014, 17:40
  • aliaksei
  • 2
Файлы в топике: tft-test.zip, coocox-ili9341-hard.zip

Комментарии (34)

RSS свернуть / развернуть
Ну вы поняли — хотим уровней 3.3 вольта, но плату надо питать от 5. Может в этом есть логика, но я не очень понял ее.
Это совсем не редкость. Первое что вспоминается — USB.
+1
Когда же меня посетит муза, и я наконец-то напишу эту статью
0
Еще была бы интересна тема легковесного UI. Может и у самого руки дойдут как-нибудь. ))
0
Совпадение, только сегодня с почты забрал, три месяца шёл.
0
У меня наоборот новый рекорд — 16 дней. Брал Здесь. Для проверки вывел цветные полосы и иконки без использования библиотек. Неплохие дисплейчики, отличные углы и яркие цвета.
0
Мне тоже до этого быстро приходили, а тут зависло чета. Я тоже не ебэе покупал.
0
Во блин и я такой на прошлой неделе с почты забрал
0
  • avatar
  • ZiB
  • 04 января 2014, 07:00
Недавно запустил такой же с 32 мегой. Интересный дисплейчик.
0
На какой частоте SPI работает?
у меня на STM32VLDiscovery заработал только с делителем 32 — частота SPI 0.75 MHz, на большей частотет отказывается.

может кто что посоветует?
0
У меня работает с EK-LM4F120XL на 12МГц без проблем.
0
C STM32F3discovery работает на 18МГц от SPI2
0
Кстати, у меня похожий модуль, только 1.8 дюйма, уровни 5В хавает без проблем. Если интересно-моя статья
we.easyelectronics.ru/lcd_gfx/podklyuchenie-tft-displeya-k-avr.html
0
Подключил к М3 и к М4. На М3 все супер, на М4 изображение зеркальное. Постоянно!!! Очистка экрана при старте начинается где то по середине, и причем с начало думал зависит от дисплея, ничего подобного. На разных Cortax по разному. В чем может быть проблема?! Датыш пытаюсь осилить
0
  • avatar
  • Geek
  • 10 марта 2014, 13:43
Отвечаю на вопрос автора статьи
К сожалению, все работает в режиме ногодрыга. Запустить SPI пока не получилось. Может добрые люди посмотрят исходники и скажут в чем ошибка.
Вы неправильно инициализировали ноги проца для работы SPI, там нужна ещё одна команда типа
// Configure peripheral I/O remapping
GPIO_PinRemapConfig ( GPIO_Remap_SPI3, ENABLE );

Короче, читайте ДШ, товарищи, и будет Вам счастье!
Только заливка всё равно тормозная. Ещё не смотрел…
+1
Охжешь… Спасибо, добрый человек. ))
0
Запустил данный дисплей на STM32 + ChibiOS + uGFX.
Выкладывать нужно?
0
Выкладывй, хуже не будет )
0
Запустил аппаратный SPI


#include "main.h"
#include "mcu_ini.h"

#define TFT_PORT	GPIOA
#define TFT_SPI		SPI1

#define PIN_LED		GPIO_Pin_1
#define PIN_RST		GPIO_Pin_2
#define PIN_DC		GPIO_Pin_3
#define PIN_CS		GPIO_Pin_0
#define PIN_SCK		GPIO_Pin_5
#define PIN_MISO	GPIO_Pin_6
#define PIN_MOSI	GPIO_Pin_7

// Colors
#define RED			0xf800
#define GREEN		0x07e0
#define BLUE		0x001f
#define BLACK		0x0000
#define YELLOW		0xffe0
#define WHITE		0xffff
#define CYAN		0x07ff
#define BRIGHT_RED	0xf810
#define GRAY1		0x8410
#define GRAY2		0x4208

#define TFT_CS_LOW		GPIO_ResetBits(TFT_PORT, PIN_CS);
#define TFT_CS_HIGH		GPIO_SetBits(TFT_PORT, PIN_CS);
#define TFT_DC_LOW		GPIO_ResetBits(TFT_PORT, PIN_DC);
#define TFT_DC_HIGH		GPIO_SetBits(TFT_PORT, PIN_DC);
#define TFT_RST_LOW		GPIO_ResetBits(TFT_PORT, PIN_RST);
#define TFT_RST_HIGH	GPIO_SetBits(TFT_PORT, PIN_RST);

	int i, j;


void TFT_sendByte(uint8_t data)
{
   while(SPI_I2S_GetFlagStatus(TFT_SPI, SPI_I2S_FLAG_TXE)==RESET);
	 SPI_I2S_SendData(TFT_SPI, data);
}

void TFT_sendCMD(int index)
{
	while(SPI_I2S_GetFlagStatus(TFT_SPI, SPI_I2S_FLAG_BSY) == SET);
    TFT_CS_HIGH;
    TFT_DC_LOW;
    TFT_CS_LOW;
    TFT_sendByte(index);
	  _delay_us(50);
}

void TFT_sendDATA(int data)
{
	while(SPI_I2S_GetFlagStatus(TFT_SPI, SPI_I2S_FLAG_BSY) == SET);
    TFT_DC_HIGH;
    TFT_sendByte(data);
}

void TFT_sendWord(int data)
{
	while(SPI_I2S_GetFlagStatus(TFT_SPI, SPI_I2S_FLAG_BSY) == SET);
    TFT_DC_HIGH;

    TFT_sendByte(data >> 8);
    TFT_sendByte(data & 0x00ff);
}

int TFT_Read_Register(int Addr, int xParameter)
{
	int data = 0;

    TFT_sendCMD(0xD9);                                                    // ext command
    TFT_sendByte(0x10+xParameter);                         // 0x11 is the first Parameter
    TFT_DC_LOW;
    TFT_CS_LOW;
    TFT_sendByte(Addr);
    TFT_DC_HIGH;
    data = SPI_I2S_ReceiveData(TFT_SPI);
    TFT_CS_HIGH;

    return data;
}

int TFT_readID(void)
{
	int i = 0;
	int byte;
	int data[3] = {0x00, 0x00, 0x00};
	int ID[3] = {0x00, 0x93, 0x41};
	int ToF = 1;

	for(i=0; i<3; i++)
    {
		byte = TFT_Read_Register(0xD3, i+1);
        data[i] = byte;

        if(data[i] != ID[i])
        {
            ToF = 0;
        }
    }

    return ToF;
}

void TFT_init()
{

	GPIO_InitTypeDef gpio;
	SPI_InitTypeDef spi;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

	gpio.GPIO_Pin = PIN_LED | PIN_DC | PIN_RST | PIN_CS;
	gpio.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
	gpio.GPIO_Mode = GPIO_Mode_OUT;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	gpio.GPIO_OType = GPIO_OType_PP;//podt'agivanie k zemle
	gpio.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(TFT_PORT, &gpio);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

	gpio.GPIO_Pin = PIN_SCK | PIN_MOSI|PIN_MISO;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	gpio.GPIO_Mode = GPIO_Mode_AF;
  GPIO_Init(TFT_PORT, &gpio);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1  );//remap
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1  );
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1  );

    //SPI_StructInit(&spi);

	spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	spi.SPI_Mode = SPI_Mode_Master;
	spi.SPI_DataSize = SPI_DataSize_8b;
	spi.SPI_CPOL = SPI_CPOL_Low;
	spi.SPI_CPHA = SPI_CPHA_1Edge;
	spi.SPI_NSS = SPI_NSS_Soft;
	spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 ;
	spi.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_Init(TFT_SPI, &spi);
	SPI_Cmd(TFT_SPI, ENABLE);
	SPI_NSSInternalSoftwareConfig(SPI1, SPI_NSSInternalSoft_Set);

	TFT_RST_LOW;

	TFT_RST_HIGH;

    TFT_sendCMD(0xCB);
	TFT_sendDATA(0x39);
	TFT_sendDATA(0x2C);
	TFT_sendDATA(0x00);
	TFT_sendDATA(0x34);
	TFT_sendDATA(0x02);

	TFT_sendCMD(0xCF);
	TFT_sendDATA(0x00);
	TFT_sendDATA(0xC1);
	TFT_sendDATA(0x30);

	TFT_sendCMD(0xE8);
	TFT_sendDATA(0x85);
	TFT_sendDATA(0x00);
	TFT_sendDATA(0x78);

	TFT_sendCMD(0xEA);
	TFT_sendDATA(0x00);
	TFT_sendDATA(0x00);

	TFT_sendCMD(0xED);
	TFT_sendDATA(0x64);
	TFT_sendDATA(0x03);
	TFT_sendDATA(0x12);
	TFT_sendDATA(0x81);

	TFT_sendCMD(0xF7);
	TFT_sendDATA(0x20);

	TFT_sendCMD(0xC0);    	//Power control
	TFT_sendDATA(0x23);  	//VRH[5:0]

	TFT_sendCMD(0xC1);    	//Power control
	TFT_sendDATA(0x10);  	//SAP[2:0];BT[3:0]

	TFT_sendCMD(0xC5);   	//VCM control
	TFT_sendDATA(0x3e);  	//Contrast
	TFT_sendDATA(0x28);

	TFT_sendCMD(0xC7);    	//VCM control2
	TFT_sendDATA(0x86);   	 //--

	TFT_sendCMD(0x36);    	// Memory Access Control
	TFT_sendDATA(0x48);   	//C8	   //48 68?»”? §??†//28 E8 ?¦???„??†

	TFT_sendCMD(0x3A); 
	TFT_sendDATA(0x55); 

	TFT_sendCMD(0xB1); 
	TFT_sendDATA(0x00); 
	TFT_sendDATA(0x18); 

	TFT_sendCMD(0xB6);    	// Display Function Control
	TFT_sendDATA(0x08); 
	TFT_sendDATA(0x82); 
	TFT_sendDATA(0x27); 

	TFT_sendCMD(0xF2);    	// 3Gamma Function Disable
	TFT_sendDATA(0x00); 

	TFT_sendCMD(0x26);    	//Gamma curve selected
	TFT_sendDATA(0x01);  

	TFT_sendCMD(0xE0);    	//Set Gamma
	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_sendCMD(0xE1);    	//Set Gamma
	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_sendCMD(0x11);    	//Exit Sleep
	TFT_sendCMD(0x29);    //Display on
	TFT_sendCMD(0x2c); 
}

void TFT_led(int state)
{
	if (state)
		GPIO_WriteBit(TFT_PORT, PIN_LED, Bit_SET);
	else
		GPIO_WriteBit(TFT_PORT, PIN_LED, Bit_RESET);
}

void TFT_setCol(int StartCol, int EndCol)
{
	TFT_sendCMD(0x2A);                                                     // Column Command address
	TFT_sendWord(StartCol);
	TFT_sendWord(EndCol);
}

void TFT_setPage(int StartPage, int EndPage)
{
	TFT_sendCMD(0x2B);                                                  // Column Command address
	TFT_sendWord(StartPage);
	TFT_sendWord(EndPage);
}

void TFT_setXY(int poX, int poY)
{
	TFT_setCol(poX, poX);
	TFT_setPage(poY, poY);
	TFT_sendCMD(0x2c);
}

void TFT_setPixel(int poX, int poY, int color)
{
	TFT_setXY(poX, poY);
	TFT_sendWord(color);
}


void fillScreen(void)
{
    TFT_setCol(0, 239);
    TFT_setPage(0, 319);
    TFT_sendCMD(0x2c);                                                  /* start to write to display ra */
                                                                        /* m                            */

    TFT_DC_HIGH;
    TFT_CS_LOW;
    for(i=0; i<38400; i++)
    {
       TFT_sendByte(0);
        TFT_sendByte(0);
       TFT_sendByte(0);
        TFT_sendByte(0);
    }
    TFT_CS_HIGH;
}
int main(void)
{


	unsigned int pix=76799;
	unsigned int collor=0x07e0;
	int i, j;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	TFT_led(1);
	TFT_init();


	TFT_setPixel(10, 10, BLUE);

	fillScreen();
	
	for(i=0; i<100; i++) {
		TFT_setPixel(i, 50, RED);
		TFT_setPixel(i, 51, RED);

		TFT_setPixel(50, i, GREEN);
		TFT_setPixel(51, i, GREEN);
	}

	for(i=50; i<200; i++) {
		for(j=50; j<200; j++) {
			TFT_setPixel(i, j, BLUE);
		}
	}
}


Простите, не знаю как прикрепить код файлом.
0
Нормально — никак, только если новый пост писать, а не комментарий.
0
кто как управляет подсветкой? проблема в том что на плате только 3.3 вольта и подсветка 3.3, p-канальный полевой транзюк?
0
На биполярном транзисторе в насыщении не так уж много падает, есть модели с падением в 0.1В (FMMT617, например).
0
хороша штука, попробую.
0
попробовал сабж, падение 0,6V хоть тресни
0
напряжение хотите регулировать, или ток?
и как, с потенциометра, или еще чего?
0
ножка PA3(STM32) подключена к базе напрямую, коллектор к 3.3V, эмиттер к аноду подсветки.

причем странно, ток с ноги контроллера на базу транзистора 0.02ma(20 микроампер), если померить с ноги на землю то 50ma. четровщина, соединения вроди все в порядке.
0
разумно между базой и МК таки поставить резюк.
и я так и не понял, чего вы от транзистора хотите, игру в ШИМ? Сейчас у Вас повторитель, если МК выставит 3.3 вольта, на эмиттере будет 3.3В минус 0.6В. 2.7 Вольт светодиоду хватит.

Какой может быть ток между ногой и землей, Вы МК сожжете!

В совокупности, начните с 1К-10К резистора между МК и базой.
0
да по идее между базой нужен резюк, но тут на эмиттере висит светодиод, так что можно не париться ток превышен не будет, наоборот хватило бы.

про ножку на землю это я так эксперементирую, мк всегда терпит, там видимо защита есть.

подсветка в таком подключении светится, но где-то процентов на 60, маловато. мне бы 90, за то и бьюсь. резюки пробовал, ничего не изменилось.
0
для вкл-выкл можно придумать какой-нить BS170/2n7000, рейловый опер (потребление подсветки замерить в начале), 74hc логику. Логика рейловая, дает легко 20мА на элемент.

Сколько на базе транзистора? МК может и не дать 3.3В, значит Вы не получите 2.7В.
0
на базе 3.2V относительно земли и 0.6 относительно эмиттера.
0
я выше написал что думаю. а сколько подсветка ест? всякие bc847/2n3904 дают не такой уж и большой ток, мож транзистор помощнее, в TO-220?
0
ну какое то-220, 50ма всего подсветка, транзистор FMMT617
0
В ОК-то? Конечно 0.6, у него 0.1 в насыщении, а для этого в ОЭ включать надо. Соответственно, тебе нужен подобный, но PNP. FFMT617 я чисто как пример приводил.
P.S. А где ты его купил? Вроде не самый распространенный транзистор.
0
я облюбовал отличную контору у себя тут www.terraelectronica.ru/ быстро и многое есть.

>для этого в ОЭ включать надо
знаю конечно, но плата уже сделана на производстве, новую заказывать уже не хочется, а эту курочить рука не поднимается. я изначально планировал туда n-канальный полевик, по идее с чего бы ему не работать, но подсветка оказалась черезчур с большим падением, там светодиоды как минимум 3.2 стоят. новую уже закажу под p-канальный полевик, самое правильное решение.

а с FMMT617 я выиграл 0.1V соответственно светить стало заметноярче, там зависимость нелинейная как вовсех светодиодах.
0
а pnp даже искать не надо, FMMT717, его рекомендуют в доке на FMMT617
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.