Дисплей ili9341 не работает
Наконец добрались руки до дисплея. Купил его еще летом, а вот нормально заняться им вышло только сейчас.
Дисплеев на сегодняшний день огромное количество, мой выбор пал на решение "лоу кост". Такой дисплей у китайских друзей стоит в 5-6$.
В общем то ничего необычного. Разрешение всего 320х240, но зато он цветной и с последовательным интерфейсом, что нещадно бъет по скорости обновления, но сильно экономит ноги контролера (и нервы при соединении на макетке).
У данного дисплея есть контролер для обработки команд и обмена с микроконтроллером - ILI9341.
Из него можно узнать набор команд и последовательность данных.
У дисплея есть ноги для обмена по SPI, нога аппаратного сброса и нога, которая помогает ему понять когда принятые данные - команда, а когда - цвет пикселя.
Для всего этого "дергонога" я решил заготовить макросы:
Этап настройки SPI я пожалуй пропущу. Тут все стандартно, берем настройку из любого примера для вашего камня в режиме 1 (CPOL = 0, CPHA = 0).
Когда это готово, делаем функции посылки команды и данных:
Тут тоже все просто. Для посылки команды нужно чтобы линия DC была в 0, а для данных - в 1. С линией CS поступаем как всегда. Можно в принципе возложить эту ответственность на железо, если ваш контроллер такое умеет.
Инициализация дисплея
Рисуем
Чтобы что-то нарисовать нужно поставить курсор в нужное место:
Курсор поставили, можно рисовать:
Ради интереса можно сохранить картинку в GIMP в формат C файла. И подтянуть его в проект. Там вы увидите массив. Его нужно просто вывести в цикле на экран.
Шрифты
Вывести текст на экрна тоже очень просто. Нужно раздобыть массив со шрифтом. Сделать это можно при помощи утилиты BitFontCreator (она крутая, но денег немереных стоит) или же народной приблуды FontsGenerator.exe, которую я нашел на easyelectronics.
В массиве аккуратно уложены битовые маски шрифта. Например имеем 16 пикселей высотой и 8 шириной, тогда нам нужно последовательно выводить по пикселю и при этом следить каким цветом нужно сделать текущий пиксель.
Для описанного примера в массиве будет 16 двухбайтных чисел. В каждом из чисел информация о том, закрашен данный пиксель или нет.
BitFontCreator генерит таблици с шрифтами различной ширины. Т.е. каждая буква имеет различную ширину, это повышает читаемость и делает текст красивее для глаза, но принуждает нас каждый раз смотреть ширину в массиве.
Строку можно выводить обычным методом при помощи указателей:
Получается вот так:
Комментарии
Какая частота полной заливки экрана в секунду у вас получилась?
Не замерял. Но медленно. Порядка двух секунд идет полная перерисовка. Но с частотой не играл.
Имеет смысл поиграть. Я когда-то брал готовую библиотеку, на частоте SPI 18 МГц экран выдавал 6-7 кадров в секунду. Это уже вполне приемлемо для интерфейса какого-нибудь девайса. В целом, экран вполне годный для изделий, если не гонять на нем видео)
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.
Последние посетители 0 пользователей онлайн
Похожий контент
Я хочу построить простой шлюз с arduino+nrf24l01+enc28j60, nrf24l01 принимает сигнал и enc28j60 передает его в LAN, но проблема в том, что и nrf24l01 и enc28j60 используют протокол SPI для взаимодействия с arduino, если я хочу использовать собственный lib разработки arduino, я могу выбрать только один из nrf24l01 и enc28j60, потому что они имеют общее определение (pins_arduino.h).
static const uint8_t SS = 10; static const uint8_t MOSI = 11; static const uint8_t MISO = 12; static const uint8_t SCK = 13 Итак, решение состоит в том, чтобы выбрать nrf24l01 вместо использования lib development, которая поставляется с arduino, но использовать другой IO порт, который я разработал сам, это правильно?
Данный проект предназначен для управления RGB лампами с помощью дисплейного модуля STONE:
1. Управление цветом света
2. Управление яркостью света
3. Управление четырьмя режимами работы лампы
Принцип работы управляющего tft-lcd дисплея STONE
Модуль tft-lcd взаимодействует с MCU клиента посредством команд (шестнадцатеричный код), а MCU затем управляет работой подключенного устройства в соответствии с полученными командами.
Разработка графического интерфейса пользователя
Проводка и сварка
Завершив вышеописанное управление сенсорным дисплеем, мы можем сосредоточиться на разработке MCU и ламп WS2812B_RGB.
Но перед этим нам нужно провести сварочные работы.
Схема подключения
Адаптер питания 12В, который необходим для питания дисплейного модуля STONE STVC070WT-01 и для питания модуля MCU и лампы WS2812B_RGB путем понижения напряжения до 5В через dc-dc buck.
Аксессуары, используемые в проекте
Сварите эти части вместе, и эффект будет следующим:
Код драйвера STM32
Код STM32
Кнопки и текст на экране дисплея имеют соответствующие адреса. В данном проекте адреса компонентов экрана дисплея следующие:
Наконец, код загружается в микросхему STM32, и готовая печатная плата подключается к экрану дисплея управления, при этом гарантируется стабильность электропитания. Затем яркость и цвет RGB-лампы можно контролировать с помощью модуля дисплея управления STONE.
Окончательная схема подключения оборудования
Около года тому назад на сайте появилась статья о том как инициализировать TFT дисплей, под управлением SSD1289, а где-то около месяца назад мне написал один из посетителей сайта. Суть письма была в том, что он заказал дисплей по указанной в статье ссылке, но запустить его не получалось и он предложил этот дисплей и ещё несколько других выслать мне, а я, в свою очередь, должен буду выложить код если получится их запустить.
Как оказалось, дисплей, который ему прислали с али управляется драйвером ILI9341, об этом помогла догадаться надпись на нём.
Верхний дисплей с драйвером SSD1289, нижний с ILI9341.
Поэтому как только ко мне пришёл этот дисплей, сразу начал изучать даташит на ILI9341.
В отличие от SSD1289 у ILI9341 нет регистров, для общения с ним используются команды. Сначала посылаешь команду, а затем набор параметров, то есть после того, как мы послали команду дисплей уже ждёт, что ему передадут параметры. Также надо сказать, что общение с дисплеем осуществляется по одному из двух протоколов: интеловский i8080 и мотороловский M6800, чем они отличаются описывал тут, не стал изменять традициям и выбрал i8080. У этого протокола существует две реализации, для получения более подробной информации можно почитать даташит.
Первым делом необходимо реализовать низкоуровневые функции и тут важно понять, что мы правильно понимаем даташит. Самый простой способ проверить, правильность понимания даташита, это считать какую-то информацию с дисплея, например, его ID.
Вторая и третья определяют их последовательность, для записи
Тогда функция, для отправки команды, будет выглядеть так.
А функция которая читает данные так.
Из скриншотов понятно, что описанные выше функции заработали, осталось реализовать отправку данных по 8 и 16 бит. Дело в том, что в основном при отправке данных используются только младшие 8 бит шины, но, например, при записи данных в память дисплея используются все 16 бит.
Всё, мы реализовали все необходимые низкоуровневые функции, теперь можно переходить непосредственно к инициализации. Перед тем как перейти к инициализации, надо сказать, что напряжение питания ЖК-ячейки постоянно изменяет свою полярность, сделано это для того, чтобы избежать явлений гидролиза и диссоциации сложных органических соединений, из которых состоит жидкокристаллический материал.
В функции инициализации есть функция TFT_SetOrientation(2), которая определяет порядок отрисовки, MAX_X и MAX_Y объявлены глобально и инициализированы нулями.
А вот как выглядит дисплей после инициализации.
Чтобы понять, что он точно инициализировался, закрасил его красным цветом.
Как это сделать буду описывать в следующей статье.
Теперь что касается схемы подключения так, как распиновка 40 выводных дисплеев SSD1289 и ILI9341 одинаковая, схему подключения оставил без изменения и выглядит она так.
Таким образом, можно сделать одну отладочную плату для обоих дисплеев и ещё важно чтобы напряжение питания МК и дисплея было 3.3 вольта, при питании от 5 вольт дисплей не запустился. Подсветку дисплея тоже запитал от 3.3 вольта через резистор 47Ом.
А на этом всё, в следующей статье мы рассмотрим как выводить символы на дисплей и там же будет проект для Atmega16 в AtmelStudio6.2.
Для желающих быстро проверить работает ли их дисплей, оставляю тут прошивку для Atmega16, которая заливает дисплей разными цветами ili9341_i8080.hex [3,54 Kb] (cкачиваний: 528) .
Ещё один эксперимент по оптимизации скорости вывода графической информации на дисплей.
Похожие дисплеи будут трудиться у меня в Патроле. Ряд параметров автомобиля будет представлен в цифровом виде и с этим проблем нет никаких. Но некоторые будут представлены в графическом виде и потому экран нужно перерисовывать с большой скоростью.
Потому в качестве основы используется самая навороченная ардуинка — Arduino DUE.
Часть информации будет выводиться дунькой через композитный(из говна и палок) Video-выход на 7" дисплей магнитолы, часть — по SPI на два дисплея в приборке Патрола.
Дисплеи в приборку планируется ставить 3.5" от Raspberry Pi. Но для экспериментов был взят 2.8" дисплей на базе ili9341, на котором ноги все подписаны и который знают многие ардуиновые графические библиотеки:
Вначале под руку попались несколько библиотек, которые(как оказалось потом) не умели задействовать аппаратный SPI. Потому выигрыша от переключения шлейфа на ножки аппаратного SPI получить с наскока я не сумел.
Но потом я набрёл на библиотеку UcgLib, которая умеет работать как через SW(программный) SPI, так и через HW(аппаратный) SPI:
Разница получилась в 3-4 раза. Некисло.
Я понял куда нужно рыть и после продолжительных ковыряний в интернете была найдена ещё более продвинутая библиотека ILI9341_due — marekburiak.github.io/ILI9341_due/
которая умеет не только работать с аппаратным SPI ардуин, но и задействует DMA у Arduino DUE.
Помимо всего прочего у библиотеки очень мощные возможности по формированию изображения на экране! Но сейчас не об этом.
На данном этапе меня интересовало — какой ещё реальный выигрыш в скорости можно получить от всех этих заморочек, чтобы закрыть тему скорострельности вывода на экран для себя окончательно.
Итоговый выигрыш получился колоссальный.
Максимальная частота SPI — 42MHz.
Это — если не разгонять дуньку с 84 до 114MHz.
У меня на такой частоте дисплей постоянно вис — пришлось скорость снизить до 28MHz.
Возможно, что с более короткими проводами или с другими дисплеями всё будет крутиться и на 42MHz, но даже на 28MHz всё летает!
Прошу продегустировать скорость в ТРЁХ доступных режимах работы:
Итоги следующие:
Аппаратный SPI без DMA: 13100 мсек.
Аппаратный SPI с DMA: 2801 мсек!
Разница за счёт DMA и других возможностей DUE(не считая частоты кристалла) — почти в 5 раз.
ИТОГО: Если подключить провода куда нужно и установить библиотеку от умных людей(или написать самому) — то получим итоговый выигрыш в скорости вывода графической информации до 20 РАЗ на том же самом железе!
Читайте также: