Короткая памятка по подключению.
Дисплей дурной. Но поскольку он есть - надо писать.
RST. Резет - он и в Мордорской домне резет. Активный уровень - низкий. Согласно ДШ должен удерживаться не менее чего то там. У меня это "чего то там" - 70 мс. После отпускания резета до отправки команд нужно подождать еще пару-тройку мс.
Дисплей может работать как по параллельному, так и по последовательному интерфейсу. За это отвечает контакт PSB.
Если этот контакт соединен с землёй - интерфейс последовательный. Если через 4к7 подтянут к питанию - параллельный 4/8-битный. (Сразу скажу, 4-битный не пробовал).
Тут есть мелкая засада. На некоторых ревизиях дисплея PCB может быть перемычкой или пофигистором притянут к питанию или земле. Мультиметр решает. Если таки да - найди и отпаять. Внизу по одной из ссылок (на drive2 ru) как раз и описана такая ситуация.
Вроде всё красиво, но дьявол кроется в деталях. Проблема в том, что обработка любой команды выполняется за время не менее 72 мкс. Т.е. отправил команду - жди 72 мкс. Отправил байт данных - жди 72 мкс... и т.д.
Те несколько дисплеев, что у меня были - вели себя по разному. Один удалось "разогнать" до 64 мкс. Второй нормально работал при периоде 78 мкс. В интернетах пишут, что некоторые экземпляры гнались до периода в 36-40 мкс.
Итого - время обновления дисплея - это отправка 1024 байт данных + 128 командных байт.
В идеальном случае - 1152 байт * 72 мкс = приблизительно 83 мс. Или 12 fps.
Питание и контрастность.
Параллельный режим.
Линия RS - признак данных/команды:1-данные, 0-команда
Линия R/W - чтение/запись данных. 1 - чтение, 0-запись. Данные можно не читать, а просто прижать линию к земле.
Строб E. В режиме ожидания - 0. После выставления уровней RS и R/W не ранее чем через 10 нс строб E переводится в 1.
На выводах D0-D7 выставляются данные для записи в дисплей. После выставления данных до опускания строба E в 0 должно пройти не менее 40 нс. Данные записываются в момент перехода строба в 0.
Следует учесть, что длительность нахождения строба в 1 должна быть не менее 140 нс.
После отпускания строба данные на шинеD0-D7, а так же сигнал R/S должны присутствовать без изменений еще 20 нс.
В применении к AVR указанные тайминги соблюдаются "автоматически", ибо 1 такт AVR при тактовой частоте 16 МГц составляет 62,5 нс.
Затык может быть только при подряд идущих трех ассемблерных командах Поднять строб, выставить данные, опустить строб. Там получится 125 нс, а не 140. Но один NOP после выставления данных решает. Хотя можно попробовать без NOP - может и 125 нс пойдут. Либо поднять строб, прочитать данные из памяти, положить их в порт, опустить строб. При тактировании МК от 8 МГц - вообще париться не надо. Если в руки попал STM - ну тут нужно смотреть на тактирование и помнить про тайминги.
Последовательный режим.
В некотором смысле последовательный режим проще - меньше GPIO занято, в некотором смысле - сложнее. Там каждый байт + флаг команда/данные раскладывается в три байта. Т.е. мечта AVR-щка - запхал байт в SPI и пошел дальше репу чесать - разбивается об суровую реальность. Нужно отправить подряд три или шесть (для 2-байтовой команды) байт. При этом период тактовой частоты SPI не должен быть менее 600 нс ( <1.66(6) МГц), длительность низкого и высокого уровней - не менее 300 нс.
По факту дисплеи заводятся и на 1.75 МГц. На 2 МГц - уже начинаются глюки. Т.е.для AVR при его типовых тактовых 8 или 16 МГц частота для SPI выше 1 МГц не светит. Разве что с кварцем в 12 МГц. Т.е. отправка трех байт - чистое время 24 мкс + накладные расходы на ожидание готовности SPI. 6 байт - все 48+ микросекунд. И так - каждые 72 мкс. Можно мутить "конвеер" на прерывании SPI - но накладные расходы уменьшатся незначительно. Просто переползут из цикла ожидания на вход в / выход из обработчика прерывания. Итого - 40-70% времени AVR проводит, ублажая дисплей. Поэтому для AVR лучше использовать параллельный режим. Хотя, если это какие-нибудь домашние часы с термометром - то им пофиг.
В этом месте STM-щики злобно почешут ручки, разразятся демоническим хохотом и скажут - а у нас есть DMA - и будут правы. Во-первых частоту ядра можно поднять до невиданных для AVR десятков, а то и сотен мегагерц. Во-вторых - подбором тактовой частоты, коэффициентов ФАПЧ и делителей шин частоту SPI можно поднять до 1.5 (и даже до 1.75) МГц. Т.е. по таймеру быстро собрать в буфер 3 или 6 байт, скормить их DMA и дальше репу чесать.
Ну и собственно, как подключить дисплей в последовательном режиме.
RS выступает как сигнал CS - Chip select, idle-уровень - низкий, активный - высокий.
E остается сигналом строба (CLK), активный уровень низкий, idle - высокий.
Линия R/W - теперь это данные (DATA). Данные считываются в момент перехода CLK (E) из низкого уровня в высокий.
Данные на линии DATA должны быть выставлены минимум за 40 нс до перехода CLK из низкого в высокий уровень и должны там удерживаться еще не менее 40нс после перехода.
Т.е. для аппаратного SPI применяем вот такие настройки:
CPOL=1 (SCK is high when idle, Leading edge is falling)
CPHA=1 (Sample on trailing edge)
Теперь о грустном. Три или шесть байт - вот в чем вопрос.
Первый байт: 1 1 1 1 1 RW DC 0
DC - признак данных или команды, 1-данные, 0-команда, RW - 0-запись данных (мы данные из дисплея не читаем, хотя могём). Итого: 0xF8 - для команды, 0xFA - для данных.
Второй байт: D7 D6 D5 D4 0 0 0 0 - старший ниббл байта команды/данных
Третий байт: D3 D2 D1 D0 0 0 0 0 - младший ниббл байта команды/данных
В случае двухбайтовой команды (команда и аргумент) - вторые 3 байта аналогичны первым трем - такой же байт с флагами и 2 байта с нибблами аргумента команды.
Резюмируя последовательный режим:
1. Подняли с земли CS (RS)
2. Отправили три или шесть байт.
3. Положили CS назад на землю.
Инициализация дисплея
Дисплей имеет 2 режима работы - графический и текстовый (включен по умолчанию).
В текстовом режиме дисплей имеет 4 строки и 16 знакомест на строку, в графическом режиме разрешение: 128x64 пикселя. При этом можно что то написать в текстовом режиме, переключиться в графику и там еще порисовать. Картинки сложатся по XOR.
С учетом того, что 16 х 4 символа, да еще и без кириллицы, нам не интересно - нужно включать графический режим.
Итого:
1. Прижать резет к земле на 70 мкс.
2. Поднять резет с земли, подождать 3 мкс.
3. Отправить команду 0x30 - включение текстового режима.
4. Отправить команду 0x01 - очистка текстового дисплея
5. Отправить команду 0x36 - включение расширенного (графического) режима.
После команд смены режимов где то рекомендовали ждать порядка 5мс.
Формат данных, организации видеопамяти и команд в графическом режиме напишу когда-нибудь позже.
Драйвер дисплея
Полезные ссылки
https://www.waveshare.com/datasheet/LCD_en_PDF/ST7920.pdf - даташит
https://habr.com/ru/post/213459/
http://avrprog.blogspot.com/2013/12/lcd-12864-st7920-8.html
https://radiokot.ru/forum/viewtopic.php?p=1888519
https://github.com/WiseLord/ampcontrol/blob/m32/display/st7920.c?ts=4
Интересно, полезно, спасибо!
ОтветитьУдалитьобращайтесь!
Удалить