Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
-
Вадиматоричик
- Грызет канифоль
- Сообщения: 299
- Зарегистрирован: Пн май 16, 2011 10:54:32
- Откуда: Красноярск
Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Захотелось мне на досуге расширить свой кругозор. Давно хотелось научиться выводить на экран какую-нибудь картинку (Но без внешней памяти. Силами Atmega). Друг-продавец посоветовал вот этот экранчик http://krsk.24au.ru/3232807/. За 360 руб я получил неплохой монохромный экранчик с приличным разрешением, а так же хорошими габаритами. Т.к. я не ищу легких путей и на каждый внешний модуль или определенную задачу пишу собственную библиотеку, то не теряя времени я взялся за работу.
Долго искал датащит. Попался только на японском. И то, с заблокированным копированием. Обратился за помощью к продавцу, и тот любезно предоставил мне вот этот датащит на английском.
Далее столкнулся со сложностями в плане адресации. Убил 2 дня на то, чтобы разобраться. Помогла вот эта статья http://avrprog.blogspot.ru/2013/12/lcd-12864-st7920-8.html. С помощью нее удалось понять принцип. А далее была написана библиотека, которая выдает на экран картинку из памяти. Изначально планировал выводить из ОЗУ. Но требуется ровно 1 килобайт. Я, обрадовавшись написал версию, читающую данные из ОЗУ, но забыл, что в Atmega16 всего 1 кб, а часть уходит на регистры и стек, из-за этого не срослось... На данный момент библиотека лишь выводит картинку, записанную в cseg (память программ), но как только приобрету Atmega32, перепишу библиотеку на чтение из ОЗУ, а так же разорхиватор картинок, сжатых с помощью алгоритма RLE. Для конвертации изображений использую вот эту программу http://hobby-research.at.ua/load/utility/grafika/bitmap2code/9-1-0-22.
Вот мой рабочий закоментированый пример.
Картинка дисплея с изображением в железе.
Долго искал датащит. Попался только на японском. И то, с заблокированным копированием. Обратился за помощью к продавцу, и тот любезно предоставил мне вот этот датащит на английском.
Далее столкнулся со сложностями в плане адресации. Убил 2 дня на то, чтобы разобраться. Помогла вот эта статья http://avrprog.blogspot.ru/2013/12/lcd-12864-st7920-8.html. С помощью нее удалось понять принцип. А далее была написана библиотека, которая выдает на экран картинку из памяти. Изначально планировал выводить из ОЗУ. Но требуется ровно 1 килобайт. Я, обрадовавшись написал версию, читающую данные из ОЗУ, но забыл, что в Atmega16 всего 1 кб, а часть уходит на регистры и стек, из-за этого не срослось... На данный момент библиотека лишь выводит картинку, записанную в cseg (память программ), но как только приобрету Atmega32, перепишу библиотеку на чтение из ОЗУ, а так же разорхиватор картинок, сжатых с помощью алгоритма RLE. Для конвертации изображений использую вот эту программу http://hobby-research.at.ua/load/utility/grafika/bitmap2code/9-1-0-22.
Вот мой рабочий закоментированый пример.
Картинка дисплея с изображением в железе.
Все можно сделать, было бы желание!
-
Вадиматоричик
- Грызет канифоль
- Сообщения: 299
- Зарегистрирован: Пн май 16, 2011 10:54:32
- Откуда: Красноярск
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Создал новую библиотеку. Достает данные из Flash памяти, распаковывает и сразу же в дисплей. Данные запаковываются алгоритмом RLE все в той же программе. Вот пример работы под ATmega16. Жалко, что в Proteus нет данного контроллера.
Все можно сделать, было бы желание!
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Спасибо.
Интересный материал. У меня как раз лежит 5 таких дисплеев, тоже хотел написать сам бииблиотечку, да все руки никак не доходят
...
Только я хочу написать под SPI, ато жалко кучу выводов тратить...
Тут http://www.bajdi.com/cheap-128x64-graphic-lcd-12864zw/
по SPI вроде подключили, все работает, так что когда займусь, думаю что ваш материал чем то поможет...
Интересный материал. У меня как раз лежит 5 таких дисплеев, тоже хотел написать сам бииблиотечку, да все руки никак не доходят
Только я хочу написать под SPI, ато жалко кучу выводов тратить...
Тут http://www.bajdi.com/cheap-128x64-graphic-lcd-12864zw/
по SPI вроде подключили, все работает, так что когда займусь, думаю что ваш материал чем то поможет...
-
Вадиматоричик
- Грызет канифоль
- Сообщения: 299
- Зарегистрирован: Пн май 16, 2011 10:54:32
- Откуда: Красноярск
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Мне пинов не жалко. Главное скорость. А 8-ми битная шина - это быстро и, болемение, просто. Вот немного изменил. Выполняется быстрее и памяти ест меньше.
- Вложения
-
- Чуть более оптимезированная.rar
- (24.88 КБ) 1812 скачиваний
Все можно сделать, было бы желание!
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Перевел ваш примерчик на Си... Работает!!!!! http://www.youtube.com/watch?v=jtNtIfQSboc
По моему у меня еще больше получилось оптимизировать процедуру распаковки картинки на дисплей...
Вот как это выглядит на Си... Чуть позже скину этот вариант на асме...
По моему у меня еще больше получилось оптимизировать процедуру распаковки картинки на дисплей...
Вот как это выглядит на Си... Чуть позже скину этот вариант на асме...
Код: Выделить всё
//----------
//функция вывода на дисплей упакованной графической картинки из PROGMEM
//АРГУМЕНТ - указатель на упакованную в PROGMEM картинку
void ST7920_CompressPictureOut (uint8_t* pPicture)
{
uint8_t RepeatMode; //флаг режима НЕНОЛЬ-повтор, НОЛЬ-неповтор
uint8_t RepeatCntr; //счетчик количества одинаковых\неодинаковых байтов
uint8_t SymbNum=0; //0-15 кол-во байт в линии
uint8_t LineNum=0; //0-63 кол-во линий по вертикали
uint8_t byte = 0;
ST7920_CommandOut (0x80);
ST7920_CommandOut (0x80);
while (1){
RepeatCntr = pgm_read_byte (pPicture++);
RepeatMode = (RepeatCntr & 0x80); //определяем режим заполнения (повтор\неповтор)
RepeatCntr &= ~0x80;
RepeatCntr++;
if (RepeatMode)
byte = pgm_read_byte (pPicture++); //тут читаем если режим повтора
for (uint8_t i=RepeatCntr; i; i--){
if (! RepeatMode)
byte = pgm_read_byte (pPicture++); //тут читаем если режим НЕповтора
if (SymbNum == 16){ //контроль окончания строки
SymbNum = 0;
if (++LineNum >= 64) //контроль окончания вывода картинки
return;
if (LineNum < 32){ //верхняя половина дисплея
ST7920_CommandOut (0x80 | LineNum);
ST7920_CommandOut (0x80);
}
else{ //нижняя половина дисплея
ST7920_CommandOut ((0x80 | LineNum) - 32);
ST7920_CommandOut (0x88);
}
}
ST7920_DataOut (byte); //данные на дисплей
SymbNum++;
}
}
}
-
Вадиматоричик
- Грызет канифоль
- Сообщения: 299
- Зарегистрирован: Пн май 16, 2011 10:54:32
- Откуда: Красноярск
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Поздравляю!
Рад, что вы всерьез взялись за этот дисплей. Чувствую конкуренцию
, но сдаваться не намерен
. Вывод картинки - это, конечно, хорошо, но далее я намерен выводить картинку с microSD в формате bmp (пока хоть в несжатом). Драйвер для SD уже написан и работает. Осталось с bmp до конца разобраться. Позже выложу все сюда. Так же на асеме. И еще. Судя по датащиту, наш дисплей может работать только в режиме 8 или 4-х битной шины. SPI нет.
Все можно сделать, было бы желание!
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Вадиматоричик писал(а):Чувствую конкуренцию
Правда мы там с ним не очень лестно отзывались о вашем стиле написания
Ну это вы погорячились... я же выше давал ссылку, где чел подключил по SPI... да и в даташите черным по белому описывается этот режим работы...Вадиматоричик писал(а):Судя по датащиту, наш дисплей может работать только в режиме 8 или 4-х битной шины. SPI нет.
И катсти... даташит пишется через Ш... вы уже несколько раз написали через Щ... (хотя мож я и ошибаюсь...
-
Вадиматоричик
- Грызет канифоль
- Сообщения: 299
- Зарегистрирован: Пн май 16, 2011 10:54:32
- Откуда: Красноярск
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Конкуренция нереальная...
Жаль, что не нашел ее, когда только купил дисплей... Было бы легче жить.
Правда мы там с ним не очень лестно отзывались о вашем стиле написания... Ну в общем не обращайте внимания...
Почему-то я не удивлен. Мой стиль написания весьма не идеален. Т.к. чувствую себя "супер программистом", а бывает и элементарного не знаю. Стараюсь писать понятнее и делать море комментариев, что помогает даже незнающему языка все понять. Так что красота письма - дело времени. Буду рад, если в ЛС скинете "переписку", в которой критикуется код. Приму к сведению и постараюсь исправиться.
Ну это вы погорячились... я же выше давал ссылку, где чел подключил по SPI... да и в даташите черным по белому описывается этот режим работы...
Гляжу в книгу - вижу фигу. Да, перечитал даташит (Спасибо за орфографическое исправление, я и вправду не знал, как пишется. Т.к. оба варианта подчеркиваются как ошибка.).
Все можно сделать, было бы желание!
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Дык та тема появилась позже вашей... так что вы по любому первопроходец!Вадиматоричик писал(а):Жаль, что не нашел ее, когда только купил дисплей... Было бы легче жить.
Да там его коммент и через один мой... вот и вся критикаВадиматоричик писал(а):Буду рад, если в ЛС скинете "переписку", в которой критикуется код.
Нашли упоминание о SPI ? Или может у вас другой какой то даташит.... Могу своим поделится...Вадиматоричик писал(а):Гляжу в книгу - вижу фигу. Да, перечитал даташит
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Много ли... мало ли... но 44 байта сэкономил, только на одной процедуре распаковки экрана...
Код: Выделить всё
LCD12864_OUT_OZU: ;ВЫВОД УПАКОВАННОЙ КАРТИНКИ НА ДИСПЛЕЙ
clr LoopLineNum ;Номер линии.
clr LoopSymbNum ;Номер байта в линии.
ldi Data, 0b10000000
rcall LCD12864_CommandOut
rcall LCD12864_CommandOut
ldi ZL, Low (LCD*2) ;Начальный адрес упакованной картинки.
ldi ZH, High(LCD*2)
CicleBig:
lpm ;читаем бит типа упаковки и количество упакованных байтов
mov RepeatCounter, r0 ;Счетчик повторов/неповторов.
ldi Temp, 1
add ZL, Temp ;Следущий байт - байт данных
adc ZH, MIN
set ;признак повторения
sbrc RepeatCounter, 7
rjmp SetT
clt ;признак НЕ повторения
SetT: andi RepeatCounter,0b01111111;Убераем старший бит (Показатель повторов).
inc RepeatCounter ;Повторы могут быть от 2-х раз до 129.
CicleRead:
lpm ;читаем байт данных
ldi Temp, 1
add ZL, Temp
adc ZH, MIN
CicleNoRead:
cpi LoopSymbNum,16 ;
brlo CicleEnd ;если НЕ конец строки - идем на конец цикла
ldi LoopSymbNum,0 ;иначе - строка с начала
inc LoopLineNum ;следующая строка
cpi LoopLineNum,64 ;контроль окончания вывода картинки
brlo DispPart
ret
DispPart:
ldi Data, 0b10000000 ;вычисляем адрес строки
or Data, LoopLineNum
cpi LoopLineNum,32 ;верхняя\нижняя половинки экрана
brlo DP1
subi Data, 32 ;если нижняя часть - отнимаем 32
DP1: rcall LCD12864_CommandOut
ldi Data, 0b10000000
cpi LoopLineNum,32 ;верхняя\нижняя половинки экрана
brlo DP2
ldi Data, 0b10000000+8 ;если нижняя часть - прибавляем 8
DP2: rcall LCD12864_CommandOut
CicleEnd:
mov Data, r0
rcall LCD12864_DataOut ;Выводим данные
inc LoopSymbNum
dec RepeatCounter ;обработка цикла повторов
breq CicleBig ;главный цикл
brtc CicleRead ;если НЕ повтор - будем читать следующее значение
rjmp CicleNoRead ;если повтор - будем использовать старое значение-
Вадиматоричик
- Грызет канифоль
- Сообщения: 299
- Зарегистрирован: Пн май 16, 2011 10:54:32
- Откуда: Красноярск
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Рад, что этот дисплей приобрел такую популярность. Есть даже статья на хабре http://habrahabr.ru/post/213459/. Попытался по ней написать нормальную библиотеку для работы по SPI. Но столкнулся с проблемой. Если подать "0" (-) на SPB (Для разрешения приема данных) вся цепь замыкается. У меня питается от программатора, так что гаснет все. Программатор в том числе. У кого-нибудь еще такое было? И еще. На дисплее по ссылке GND и VCC, по сравнению с мои дисплеем, на разных местах. Я об этом узнал уже после того, как подключил и цепь замкнулась. Даже и не подумал, что пины могут отличаться по назначению. Видимо, не судьба с SPI мне поработать... Спасибо за примеры. Буду стараться написать еще более компактный код 
Все можно сделать, было бы желание!
-
rastamanoff
- Первый раз сказал Мяу!
- Сообщения: 38
- Зарегистрирован: Чт июл 28, 2011 22:17:32
- Откуда: Тростянец
- Контактная информация:
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Тоже прикупил такой дисплей , именно st7920.
Пробую прикрутить его к Си-библиотеке u8glib - https://code.google.com/p/u8glib/ (U8glib for AVR) , интересует SPI-режим.
В качестве МК Atmega328 ,а точнее плата ArduinoProMini.
Компилирую в AVR Studio 4.19.Сначала шла ошибка - нету Makefile , с библиотекой идет пример "Hello World", там есть Makefile .Кинул его в папку default, предварительно поменяв в нем МК на Atmega328 и частоту 16МГц.Теперь ошибка другого плана -
В самом источнике библиотеки есть описание как подключить ее к AVR Studio 4,к сожалению на английском https://code.google.com/p/u8glib/wiki/avr
Спецы помогите ! Или ткните носом в нормальное описание подключения на СИ.
И еще не могу понять,что надо делать в опциях:
Самое интерестное, для Arduino есть пример http://nnm.me/blogs/pencraft/arduino-i-graficheskiy-displey-128x64-s-kontrollerom-st7920/.Я подключил все работает.Простенькие фигуры,текст.
Пробую прикрутить его к Си-библиотеке u8glib - https://code.google.com/p/u8glib/ (U8glib for AVR) , интересует SPI-режим.
В качестве МК Atmega328 ,а точнее плата ArduinoProMini.
Компилирую в AVR Studio 4.19.Сначала шла ошибка - нету Makefile , с библиотекой идет пример "Hello World", там есть Makefile .Кинул его в папку default, предварительно поменяв в нем МК на Atmega328 и частоту 16МГц.Теперь ошибка другого плана -
make: *** Нет правила для сборки цели `u8m2.a()', требуемой для `u8m2.elf'. Останов.
Build failed with 1 errors and 0 warnings...
В самом источнике библиотеки есть описание как подключить ее к AVR Studio 4,к сожалению на английском https://code.google.com/p/u8glib/wiki/avr
Спецы помогите ! Или ткните носом в нормальное описание подключения на СИ.
И еще не могу понять,что надо делать в опциях:
AVR Studio 4: Set additional options (Project - Configuration - Custom Options)
[All Files]
-ffunction-sections
-fdata-sections
[Linker Options]
-Wl,--gc-sections
Самое интерестное, для Arduino есть пример http://nnm.me/blogs/pencraft/arduino-i-graficheskiy-displey-128x64-s-kontrollerom-st7920/.Я подключил все работает.Простенькие фигуры,текст.
-
rastamanoff
- Первый раз сказал Мяу!
- Сообщения: 38
- Зарегистрирован: Чт июл 28, 2011 22:17:32
- Откуда: Тростянец
- Контактная информация:
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
С опциями разобрался,но ошибка осталась
make: *** Нет правила для сборки цели `u8m2.a()', требуемой для `u8m2.elf'. Останов.
Build failed with 1 errors and 0 warnings...
-
rastamanoff
- Первый раз сказал Мяу!
- Сообщения: 38
- Зарегистрирован: Чт июл 28, 2011 22:17:32
- Откуда: Тростянец
- Контактная информация:
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
"Лед тронулся..." Разобрался.

Тестовый проект для AVR Studio 4.19 ,подключение 3-мя поводами по SPI (PB2,PB3,PB4)
http://yadi.sk/d/1EuM3dLkJcHoa

Тестовый проект для AVR Studio 4.19 ,подключение 3-мя поводами по SPI (PB2,PB3,PB4)
http://yadi.sk/d/1EuM3dLkJcHoa
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
А она не слишком тяжеленькая... эта библиотечка?...
Чет с виду перегружена очень... или это так, только кажется?
И еще, как скорость по SPI ? не слишком медленный обмен? (хотя... это наверное будет заметно только в графическом режиме...)
Чет с виду перегружена очень... или это так, только кажется?
И еще, как скорость по SPI ? не слишком медленный обмен? (хотя... это наверное будет заметно только в графическом режиме...)
-
rastamanoff
- Первый раз сказал Мяу!
- Сообщения: 38
- Зарегистрирован: Чт июл 28, 2011 22:17:32
- Откуда: Тростянец
- Контактная информация:
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Размер для Atmega328 получился - Program: 6888 bytes (21.0% Full).
Это строка текста,несколько прямоугольников и круг.
Пока меня устраивает..
Скорость ,не могу сказать,так как сравнить с паралельным режимом не пробовал .Но для вывода текста в рамочке на мой взгляд подойдет.
Это строка текста,несколько прямоугольников и круг.
Пока меня устраивает..
Скорость ,не могу сказать,так как сравнить с паралельным режимом не пробовал .Но для вывода текста в рамочке на мой взгляд подойдет.
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Многовато однако.....rastamanoff писал(а):Размер для Atmega328 получился - Program: 6888 bytes (21.0% Full).
Это строка текста,несколько прямоугольников и круг.
Думаю надо будет все таки свой вариант библиотеки состряпать...
Прямоугольники думаю элементарно будет сообразить... а вот остальные фигуры наверное не нужны...
Если нужно вывести чтото более замудреное, легче упаковывать графическую картинку и ее выводить когда надо, как предложл Вадиматоричик ...
Тем более можно сделать эффективность упаковки еще больше, если паковать не горизонтально, а вертикально... скоро предложу и такой вариант...
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
Я тут кой чего намулевал...
Соображаю библиотечку для печати шрифтом размерностью 6х8...
Тогда в строке помещается 21 символ...

Соображаю библиотечку для печати шрифтом размерностью 6х8...
Тогда в строке помещается 21 символ...
- Вложения
-
- chars_screen_low.jpg
- (34.31 КБ) 37132 скачивания
-
aleksandr-zh
- Сверлит текстолит когтями
- Сообщения: 1278
- Зарегистрирован: Пн июн 18, 2007 21:51:20
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
добрый день
подскажите: как выводите символы своего размера на индикатор?
я не могу понять алгоритм
подскажите: как выводите символы своего размера на индикатор?
я не могу понять алгоритм
Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920
В оперативке отводится место под графический буфер дисплея, для данного дисплея это 1024 байта...
Потом печать текстом (в принципе любого размера) идет в этот буфер... (вот тут самые интересные нитересности этой либы заложены
... )
Ну и теперь остается только периодически рефрешить дисплей из этого самого буфера, например 10 раз в сек... или по необходимости...
Потом печать текстом (в принципе любого размера) идет в этот буфер... (вот тут самые интересные нитересности этой либы заложены
Ну и теперь остается только периодически рефрешить дисплей из этого самого буфера, например 10 раз в сек... или по необходимости...