неділю, 8 січня 2017 р.

Дисплей Nokia 5110 на контролері PCD8544 - огляд

Власне, LCD Nokia 5110.
Фото звідси, там же можна зразу й
купити, хоча в китайців - дешевше.
Часто доводиться стикатися із цим симпатичним, хоч і зовсім простеньким, дисплеєм, нарешті вирішив описати, як він працює та як його програмувати.

Називають його Nokia 5110, за іменем телефону, де використовувався (також його використовувала Nokia 3310).  У ньому використано контролер дисплея Philips PCD8544.

Для визначеності, розглядатимемо на прикладі китайського модуля, типу того, що на фото праворуч. Adafruit стверджує, що самі дисплеї більше не випускаються -- в продажу старі запаси, але зріє в мене підозра, що китайці їх таки виготовляють потроху.

Апаратура

Фізичні характеристики

  • Дисплей -- чорно-білий.
  • Діагональ: 1.5" або 38 мм.
  • Роздільна здатність -- 48x84 пікселі. 
  • Розмір модуля -- порядку 45 на 45 мм.
  • Робочою напругою контролера є 2.7-3.3В, тому, якщо мікроконтролер працює на 5В, як, скажімо, Arduino Uno/Mega, потребуватиме перетворювач рівнів.
    Не робіть так, якщо вам шкода вашого дисплею, але, як показує практика, якщо його живити від 3.3В, то, зазвичай, він нормально витримує 5В сигнали на входах. Зрозуміло, це зменшує час життя і взагалі -- ніяких гарантій.  
  • Напругу для LCD контролер PCD8544 вміє генерувати сам, хоча дисплей можна живити і окремо (потребує 6-9В). Модуль, що розглядається, живить дисплей від внутрішнього генератора контролера.  
  • Струм через піни -- до 10мА. Обіцяють, що на практиці цей струм складатиме не більше 300 мкА.
    Знаючи цей факт, найпростіший перетворювач рівнів із 5В до 3.3В можна зробити, включивши між піном 5В мікроконтролера та піном дисплея, резистор на 10 кОм -- спад напруги на ньому приблизно підгонить напругу до потрібного рівня. Халтура, зате проста. І надійніша, ніж просто подати 5В та вірити у краще майбутнє.
  • Однак, підсвідка у модулі зібрана незалежно від контролера -- це просто чотири білих світлодіоди без резисторів, які обмежують струм.  Вони споживатимуть порядку 80мА, але споживання може доходити до 300 мА.
    Пін підсвітки модуля під'єднано до транзистора. Тому, з одного боку, можна керувати їх яскравістю за допомогою ШІМ (PWM), з іншого  -- напругу більше 3.3В подавати на них, не використовуючи додатковий резистор на 100Ом і більше, не можна! Так само не можна живити підсвітку безпосередньо від пінів мікроконтролера -- вони просто не здатні віддати такий струм, не вийшовши з ладу.
  •  Робочий діапазон температур: -25 -- +70 °C.
  • УВАГА!!! Різні китайські модулі можуть мати зовсім інше розташування пінів, навіть якщо виглядають ідентично!

Інтерфейс

  • Для керування потребує 5 пінів. (Хитруючи із схемотехнікою, можна обійтися меншою кількістю).
  • Обмін даних відбувається послідовним інтерфейсом, схожим на однонаправлений SPI. Для передачі можна використовувати апаратні SPI мікроконтролерів.
  • Максимальна швидкість передачі даних послідовним інтерфейсом -- 4Мбіт/с.
  • Передача -- побайтова (8 біт за раз), починаючи із старшого (MSB):

  • Містить внутрішню RAM -- "відеопам'ять" на 48х84 біт (504 байти).

Робота із контролером PCD8544

Модуль, із яким працюємо, виглядає так:

УВАГА! Завжди перевіряйте маркування пінів! В дикій природі трапляється декілька абсолютно несумісних комбінацій! Які, при тому, візуально можуть бути дуже схожими.
Розглянемо його виводи-піни:
  • GND --- "земля".
  • LIGHT -- підсвітка. Якщо його заземлити, вона засвітиться. Якщо напруга живлення більша за 3.3В, використовуйте резистор для обмеження струму.
  • VCC -- живлення, 3.3В. (Можна менше, більше не треба.)
  • RST -- перевантаження мікроконтролера. Інвертований вхід -- активним є низький рівень, 0!  Тобто, поки на ньому 1 -- дисплей не перевантажуватиметься. 
  • DC -- власне, правильніше . Низький рівень -- відбувається передача команд, високий -- даних.
  • CE --  Chip Enable. CS в термінах SPI. Інвертований вхід -- активним є низький рівнь, 0. Тобто, щоб звертатися до дисплею, слід сюди подавати 0. 
  • CLK -- тактовий сигнал послідовного інтерфейсу. Активний -- високий рівень, 1. SCK в термінах SPI.
  • DIN -- вхідні дані послідовного інтерфейсу.  Активний -- високий рівень, 1. MOSI в термінах SPI.
Підсвітка ніяк не зв'язана із рештою схем. Зокрема, навіть якщо вона світиться, це не означає, що модуль правильно підключено!. Її зараз не розглядатимемо.

Взаємодія із модулем


Увага! Не пізніше, ніж через 100 мс після ввімкнення, слід подати сигнал RES! Після цього можна переходити до ініціалізації, яка описана далі. Справа в тому, що після ввімкнення живлення і до перевантаження, його внутрішній стан невизначений, може трапитися така комбінація налаштувань, яка виведе його з ладу.
Поки на CE високий рівень, 1, послідовний інтерфейс ігнорується. По його спаду, переходу в 0, починається обмін даними -- за кожного такту на CLK читається значення біта на DIN:
Зображення із офіційної документації.
(c) Philips

Передача відбувається побайтово. Першим йде найстарший (MSB) біт. Якщо після передачі восьми бітів CE залишається активним (на ньому все ще 0), контролер вважає, що передається наступний байт.
Перевантаження припиняє всілякі обміни, очищає регістри і т.д. Однак, вміст RAM -- пам'яті, не очищається.
Існує два режими роботи -- передача даних (D/C == 1) та передача команд ( D/C == 0).
Рівень D/C читається під час передачі останнього біта байту, тому цей сигнал повинен бути активним достатньо довго!
Команди, власне, змінюють стан контролера, а дані поступають безпосередньо в RAM. Куди саме -- визначається двома адресними регістрами, X та Y. Про ці регістри та організацію RAM  -- трішки нижче.


Команди

Доступні команди наведено в наступній таблиці:
Система команд PCD8544.
(c) Philips

Зауважте оригінальну систему команд -- біти, які задають команду, підібрані так, щоб у байті залишилося ще місце для безпосередніх даних, а будь-які безпосередні дані ніколи не сприймалися за команду. 
Загальний огляд проблеми побудови системи команд, на прикладі центральних процесорів, див. Таненбаум Э., Остин Т., "Архитектура компьютера" (6-е издание), глава 5 "Уровень архитектуры набора команд", розділ "Форматы команд".
Однак, вмістити все в один байт таки не вдалося. Тому є два режими  -- базові команди та розширені команди. Дві команди однаково ведуть себе в обох режимах:
  • Код нуль, 0000 0000, означає відсутність команди. 
  • Команда 0010 0xxx -- вибір функції (function set).
Розглянемо вибір функції детальніше. Вона включає три біти опцій:
  • Біт 2, PD -- Power Down. Коли 0 -- пристрій активний, 1 -- спить.
    Якщо цей режим використовується для енергозбереження, спершу заповніть RAM нулями.
  • Біт 1,V -- Vertical. Вибирає режим адресації. 0 -- горизонтальна, 1 -- вертикальна. Адресація -- спосіб вибору наступного байту при записі в RAM. Детальніше про неї -- нижче.
  • Біт 0, H. Якщо рівний 0 -- використовується базова система команд, 1 -- розширена.
Тобто, якщо передати команду 0010 0001, наступні команди сприйматимуться як розширені, із нижньої частини таблиці, а якщо команду 0010 0000 -- як базові, із середини таблиці.

Базові команди включають керування дисплеєм та запис у адресні регістри X та Y, про які далі.

Формат команди керування наступний: 00001D0E, де біти D та E задають режим роботи дисплея:
  • 00 -- дисплей чистий, (не залежно від вмісту RAM),
  • 10 --  нормальний режим, 
  • 01 -- дисплей повністю заповнений,
  • 11 -- інвертований режим.
Можна сказати, що D визначає, відображати вміст пам'яті чи залишити дисплей порожнім, а E -- нормальний/інвертований режим виводу пікселів.

Команда встановлення X має формат 1XXX XXXX, де семи бітів безпосередніх даних якраз вистачає, щоб задати всі можливі значення X -- від 0 до 83. Аналогічно, команда встановлення Y має формат 0100 0YYY -- Y може набувати значень від 0 до 5, тому трьох бітів достатньо. Наприклад, 0100 0100 встановить Y == 4, а 1001 100 встановить X == 12.

Розширені команди дозволяють задати:
  • Температурний коефіцієнт (рідкі кристали ведуть себе по різному за різних температур) від 0 до 4.
  • "Bias", який, фактично, визначає контраст, 0-7. Хорошим значенням по замовчуванню є 3, але експериментуйте. :-)
  • Напругу на LCD -- Vop. Подробиці див. документацію ("Set Vop value"). От тут із експериментами слід бути акуратним, щоб не вийти за допустимі межі напруги на LCD. Шістнадцяткове значення 0x40 -- цілком розумне.

Ініціалізація 

Після ввімкнення живлення внутрішній стан контролера не визначений. Тому, протягом 100 мс слід подати сигнал RES -- перевантаження. Якщо цього не зробити, контролер може вийти з ладу!
Ймовірно, він не вийде з ладу першого разу. Але, через невизначений внутрішній стан, рано чи пізно, це таки станеться. Не легковажте даною рекомендацією тільки із міркувань "працює ж" -- "зразу не згоріло". Це як п'яним за рулем: "доїхав ж!".
Тривалість імпульсу на  RES має бути більшою за 100 нс, він може бути як завгодно довгим.

Після перевантаження внутрішні регістри очищено, вміст RAM невизначений після ввімкнення живлення, залишається тим же, що й був до приходу RES, стан контролера наступний:
  • PD == 1 -- Power-down mode.
  • Горизонтальна адресація (V==0), базові команди (H==0).
  • Дисплей очищено (ED==00)
  • X == 0, Y == 0
  • TC (temperature coefficient) == 0
  • BS (bias) == 0
  • Генератор напруги для LCD вимкнено.
Ініціалізація може виглядати якось так:
  • CE -- активний, 0.
  • RST -- активний, 0.
  • Чекаємо мікросекунду або більше. 
  • RST -- пасивний, 0.
  • DC == 0: режим передачі команд.
  • Передати 0010 0001 --вибрати режим розширених команд.
  • Передати команду встановлення коефіцієнта напруги 0x40 (1100 0000).
  • Передати температурний коефіцієнт, наприклад, 2: 0000 0110.
  • Передати контраст, bias == 3: 000 1 0011.
  • Обрати режим базових команд: 0010 0000.
  • Встановити нормальний режим дисплею: 0000 1100.
  • Якщо є сумніви в X та Y -- можна ще занулити їх.
  • Далі може йти: CE -- пасивний, 1, для припинення обміну, або DC == 1, передача даних.

Організація RAM -- "відеопам'яті"

Дисплей чорно-білий -- для одного пікселя достатньо одного біта. Тому потрібно 48*84 = 4032 біти або 504 байти. Пам'ять справді організована побайтово, один байт задає один стовпець, висотою 8 пікселів: 

Відповідність бітів пам'яті пікселям дисплею.
(c) Philips
Можна вважати, що пам'ять організована у вигляді шести банків, кожен із котрих керує вісьмома горизонтальними лініями.

В режимі передачі даних (D/C==1), байти послідовно записуються в RAM. Адреса запису визначається регістрами X та Y, розповісти про які обіцялося вище. Y задає банк, тому може набувати значень від 0 до 5, X визначає байт, для даного випадку це еквівалентно номеру стовпця.

Адресація RAM.
(c) Philips
Після запису відбувається перехід до наступного байту. Як саме це відбувається, визначається бітом адресації V з команди вибору функції.
  • Якщо V == 0, то X автоматично збільшує на одиницю -- записуватиметься байт праворуч від поточного. Коли X досягає правого краю (X==83), на наступному кроці він встановлюється в 0 а Y збільшується на 1. Для Y після 5 йтиме нуль:
    Послідовність доступу до байт RAM за горизонтальної адресації.
    (c) Philips
  • Якщо ж V==0, то спершу збільшуватиметься Y, а по досягненню нижньої лінії -- X:
Тобто, система координат наступна:


Посилання

Головне джерело інформації це, безперечно, datasheet: "PCD8544: 48 × 84 pixels matrix LCD controller/driver".

Модулі на його базі продаються Adafruit та Sparkfun. І там і там є посилання на документацію, приклади, бібліотеки для Arduino та допоміжні програми (зазвичай -- глючні та лише в міру юзабельні). Зауважу, що на момент написання вартість такого модуля у них -- 10$. На ebay ціна модуля (не самого екрана -- ті ще дешевші) починається від 1.81$. 

Зокрема, тут є бібліотека для Arduino від Adafruit, а тут -- від Sparkfun.

Ще одне цікаве посилання (із безлічі!): "How to use the Nokia 5110 LCD Module at Arduino".

Про Arduino мені писати нецікаво -- в Інтернеті є дуже багато прикладів. Тому наступного разу розглянемо бібліотеку для STM32.

А поки --

Дякую за увагу!

2 коментарі:

  1. Спасибо большое за статью и за Ваш труд. Все написано доступно и понятно.

    ВідповістиВидалити
  2. Знаю про критику мікроконтролерів сімейства 8051, але все-таки маю намір розробити бібліотеку для них - в них є неоціненний вхід ЕА(External Enable), а швидкість можна збільшити за рахунок багатоконтролерної системи. Чи нема в Вас інформації на цю тему - бо текстові функції розроблені, а з графічними(переважно по віссі Y) є проблема.

    ВідповістиВидалити