Купил себе дисплейчик вот такой: 3.2 inch TFT LCD Module with Touch Panel ILI9341 Drive IC 240(RGB)*320 SPI Interface (9 IO) 240*320 Touch ic XPT2046 SPI port очень хочется заюзать Если кто нить запускал такой, поделитесь библой для CVAVR
Давайте сначала определимся, какие требования к библиотеке должны быть ? Поскольку работа с дисплеем делится на три части: 1. Физическая работа с дисплеем - это подключение дисплея к АВРке, отправка байта в дисплей, управление выводами CS, RS и RST 2. базовая работа с дисплеем (низкоуровневая графика) - включение/выключение, инициализация, спящий режим, определение области вывода, отправка данных в дисплей 3. Работа с графикой на более высоком уровне - процедуры рисования линии, прямоуголника, окружности, вывода текста
По большому счету - эти три части - это три разных уровня, которые не зависят друг от друга.
И Аппаратно-зависимый - только первый уровень, где описано физическое подключение дисплея к МК.
Я в свое время делал изделие с таким дисплеем, под него выписал первую и вторую части. Третья часть - графика - у меня была написана ранее.
Все написано на чистом С (файлы *.h, *.c) - поэтому не важно, по большому счету, в какой оболочкне писать - в Авр Студии, Атмел Студии или в ЦВАРе... Или в блокноте. для avr gcc не имеет разницы, где написан с-код.
Если вопрос еще актуален - напишите, что нужно - я выложу.
Добавлено after 21 minute 5 seconds: Re: Нужна библиотека для CVAVR ILI9341 3.2 inch TFT LCD module Единственное что - у меня дисплей с параллельным интерфейсом - соответственно, у меня 2 порта полностью заняты 16битной шиной данных. У вас SPI - вам проще подключать.
Если посчитать с какой скорость AVR сможет его обновлять, то не очень и странно.
У меня по параллельному интерфейсу заливка дисплея - кадров 4-5 в секунду при тестировании железа была. Мега32 16 мгц. Отрисовка всего дисплея (вывод текста, распаковка RLE-битмапов) - нуууу, навскидку менее секунды на всё.... У меня реализованы часики с календарем - на дисплее большие цифры времени и ниже календарь на месяц. И термометр в верхнем углу.
Но по СПИ будет медленнее.... Но увы, топикстартер уже купил СПИ-дисплей....
Подключение дисплея. Диспллей с SPI - последовательным интерфейсом.
SCK - тактирование, данные с линии SDA защелкиваются по нарастающему фронту SDA - Данные для записи в дисплей (биты передаются от старшего к младшему) RES(RST) - Сброс, активный уровень низкий RS(A0) - низкий уровень - команда, высокий уровень - данные CS - выбор дисплея (chip select), активный уровень низкий
SCK дисплея - к SCK контроллера SDA дисплея - к MOSI контроллера.
RES, RS, CS - к любым портам контроллера.
Инициализация железа. Спойлервсе 5 линий настраиваем на выход, на линии CS и RES выводим 1.
Так же настраиваем SPI на максимальную скорость: SPCR = 1<<SPE | 1<<MSTR | 0<<SPR1 | 0<<SPR0; SPSR |= (1<<SPI2X);
Теперь процедуры низкоуровневого общения с дисплеем. СпойлерУ нас 4 процедуры : процедура отправки байта по СПИ и три процедуры управления сигналами RST, RS, CS.
определение, куда у нас подключен выводы RST, RS и CS дисплея
Код:
#define LCD_RST_PORT B #define LCD_RST_BITVAL (1<<PORTB4) #define LCD_RS_PORT D #define LCD_RS_BITVAL (1<<PORTD5) #define LCD_CS_PORT D #define LCD_CS_BITVAL (1<<PORTD3)
и процедуры управления выводами этими:
Код:
// Управление битом RST - Сброс, активный уровень низкий void setResetPinILI9341(unsigned char resetLevel){ if (resetLevel) __OUTPORT(LCD_RST_PORT) |= LCD_RST_BITVAL; else __OUTPORT(LCD_RST_PORT) &= ~LCD_RST_BITVAL; }
// Управление битом RS(A0) - выбор данные/команда void setRsLevelILI9341(unsigned char rsLevel){ if (rsLevel) __OUTPORT(LCD_RS_PORT) |= LCD_RS_BITVAL; else __OUTPORT(LCD_RS_PORT) &= ~LCD_RS_BITVAL; }
// Управление битом CS - выбор дисплея void setСsLevelILI9341(unsigned char сsLevel){ if (сsLevel) __OUTPORT(LCD_СS_PORT) |= LCD_СS_BITVAL; else __OUTPORT(LCD_СS_PORT) &= ~LCD_СS_BITVAL; }
//---------- //-- Внешние процедуры физического общения с дисплеем ---------- //----------
// Управление пином сброса дисплея. extern void setResetPinILI9341(unsigned char resetLevel);
// Управление битом RS(A0) - выбор данные/команда extern void setRsLevelILI9341(unsigned char rsLevel);
// Отправка слова в дисплей // процедура должна прижать CS дисплея к 0, отправить слово в дисплей, // подождать окончания отправки данных и, по окончании отправки, отпустить CS extern void sendWordILI9341(unsigned int wordToSend);
//---------- //-- Основные процедуры работы с дисплеем ---------- //---------- // инициализация void initDisplayILI9341(void);
// спящий режим void sleepModeILI9341(unsigned char isSleep);
// аппаратная инверсия изображения void inversionModeILI9341(unsigned char isInversionOn);
// управление записью данных в видеопамять дисплея (регистр MADCTL). // параметр - комбинация флагов ILI9341_MADCTL_хх. // // направление записи данных в видеопамять - флаги ILI9341_MADCTL_MY, ILI9341_MADCTL_MX, ILI9341_MADCTL_MV // ILI9341_MADCTL_MX - X-mirror // ILI9341_MADCTL_MY - Y-mirror // ILI9341_MADCTL_MV - X-Y axis exchange (влияет на верхнюю границу RASET/CASET) // [MV:MX:MY] = 000, start left top, draw left to right, then top to bottom // [MV:MX:MY] = 001, start left bottom, draw left to right, then bottom to top // [MV:MX:MY] = 010, start right top, draw right to left, then top to bottom // [MV:MX:MY] = 011, start right bottom, draw right to left, then bottom to top // [MV:MX:MY] = 100, start left top, draw top to bottom, then left to right // [MV:MX:MY] = 101, start left bottom, draw bottom to top, then left to right // [MV:MX:MY] = 110, start right top, draw top to bottom, then right to left // [MV:MX:MY] = 111, start right bottom, draw bottom to top, then right to left // // Режим отображения цвета из видеопамяти на матрице дисплея: // ILI9341_MADCTL_RGB : RGB data - RGB-данные отображаются как есть // ILI9341_MADCTL_BGR : BGR data - при отображении RGB-данных меняются R- и B-компоненты void setMemoryWriteModeILI9341(unsigned char madctlFlags);
// определение области вывода на дисплее. // установка позиции вывода графических данных в стартовый угол, данные будут // последовательно выводиться согласно MADCTL-регистра (см. setMemoryWriteModeILI9341) // условие: x1<=x2, y1<=y2 // после задания области вывода дисплей переводится в режим записи цветовых данных void setOutputAreaILI9341(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
// команда включения режима записи цветовых данных в определенную область вывода. // после данной команды в дисплей можно отправлять неограниченное количество цветовых данных, // данные будут запиываться в заданную область вывода согласно MADCTL-регистра, после достижения // конечного угла области вывода запись продолжится снова со стартового угла. void setColorWriteModeILI9341(void);
// отправка слова данных о цвете в дисплей, должна выполняться после включения резима записи цветовых данных. // Формат цвета RGB565 или BGR565 (см. MADCTL) // Физически - команда отправляет в дисплей одно слово данных, сначала старший байт, потом младший. void sendColorDataILI9341(unsigned int colorData);
// отправка произвольной команды в дисплей void sendCommandILI9341(unsigned char displayCommand);
// отправка произвольного слова данных в дисплей void sendDataILI9341(unsigned int displayData);
// заполнение дисплея заданным цветом void fillDisplayILI9341(unsigned int fillColor);
// заполнение заданным цветом прямоугольной области на дисплее // условие: x1<=x2, y1<=y2 void fillAreaILI9341(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int fillColor);
// отрисовка пикселя заданным цветом void putPixelILI9341(unsigned int x, unsigned int y, unsigned int pixelColor);
//-- Основные процедуры работы с дисплеем ---------- // инициализация void initDisplayILI9341(void){ setResetPinILI9341(0); _delay_ms(50); setResetPinILI9341(1); _delay_ms(10);
// аппаратная инверсия изображения void inversionModeILI9341(unsigned char isInversionOn){ if (isInversionOn) sendCommandILI9341(ILI9341_INVON); else sendCommandILI9341(ILI9341_INVOFF); }
// управление записью данных в видеопамять дисплея (регистр MADCTL). void setMemoryWriteModeILI9341(unsigned char madctlFlags){ sendCommandILI9341(ILI9341_MADCTL); sendDataILI9341(madctlFlags); isSwapCoordinates = madctlFlags & ILI9341_MADCTL_MV; }
// определение области вывода на дисплее. void setOutputAreaILI9341(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2){ sendCommandILI9341(ILI9341_CASET); sendDataILI9341(HI(x1)); sendDataILI9341(LO(x1)); sendDataILI9341(HI(x2)); sendDataILI9341(LO(x2)); sendCommandILI9341(ILI9341_RASET); sendDataILI9341(HI(y1)); sendDataILI9341(LO(y1)); sendDataILI9341(HI(y2)); sendDataILI9341(LO(y2)); setColorWriteModeILI9341(); }
// команда включения режима записи цветовых данных в определенную область вывода. void setColorWriteModeILI9341(void){ sendCommandILI9341(ILI9341_RAMWR); }
// отправка двух слова данных о цвете в дисплей, должна выполняться после включения режима записи цветовых данных. void sendColorDataILI9341(unsigned int colorData){ sendDataILI9341( colorData ); }
// отправка произвольной команды в дисплей void sendCommandILI9341(unsigned char displayCommand){ setRsLevelILI9341(0); sendWordILI9341(displayCommand); }
// отправка произвольного слова данных в дисплей void sendDataILI9341(unsigned int displayData){ setRsLevelILI9341(1); sendWordILI9341(displayData); }
// заполнение дисплея заданным цветом void fillDisplayILI9341(unsigned int fillColor){ if (isSwapCoordinates) fillAreaILI9341(0,0,DISPLAY_ILI9341_HEIGHT-1,DISPLAY_ILI9341_WIDTH-1,fillColor); else fillAreaILI9341(0,0,DISPLAY_ILI9341_WIDTH-1,DISPLAY_ILI9341_HEIGHT-1,fillColor); }
// заполнение заданным цветом прямоугольной области на дисплее // условие: x1<=x2, y1<=y2 void fillAreaILI9341(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int fillColor){ setOutputAreaILI9341(x1,y1,x2,y2); unsigned int i=x1; while(1) { unsigned int j=y1; while(2) { sendColorDataILI9341(fillColor); if (j==y2) break; j++; } if (i==x2) break; i++; } }
// отрисовка пикселя заданным цветом void putPixelILI9341(unsigned int x, unsigned int y, unsigned int pixelColor){ fillAreaILI9341(x,y,x,y,pixelColor); }
Как пользоваться.
1. Проинициализировать интерфейс СПИ и выводы управления дисплеем. 2. вызвать initDisplayILI9341(); 3. Рисовать.
И да, я тут не рассматривал вопросы питания и подсветки. Хоть контроллер ILI9341 и толерастен к 5 вольтам питания, входная логика исключительно 3.3 вольта. Соответственно, на 5 линий интерфейса надо 5 делителей, или питать контроллер от источника 3,3 вольта В том дисплее, что у меня - управление подсветкой - это логический вход, т.е. им можно управлять без всяких резисторов и транзисторов прямо с ноги контроллера. Читайте описание вашего дисплея, что бы убедиться, что у вас так же. Или смотрите по плате - куда и как идут дорожки подсветки.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения