Предисловие
В одной из своих разработок мне потребовалось использовать небольшой монохромный графический LCD экран для вывода информации. После изучения доступности различных моделей я пребывал в легком недоумении: все уважаемые компании, продукция которых представлена на рынке электронных компонентов либо имеет заоблачную цену, либо абсолютно неприемлемые габариты (точнее, соотношение "размер модуля"/"размер видимой области"), либо отвратительные характеристики. Поэтому пришлось обратить внимание на дисплеи, продающиеся как запчасти для сотовых телефонов. В качестве запчасти можно купить экран почти к любому более-менее распространенному телефону, но в силу субъективных причин выбор пал на дисплей от Siemens C55. Технической информации по нему, кроме распиновки, в интернете найти не удалось, зато вариантов графической библиотеки для дисплея от Nokia 3310 обнаружилось минимум варианта три. На мое счастье эти дисплеи оказались очень похожими :-)
Поскольку многие данные были получены экспериментальным путем, вся информация выкладывается без претензий на "истину в последней инстанции". Если она кому-то окажется полезной я буду только рад.
Краткое описание LCD Siemens C55/A55/A52
Самым простым этапом в освоении оказалось приобретение дисплеев в компании "Промэлектроника". Оплатил заказ и через неделю забрал дисплеи. Далее - распиновка. Была взята из сервис-мануала по телефону-"донору". В принципе, она совпадает с распиновкой LCD Nokia 3310.
Плоскость координат дисплея | Нумерация контактов разъема | Распиновка |
Методами дедукции, профессора тыка и такой-то-матери было выяснено, что в дисплее стоит контроллер PCF8812, или очень на него похожий. Максимальное разрешение для контроллера - 102 х 65 точек. Разрешение LCD Siemens C55 - 101 х 64 точки. В дисплее они используются совершенно непонятным для меня образом: вместо 102 точек отображаются только 101, а один столбец просто не использован (но при адресации памяти контроллера всё-равно существует), что при программировании вызывает некоторые ньюансы. Отстутствие одной строки не так критично и на удобстве программирования не сказывается.
При использовании дисплея следует учесть одну тонкость, оговоренную в даташите на контроллер мелким шрифтом: сигнал сброса должен быть активизирован _ДО_ подачи питания, либо не позже, чем 1 мкс после. То есть, сначала обнуляем RST, а потом подаем VDD!
Физический интерфейс у дисплея проблем не вызывает: классический SPI, работающий только на ввод. Инициализация и вывод информации (когда уже знаешь, как оно должно быть!) тоже просты до безобразия. Картинка четко видна без подсветки. По сравнению с Nokia 3310 - точки мельче, зато их число несколько больше. Цена и на тот, и на другой - 100-200 рублей (на апрель 2007г).
Железо
Для подключения была использована вот такая схема на основе ATmega168. Напряжение VCC подавалось 5 V, несмотря на то, что штатно дисплей должен питаться от 2.9 V. Пока полет нормальный. Да и если верить даташиту на PCF8812 - это вполне допустимо. Пара комментариев к схеме. Несмотря на наличие режима PowerDown в контроллере дисплея, питание на LCD было подано от порта микроконтроллера. Это сделано как раз для того, чтобы можно было сначала активировать сигнал RST, а уже после этого подавать питание. Резистор R1 ограничивает ток заряда конденсатора C2 в момент подачи питания на дисплей. Часовой кварц можно не ставить, мне он был нужен для асинхронного тактирования второго таймера ATmega168. Обвязка вокруг AVCC в-общем то тоже не является необходимой для работы индикатора. Конденсаторы C7 и C8 можно выкинуть, а резистор R4 замкнуть. Разъем XP1 предназначен для подключения программатора. В моем случае использовался AVReal с адаптером Altera Byte Blaster.
Софт
Файл тестовой программы можно скачать отсюда, а скомпилированная прошивка лежит здесь. В этой программе нет графических библиотек, а есть только инициализация и простейший тестовый вывод. В подробные комментарии вдаваться не буду, отмечу лишь основные моменты. Строки типа
#define LCD_RST_DDR DDRD_Bit4
#define LCD_RST_PORT PORTD_Bit4
#define LCD_RST_PIN PIND_Bit4
задают символические имена битам портов, к которым подключен дисплей. Соответственно в тексте программы всегда используются именно они, значения устанавливаются индивидуально для каждого бита даже там, где можно обойтись одной командой пересылки значения в порт: при отладке так удобнее.
В тексте есть также функция для инициализации LCD-дисплея Nokia 3310 с контроллером PCD8544 на борту. Если понадобится - закомментируйте вызов LInitSiemensC55 и раскомментируйте LInitNokia3310. Функция LInitPCF8812 осталась "в наследство". Назначение функций:
void LSend ( unsigned char, char ); - пересылка байта в дисплей. От второго параметра зависит, что передается, команда или данные.
void LOn(void); - подача питания на дисплей.
void LReset (void); - сброс дисплея
void LInitSiemensC55(void); - инициализация дисплея Siemens
void LInitNokia3310(void); - инициализация дисплея Nokia
void LInitPCF8812(void); - инициализация контроллера PCF8812 (аналогична C55)
void LTestOut(void); - вывод тестовой картинки
void SInit(void); - инициализация SPI микроконтроллера
void Delay(unsigned int); - задержка, при тактовой частоте 8МГц - параметр определяет время задержки в микросекундах
void Delay2(unsigned int); - то же, но в миллисекундах
Поскольку требовалась максимально гарантированная инициализация, многие задержки в реально работающем устройстве можно убрать. Кроме того SPI инициализирован на самую медленную из возможных скоростей работы. Это тоже целесообразно изменить. Особо отметить нужно строки инициализации параметров "Internal HV-gen", "Set Vop" и "Bias". От них, грубо говоря, зависит контрастность изображения и в конечном итоге видимость изображения в принципе. Если дисплей вообще ничего не будет показывать, или показывать очень слабо - нужно увеличивать значение Vop и Bias (за подробностями отсылаю к даташиту, который есть на странице по ссылке выше). Если экран становится черным - эти значения нужно уменьшать.
Самой большой неприятностью для меня явилось то, что у дисплея остутствуют какие бы то ни было статусные регистры, доступные для чтения. Поэтому признаком корректного подключения и работы по SPI может служить напряжение на выводе 7 дисплея. Это напряжение должно меняться, когда в инициализации меняется значение "Set Vop" и "Bias" и, частично, "Internal HV-gen".
Вот что должно получиться на экране |
Если кто всерьёз решит использовать приведённый выше исходник, могу порекомендовать убрать лишние задержки, которые были использованы при отладке для вящей надёжности. Либо, что намного правильнее, переписать функции на режим работы с прерыванием от SPI. Не самая простая задача, но оправданная. Хотя при использовании ATmega168 (ATmega88) основная неприятность всё же в том, что видеобуфер съедает почти всю имеющуюся в микроконтроллере SRAM.
20 апреля 2007
P.S. При программировании следует учесть, что пикселы на этом дисплее либо не строго квадратные, либо размещены с разным шагом по X и по Y, соотношение X/Y ~= 19/20, что заметно при отрисовке окружностей, если смотреть под прямым углом. Если смотреть с "естественного" для сотовика направления - получается как раз окружность :)
Добавлено 3 мая 2007
Существенное дополнение!
По ссылке автор утверждает следующее: "...но там маленькая ошибка в исходнике,не включен PRS для контрллера LCD. Не буду спорить может другие дисплей и без него работают но у меня из двух LCD ни один не показывал пока не включил PRS." Я не проверял, но возможно он прав!
Добавлено 14 декабря 2018