Появилась свободная минутка и решил повозиться с графическим дисплеем на базе контроллера KS0108. Заодно поковырял LcdVision и даже нарисовал танк, который ездит по экрану и стреляет 🙂 Теперь обо все по подробнее.
Про то, как выводить символы на экран мы поговорили в прошлом уроке, но в этом пользы мало, это умеет и символьный LCD. Поэтому, целью стал вывод какой нибудь картинки на экран. Для начала, хотя бы точку. Оказалось, что вывести на экран точку проще простого. Достаточно указать координаты х,у для вставки изображения.
glcd_putimagef(x,y,buffer,GLCD_PUTCOPY); |
Сама картинка хранится в виде массива. Формат хранения картинки выглядит так:
flash unsigned char buffer[]= { 0x01,0x00, 0x01,0x00, #ifndef _GLCD_DATA_BYTEY_ 0x01, #else 0x01, #endif }; |
Это массив, первый элемент которого отвечает за размер картинки по горизонтали, третий за размер по вертикали. Для чего нужны второй и четвертый элемент я пока не понял. Дальше два элемента, условно компилируемые, в них находятся одинаковые значения — 0х01. То что 0x01 означает закрашенный пиксель, 0x00 не закрашенный, стало понятно сразу. Почему же одинаковые значения, по разному включаются в проект? Судя по описанию, бывают два типа дисплеев, те что читают строчки и те что читают столбцы. Соответственно, если рисовать фигуры больше чем 1 пиксел, то значения для строк и столбцов будут совершенно разные.
Сам формат хранения данных оказался довольно интересным, но предсказуемым. Допустим, дисплей использует чтение столбцов. Верхний левый край экрана является координатой 0,0. От этой координаты отсчитываются 8 пикселей вниз, если какой то из этих пикселей записана единица, т.е. он закрашен. Допустим, закрашен 1 и 8 пиксель, в двоичной системе это 1000 0001, т.е. 81 в шестнадцатеричной. Вот это значение и будет первым элементом массива. Следующие 8 точек аналогично.
Чтобы все это не рассчитывать, а только рисовать и получать этот массив готовым, придумана программа LCD Vision, которую можно скачать с сайта CAVR. У бесплатной версии недостаток — нельзя скопировать полученный код, только посмотреть. Если рисунок маленький, то это не проблема. Кроме того, в программу можно импортировать рисунок, программа послушно преобразовывает его в код, однако на выходе ничего адекватного получить не удалось. Возможно программа еще сыровата пока.
Вернемся к основной нашей цели. Выведем точку на экран и будем управлять ее перемещением. Добавим 2 переменные х, у и четыре кнопки. Кнопки будут увеличивать и уменьшать точку вставки изображения, таким образом мы будем управлять положением точки на экране.
#include <mega8.h> #include <glcd.h> // Font used for displaying text // on the graphic LCD #include <font5x7.h> flash unsigned char buffer[]= {0x01,0x00, 0x01,0x00, 0x01 }; int x=0,y=0; void main(void) { GLCDINIT_t glcd_init_data; // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=P State2=P State1=P State0=P PORTB=0x0F; DDRB=0x00; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0x00; glcd_init_data.font=font5x7; glcd_init(&glcd_init_data); glcd_putimagef(x,y,buffer,GLCD_PUTCOPY); while (1) { if(PINB.0==0) { x++; glcd_clear(); glcd_putimagef(x,y,buffer,GLCD_PUTCOPY); } if(PINB.1==0) { x--; glcd_clear(); glcd_putimagef(x,y,buffer,GLCD_PUTCOPY); } if(PINB.2==0) { y++; glcd_clear(); glcd_putimagef(x,y,buffer,GLCD_PUTCOPY); } if(PINB.3==0) { y--; glcd_clear(); glcd_putimagef(x,y,buffer,GLCD_PUTCOPY); } } } |
Продолжим улучшать нашу программу, вместо точки нужно нарисуем танк :). Причем, танк будет двигаться он будет в разных направлениях, значит, для каждого из них, нужно нарисовать свою картинку и сделать свой массив. Размеры одного спрайта 12х12.
Как пример, массив для танка, направленного вверх
flash unsigned char Ubuffer[]= { 0x0C,0x00, 0x0C,0x00, 0xAC,0xAC,0xFC,0xF0,0xF8,0xFF,0xFF,0xF8, 0xF0,0xFC,0xAC,0xAC,0x0A,0x0A,0x0F,0x03, 0x07,0x07,0x07,0x07,0x03,0x0F,0x0A,0x0A, }; |
Теперь можно еще научить его стрелять. Для этого при нажатии кнопки, будет отрисовываться точка, которая будет двигаться от текущей координаты x,y до края экрана. В зависимости от направления, краями экрана будут точки 0, 0, 63, 127.
Результат немного огорчил, дело в том что функция очистки экрана работает достаточно медленно, во всяком случае, в протеусе, поэтому картинка мерцает. Возможно на реальном мк, при более высоких частотах это будет менее заметно. Либо, нужно анализировать предыдущее и последующее положение спрайта и закрашивать только не используемую часть. В общем простор для фантазии есть.
Осталось разобраться с русскоязычными шрифтами. Схема и прошивка
админ у меня вопрос.
в 3 строке написано #include
Она же не должна быть пустая
Когда я написал программу у меня компилятор подсветил именно эту строку.
Пожалуйста подскажите в чем ошибка?
Поправил
админ я тоже исправил у себя все компилируется но когда я начал испытывать в протеусе весь экран дисплея стал чисто черным и картинки не высвечивались
потом поставил вашу прошивку результат тот же
попробуйте менять частоту камня в протеусе, у меня на 2 и 4 мгц работало
спасибо попробую я испытывал только на 8 и 1 мгц
Урааааааа!!!!!! заработало 😀 😀 😀 😀 😀
только мерцает немного
Про снаряд! Если затирать только точку пробелом в том месте где она была и/или движущийся танчик. То пулька даже прикольней получается со шлейфиком. При этом весь экран не перемаргивает.
Как можно организовать вывод изображения по антенному кабелю на телик, используя мегу8? Или на монитор через vga?
возможно об этом будет, в планах есть
Вывод изображений примерно также будет организовываться на дисплей nokia3310?
примерно также
Подскажите нельзя объяснить поподробней как пользоваться программой LcdVision, что я не пытаюсь на ней нарисовать, она выдает огромный код. Нарисовал квадратик 2X2 на рисунке этого же формата, а код получился больше 1000 шагов. Прошу прошения если мой вопрос показался глупым.
Частоту не камня. а экрана надо менять, в настройках в протеусе, тогда без потерь частоты все работает
Подскажите как выводить изображение на дисплей с SD карты, или где «копать»? А если будет небольшой пример, я просто буду счастлив.
будет, причем в ближайшее время
Нашел пример вывода изображения на дисплей с SD карты, но знаний чтобы разобраться не хватает, запутался в конец, если у вас будет желание и возможность разобрать на примере с вашими комментариями
Такая статья будет и она уже в общем то готова, осталось только сделать железяку, но нет времени.
Если есть готовая прошивка, то вышлите пожалуйста мне на E-mail, со схемой я в ближайшее время соберу и поверю на железе и сниму небольшое видео которое вышлю вам.
Андрей, вы даже не просили для какого камня и для какого дисплея, а уже готовы собрать??? Я планировал сделать для stm32 + nokia1100.
Я как и вы радиолюбитель, и фанат своего дела. Я уже давно жду выхода подобной статьи, и уже заранее подготовился, купил еще месяц назад STM32F4 (хотя не знаю с какой стороны к нему подойти), есть и nokia1100, есть почти все распространенные виды «камня» как AVR так PIC. А если чего не хватает то докупить не проблема. Мое увлечение по МК отлично помогает мне по работе с промышленными контроллерами. По этому я на этом не экономлю. Я много рылся в интернете в поисках обучения по МК. Ваш сайт самый лучший, по способу представления информации. Благодаря вашим статьям, я собрал и реализовал на промышленных объектах некоторые виды автоматики (в плане импортно замещения — шутка), чему огромное вам спасибо! И я очень сильно заинтересован в развитии вашего сайта. Жду с нетерпением новой статьи!!!!
Статья появится) Немного терпения
А почему пример с чтением изображения с SD карты должен быть обязательно stm32? Я например не знаю вообще как нему «подойти». В CodeVision AVR есть готовые примеры, только я понять его не могу. Да и в протеусе у меня ATxmega-библиотеки нет чтобы проверить. Нельзя пример сделать на более доступных контроллерах AVR.
Заранее Спасибо.
Не подскажите если команда, функция для очистки не всего экрана, я только заданной области? Спасибо.
готовой функции нет, но можете выводить пустой символ
Написал законченную программу для вывода картинок (нескольких) на цветной дисплей SSD1289 с SD карты пример которой я так долго искал на просторах глобальной сети и спрашивал у вас. Нашел если у вас будет желание сайт указан в документах, (только там инициализация кривая). Все проверенно на «железе» и Протеусе. Написано в Atmel Studio на СИ, думаю вам не составит труда перенести CodeVisionAVR. Очень хотелось хотелось бы увидеть еще один (а может несколько) уроков на эту тему в вашим практичным подходом к разъяснениям. Ссылка на все исходники и необходимые программы https://yadi.sk/d/BCrDYkIsqHDCK . Знаю что у вас не принято оставлять ссылки, но все же посмотрите, в комментариях программы я старался все подробно описать (как смог). Сам мой этот комментарий просто удалите.
Забыл, моем варианте (в отличие от указанного сайта) работает все идеально.
В последнее время я пишу только о вещах, которые либо сделал, либо буду использовать в своих проектах. Пока подобный дисплей не планировал использовать, поэтому и нет материала, но все может измениться. За материал спасибо, думаю что пригодится. По поводу ссылок меня напрягает, когда расхваливаешь какой то сайт, а завтра его нет. Про крупные ресурсы все и так знают, смысла на них оставлять ссылки нет.
Если вы решите купить этот дисплей на Aliexspress не покупайте, там китайцы вместо него продают замену на основе микроконтроллера ILI9341 работать не будет,проверенно несколько раз. Нужно заказать на Ebay с поиском SSD1289 если позволите выложить на сайте укажу конкретную ссылку. Дисплей изначально предназначен под Arduino на шилде должно быть написано TFT_320QVT (это то что надо) если написано TFT_320QVT_9341 то не годится, работать не будет, там другая инициализация, а внешне и подключение у них одинаковое. Дисплей питается 5В а сигналы подаются с напряжением 3,3В, преобразователь уровней сигналов не нужен любой МК прекрасно работает с напряжением 3,3В, проверенно. На подсветку тоже идет 3,3В.
ок, буду иметь ввиду, спасибо
А можно поподробнее про GLCD_PUTCOPY?
Когда пишу в Codevision glcd_putimagef последний аргумент GLCDBLOCKMODE_t. Что это за мод такой и что можно туда еще вписать?
Я пытаюсь вывести неподвижную картинку нарисованную в LCDVision, и когда пытаюсь вывести изображение на GLCD, то в Протеусе рисуется сплошной черный экран.
С GLCDBLOCKMODE_t разобрался, но все равно черный экран
С черным экраном тоже разобрался. Почему то LCDVision выдал код полностью заполненного экрана.
Как должен происходить обмен данными между мк ATmega8 и LCD-экраном? В качестве LCD экрана использую Nokia1100.По идее передача сигнала должна быть в виде обмена битами, но не могу понять, как именно(
все очень просто, у любого экрана есть свой контроллер, не тот что атмега8, а свой встроенный. ищете какой контроллер у вашего дисплея, затем документацию на него, там будет указаны временные диаграммы, инициализация, команды, и как передавать данные.