Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 11:25:55

Вот ещё возник один вопрос.

В параллельном режим можно данные в дисплей посылать "пачками", то есть:
Фаза 1: RS = 0, D7-D0 = Адрес Y, строб
Фаза 2: RS = 0: D7-D0 = Адрес X, строб
Фаза 3: (RS = 0: D7-D0 = данные, строб ) * 32 раза подряд, после чего нужно снова устанавливать адреса (переходить в режим команд)

Между стробами нужно обеспечить не менее 50мкс. Это наиболее удобный вариант в случае работы с экранным буфером, можно использовать таймер для обеспечения 50мкс интервалов. Вот, например, моя реализация такого прерывания.

Интересно, есть ли возможность и в режиме SPI передавать не три байта данных (режим - старшие биты - младшие биты), а лишь два последних. Наверное, нельзя, и последовательность 11111(RW)(RS)0 должна присутствовать всегда.

И ещё интересно, 50мкс в этом случае надо обеспечивать лишь между группами по 3 байта, или между каждыми байтами, т.е.
11111(RW)(RS)0 - 50мкс - HHHH0000 - 50мкс - LLLL0000 - 50мкс
или достаточно
11111(RW)(RS)0-HHHH0000-LLLL0000 - 50мкс

Второй вариант хорош тем, что можно организовать SPI на очень быстрой скорости, а задержку 50мкс опять же организовывать таймером, не тратя времени на пустое ожидание.

Кстати, тут ранее писали, что можно SPI настроить на более медленный режим и якобы не заботиться о задержках, мол, всё будет обеспечиваться аппаратно. Но хрен редьки не слаще. Какая разница - быстрый SPI + _delay_us(50); или медленный SPI и висение а-ля while (SPI_is_ready())? Так или иначе процессор полезного кода не выполняет в это время, вися в ожидании.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 13:59:17

WiseLord писал(а):В параллельном режим можно данные в дисплей посылать "пачками", то есть:
Фаза 1: RS = 0, D7-D0 = Адрес Y, строб
Фаза 2: RS = 0: D7-D0 = Адрес X, строб
Фаза 3: (RS = 0: D7-D0 = данные, строб ) * 32 раза подряд, после чего нужно снова устанавливать адреса (переходить в режим команд)
Ну в последовательном то же самое... установил адрес и шуруй 32 байта данных... потом адрес следующей строки... и т.д.
Обрати внимание как у меня сделана очистка экрана LcdClear ();

WiseLord писал(а):Между стробами нужно обеспечить не менее 50мкс.
Вот об этом я даже не позаботился... у меня шурует подряд (за исключением пару нопов) и все работает... мож это касается только параллельного режима??? или может это должно обеспечиваться между сменами адресации???
Хотя у меня где то есть и параллельная реализация, пороюсь, посмотрю как я там делал...

WiseLord писал(а):Интересно, есть ли возможность и в режиме SPI передавать не три байта данных (режим - старшие биты - младшие биты), а лишь два последних. Наверное, нельзя, и последовательность 11111(RW)(RS)0 должна присутствовать всегда.
Наверное всегда должно быть вначале 11111(RW)(RS)0

WiseLord писал(а):И ещё интересно, 50мкс в этом случае надо обеспечивать лишь между группами по 3 байта, или между каждыми байтами, т.е.
11111(RW)(RS)0 - 50мкс - HHHH0000 - 50мкс - LLLL0000 - 50мкс
или достаточно
11111(RW)(RS)0-HHHH0000-LLLL0000 - 50мкс
Ну в общем как я и сказал - этой задержки у меня вообще нет... надо разобраться почему у меня работает и где это вообще должно быть... возможно что это касается параллельного режима...

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 14:50:54

Как я понял, Вы просто частоту SPI довольно низкую сделали, вот оно и укладывается в 50мкс само по себе

50мкс - это на передачу всей посылки, т.е. 24 бит. Вот и получается, что скорость SPI нужна порядка 24*(1/50мкс) = 500кбит/с, тогда и задержки не нужны.

За 50мкс отрисовывается 8 точек, значит весь экран - за 50мс приблизительно. Вполне быстро, но вот в течение этого времени контроллер будет "висеть" - ну, не считая возможных прерываний, само собой.

Кстати, что Вы имеете в виду, говоря о некоем "текстовом буфере"? Ведь, по идее, если экономить память и буферизовать не весь экран (1КиБ ОЗУ), а некий текстовый буфер, требующий в 8 раз меньше памяти, мы фактически привязываемся к определённым позициям символов. То есть, максимум 16 букв в ширину с большими расстояниями между ними. Как-то это не очень красиво выглядеть будет, слишком разреженно.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 16:39:54

WiseLord писал(а):50мкс - это на передачу всей посылки, т.е. 24 бит. Вот и получается, что скорость SPI нужна порядка 24*(1/50мкс) = 500кбит/с, тогда и задержки не нужны.
Возможно... наверное при программном формировании потока скорость примерно такая и будет...

WiseLord писал(а):За 50мкс отрисовывается 8 точек, значит весь экран - за 50мс приблизительно. Вполне быстро, но вот в течение этого времени контроллер будет "висеть" - ну, не считая возможных прерываний, само собой.
Обычно реалтайм функции реализуются в прерываниях, так что тут проблем нет... а вот все остальное - типа отработки результатов нажатий кнопок, ветвлений алгоритмов, и прочих телодвижений в майне - тут 50мс вааще погоды не делают... тем более что отрисовка обычно нужна именно ПОСЛЕ какого то из этих событий...

WiseLord писал(а):Кстати, что Вы имеете в виду, говоря о некоем "текстовом буфере"? Ведь, по идее, если экономить память и буферизовать не весь экран (1КиБ ОЗУ), а некий текстовый буфер, требующий в 8 раз меньше памяти, мы фактически привязываемся к определённым позициям символов. То есть, максимум 16 букв в ширину с большими расстояниями между ними. Как-то это не очень красиво выглядеть будет, слишком разреженно.
Согласен... не очень красиво... но для самых простейших применений пойдет... вот как выглядит такой вариант http://asis-kbr.ru/forum/viewtopic.php?p=1168#p1168

Как нибудь, хочу сделать вариант 21х8 символов... будет чуть покрасивше...
Проблема в том, что в ST7920 байты располагаются горизонтально, и формировать символы в 6 пикселей шириной чуть заморочено... но решаемо, я так на спектрумах делал, там тоже на экране байты горизонтально лежали...

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 17:21:26

Да, горазонтальные байты в ST7920 - это печально.

Я свой проект изначально делал на ATmega16 под KS0108 и шрифт делал с вертикальными байтами. Оно и компактнее получается, и можно делать пропорциональный шрифт, с разной ширины символами.

Так вот, когда начал добавлять поддержку ST7920, пришлось делать следующим образом:
- завести буфер в 128 байт (длина одной из 8-ми текстовых строк)
- вычитывать из памяти ST7920 в этот буфер
- менять что надо в буфере (скажем, текст туда выводить)
- возвращать буфер назад в ST7920.

Получалось достаточно медленно, за счёт чтения - вдвое медленнее, чем просто бы выводить данные на экран. Но ничего лучше не придумывалось, памяти у МК было маловато.

Позже, когда на ATmega32 перешёл, выделил целый половину ОЗУ - килобайт - под кадровый буфер. Основной код просто пишет данные в этот буфер, а уже в прерывании (раз в те самые 50мкс) берётся очередная порция данных (или команда, если её черёд) и посылается в дисплей - без всяких задержек, максимально быстро.

В итоге получается крайне быстрая реализация вывода. Необходимые данные - текст, графика, да что угодно - просто и быстро записываются в этот буфер, а уже из прерывания это всё дело попадает в реальный дисплей. Итого - порядка 18 обновлений экрана в секунду "в фоне" и этот вывод совершенно не блокирует основной поток программы, замедляя его от силы на процентов 5.

Собственно, вот так это и работает потом на ST7920 - хватает времени и на анализ Фурье, и на обработку кнопок, пульта и прочие красоты:

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 18:54:54

WiseLord писал(а):Кстати, тут ранее писали, что можно SPI настроить на более медленный режим и якобы не заботиться о задержках, мол, всё будет обеспечиваться аппаратно. Но хрен редьки не слаще. Какая разница - быстрый SPI + _delay_us(50); или медленный SPI и висение а-ля while (SPI_is_ready())? Так или иначе процессор полезного кода не выполняет в это время, вися в ожидании.
Кто сказал "Мяу"?!. Я же выдал расчет, медленный SPI будет выдавать один байт из трех (8 бит из 24) в течение 128 тактов. А на обслуживание прерывания, сохранение-восстановление, выдачу нового байта в РД SPI и пр., нужно, максимум, 20-30 тактов (на асме, вестимо). Так, что спокойно переносим выдачу через SPI в прерывания, свободная сотня тактов на любые действия останется. То есть сотню или чуть больше тактов занимаемся своими делами, 20-30 тактов тратим на прерывание от SPI и связанные с ним дела. Если часть условно свободного времени (в смысле часть основной задачи) будет при закрытых прерываниях, максимум неприятностей - это очередной байт будет передан с задержкой, да и на здоровье - кроме замедления выдачи на экран это ничем не грозит.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 19:15:46

WiseLord писал(а):Позже, когда на ATmega32 перешёл, выделил целый половину ОЗУ - килобайт - под кадровый буфер. Основной код просто пишет данные в этот буфер, а уже в прерывании (раз в те самые 50мкс) берётся очередная порция данных (или команда, если её черёд) и посылается в дисплей - без всяких задержек, максимально быстро.

В итоге получается крайне быстрая реализация вывода. Необходимые данные - текст, графика, да что угодно - просто и быстро записываются в этот буфер, а уже из прерывания это всё дело попадает в реальный дисплей. Итого - порядка 18 обновлений экрана в секунду "в фоне" и этот вывод совершенно не блокирует основной поток программы, замедляя его от силы на процентов 5.

Собственно, вот так это и работает потом на ST7920 - хватает времени и на анализ Фурье, и на обработку кнопок, пульта и прочие красоты:

Я сравнил этот подход со своим. Как я понимаю, вся разница в том, что у меня прерывания получаются втрое чаще - с параллельным интерфейсом байт передается за один прием, а в последовательной передаче - в три приема, для программы на Си это, скорее всего, существенно. Зато проводов меньше...

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 19:47:30

WiseLord писал(а):Собственно, вот так это и работает потом на ST7920 - хватает времени и на анализ Фурье, и на обработку кнопок, пульта и прочие красоты:
Неплохо неплохо :shock:
Как я понял - это KS0108? или все таки ST7920? просто обычно у ST7920 - экран синий...


Кстати, вот как будет смотреться вариант с 21 символом по горизонтали... http://forum.cxem.net/index.php?showtop ... try1811878

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 21:18:28

afz писал(а):Так, что спокойно переносим выдачу через SPI в прерывания, свободная сотня тактов на любые действия останется. То есть сотню или чуть больше тактов занимаемся своими делами, 20-30 тактов тратим на прерывание от SPI и связанные с ним дела.
Да, но при таком подходе всё равно нужен какой-то буфер в ОЗУ, из которого "параллельный поток кода" на базе прерываний будет брать очередной байт для записи в дисплей, в идеале - те же 1КиБ на хранение всего кадра.

Поэтому такой подход, равно как и мой, относительно равнозначны. Разница в том, что у меня - максимально быстрый обмен (по SPI, либо параллельный режим - не так важно), а необходимые 50мкс обеспечены прерыванием от таймера, а у Вас - более медленный аппаратный SPI, обеспечивающий те же 50мкс уже своим прерыванием.

Но опять же, без некоего буфера оба эти подхода не имеют смысла.
afz писал(а):Я сравнил этот подход со своим. Как я понимаю, вся разница в том, что у меня прерывания получаются втрое чаще - с параллельным интерфейсом байт передается за один прием, а в последовательной передаче - в три приема, для программы на Си это, скорее всего, существенно. Зато проводов меньше...
Ну так-то да. Но я не заморачивался с SPI, поскольку проект поддерживает ещё и KS0108 (да и начинался с него). Поэтому смысла городить SPI не было, т.к. всё равно ноги D0-D7 заняты дисплеем, а параллельный интерфейс всё же максимально быстрый.

Кстати, вполне можно Ваш подход и мой совместить. Идея следующая:
а) Раз в 50 мкс таймер вырабатывает прерывание - как у меня и было.
б) По прерыванию от этого таймера у меня в параллельном режиме в это время берётся очередной байт (данных или команды - не важно) и пишется (стробируется) в дисплей. В случае SPI нужно по прерыванию от таймера этот байт просто разложить на три части, включить прерывание SPI и стартовать передачу по SPI первой части
по прерыванию SPI стартовать передачу второй части
по прерыванию SPI стартовать выключить прерывание SPI и начать передачу последней трети
Если SPI настроить на максимальную частоту (8МГц при 16МГц), получится, вся передача по SPI займёт около 5мкс (3мкс на три байта плюс небольшие накладные расходы на обработку прерывания), остальные 45мкс контроллер будет делать полезную работу. Да и между прерываниям SPI будет ещё некоторое "полезное" время. То есть, выглядеть это во времени будет как-то так:
Код:
___|Thh__Shh__Shh_______________________~_______|Thh__Shh__Shh_______________________~_______|Thh__Shh__Shh________
   |     5us     |                     45us     |     5us     |                     45us     |     5us     |       

(здесь T,S - прерывания от таймера и SPI, hh - время нахождения в обработчиках прерывания, ___ - полезная работа контроллера. ~ - просто "разрыв" временной шкалы)
В принципе, можно особо и не заморачиваться, и делать по-вашему:
Код:
___|Shh____________Shh____________Shh___________|Shh____________Shh____________Shh___________|Shh____________Shh____
   |     17us     |     17us     |     17us     |     17us     |     17us     |     17us     |     17us     |       
, но не забывать отслеживать, какую именно треть данных сейчас передаём, и когда переходить к следующей (у меня это однозначно определяется таймером)
shads писал(а):Как я понял - это KS0108? или все таки ST7920? просто обычно у ST7920 - экран синий...
Это именно ST7920.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июн 30, 2016 21:58:01

WiseLord писал(а):Это именно ST7920.
Чет дороговатый какой то...
Вот тут подешевле http://ru.aliexpress.com/item/128-64-DO ... 9714fa5575

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пт июл 01, 2016 07:52:23

Покупал давно, два года назад. Пара стоила тогда $15,75 с учётом доставки с нормальным треком, на тот момент цена была нормальной.

Да и по Вашей ссылке цена с доставкой $15,69 за пару - не особо и отличается.

С тех пор цены на ST7920 упали (почему-то по этой ссылке выросли), да и белых на синем стало много. Недавно покупал здесь, пару за $12,10 с учётом доставки с нормальным треком. А сейчас и ещё чуть дешевле стало, смотрю.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Сб июл 02, 2016 06:55:03

WiseLord писал(а):Да, но при таком подходе всё равно нужен какой-то буфер в ОЗУ, из которого "параллельный поток кода" на базе прерываний будет брать очередной байт для записи в дисплей, в идеале - те же 1КиБ на хранение всего кадра.
Необязательно, зависит от того, что надо выводить. Я прикидываю метеостанцию, собираюсь рисовать график изменения атмосферного давления. Такую картинку можно генерить "на лету". Чисто текстовую строку также можно генерить на лету. Впрочем, небольшой буфер FIFO не помешает...

WiseLord писал(а):Ну так-то да. Но я не заморачивался с SPI, поскольку проект поддерживает ещё и KS0108 (да и начинался с него).
Тогда, конечно, понятно.

WiseLord писал(а):Поэтому смысла городить SPI не было, т.к. всё равно ноги D0-D7 заняты дисплеем, а параллельный интерфейс всё же максимально быстрый.
Как мы видим, скорость тут ни разу не нужна. А вот ноги поэкономить вполне можно, моя проектируемая метеостанция имеет реальный шанс влезть в 8-ю Мегу. Не хватит памяти (ОЗУ, флеши мне хватит по-любому, писать буду на асме), поставлю 328-ю Мегу.

WiseLord писал(а):Если SPI настроить на максимальную частоту (8МГц при 16МГц), получится, вся передача по SPI займёт около 5мкс (3мкс на три байта плюс небольшие накладные расходы на обработку прерывания), остальные 45мкс контроллер будет делать полезную работу. Да и между прерываниям SPI будет ещё некоторое "полезное" время.
Увы, не выйдет. У 7920 ограничение по частоте SCLK 2.5 МГц. (В ДШ прямо это не заявлено, но длительность импульса и длительность паузы не должны быть меньше 200 нс каждый, итого минимальный период SCLK 400 нс.) Да и таймер может пригодится для чего-то другого - зачем использовать еще и таймер, когда SPI справится с этим ничуть не хуже? Таймер здесь - классическая лишняя сущность.

Тем более, при 16 МГц делитель можно поставить 32, это 256 тактов на передачу 8 битов из 24, при такой частоте прерываний накладные расходы на них становятся несущественными.

WiseLord писал(а):И ещё интересно, 50мкс в этом случае надо обеспечивать лишь между группами по 3 байта, или между каждыми байтами, т.е.
11111(RW)(RS)0 - 50мкс - HHHH0000 - 50мкс - LLLL0000 - 50мкс
или достаточно
11111(RW)(RS)0-HHHH0000-LLLL0000 - 50мкс
Во-первых, не 50 мкс, а 72 мкс. 50 - это разгон. Тут на предыдущих страницах кто-то отписался, что разгонять можно до 33 мкс, при меньшем времени цикла (большей частоте передачи данных) появляются артефакты.

Во-вторых, времянка SPI в ДШ одна сплошная на 24 бита, без пауз между отдельными байтами.

Интересно, есть ли возможность и в режиме SPI передавать не три байта данных (режим - старшие биты - младшие биты), а лишь два последних. Наверное, нельзя, и последовательность 11111(RW)(RS)0 должна присутствовать всегда.
А вот это тоже интересно. Как я понимаю, если регулярно дрыгать 4-й ножкой дисплея (CS ), то точно нельзя, ибо где-то в ДШ упоминается, что она сбрасывает весь автомат обмена по SPI. А вот если CS оставить в единице, то черт его знает, что там будет. Или дисплей заработает, или его расколбасит по-тяжелому... :)

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Вт мар 21, 2017 21:38:30

кто нибудь защепил st7920 режиме spi по DMA?

afz писал(а):А вот если CS оставить в единице, то черт его знает, что там будет

оно так работает .... Но нужно делать паузу между через каждые 2 байта ... чтобы дисплей их переварил ...

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Вт апр 18, 2017 12:19:29

Доброе. Решил попробовать оживить свой 128*64 дисплей. Столкнулся с проблемой. При включении дисплея все пиксели подсвечены. Если выключать их последовательно, по одному, то они нормально все выключаются. Потом так же все нормально по одному включаются. Но! Нарисовал картинку 128*64, конвертнул её в хекс код, вывожу на дисплей. Нижняя строка (получается 7-ая), в ней какой-то мусор. Данные вывожу на дисплей побайтно: седьмая строка нулевой столбец, шестая строка нулевой столбец... ... нулевая строка 127-о1 столбец. И вся седьмая строка косячная. Данные которые в неё выводятся, смотрел по массиву который туда выводится - нормально всё. Дисплей фигню выводит. Пробовал три разных. Не помогает. Сказать что скорость слишком большая, так у меня камушек MCS-51. Кварц на 12 МГц. Тут прям вообще нельзя грешить на то, что в тайминги не вписываюсь. Дисплеи все рабочие, не фуфлыжно-китайско-неизвестного производства. Ранее были установлены в банковских платёжных терминалах :)

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Вт апр 18, 2017 14:19:01

krepitsin писал(а):Нижняя строка (получается 7-ая)
Тут, ЕМНИП, другая организация. Всего 32 строки, по 32 байта каждая. Байты ложатся горизонтально. Если писать последовательно данные, то первые 16 байт занимают всю верхнюю строчку, далее строка продолжается во второй (нижней) половине дисплея.

Между посылками данных нужно выдерживать 50мкс (возможно, и больше по даташиту).

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Вс апр 23, 2017 07:39:57

Может я не так что-то понимаю. Но у этого дисплея 2 части (64*64 pix). В каждой по 8 строк в которой по 8 пиксов. Или мы про разные вещи говорим?

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Вс апр 23, 2017 09:16:05

Нет, два по 64x64 - это у KS0108, там для выбора левой и правой половины и служат ноги CS1 и CS2. И фактически - там две половины, в каждой по 8 строк 64 вертикальных байтов. А у ST7920 совсем другая адресация, и байты горизонтальные.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Вс апр 23, 2017 18:44:47

Прошу покорнейше извинить меня. Не в ту тему залез. Только зарегистрировался на форуме. У меня как раз ks0108 контроллер. Пойду искать искать ответы в других темах.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пн июн 12, 2017 14:22:04

Мож кому будет полезен примерчик использования простой либки для дисплея ST7920, используется текстовый буфер 16х8 символов (128 байтов). Графики нет, зато либа занимает немного места... к примеру - легко можно использовать с мега8.
В проекте реализована работа и с ST7920 и с KS0108, так что можно работать в протеусе переключившись на KS0108 (в протеусе вроде нет ST7920), а когда все отлажено, можно переключиться на ST7920 и заливать в железо с дисплеем ST7920...
Вложения
DISPLAY_128x64.7z
(47 KiB) Скачиваний: 675

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пн июн 12, 2017 16:32:55

Большое спасибо за пример с библиотекой. Для моих скромных нужд то что надо.
Ответить