Работаем с LCD дисплеем на основе микроконтроллера – HD44780 (ч.2)

 

LCD_practice

Практическая часть

 

Итак, мы рассмотрели принцип работы с ЖК модулем на основе HD44780 в прошлом посте.

Данная часть практическая, здесь мы отработаем полученные знания

Порядок поста следующий:

  1. сначала я приведу пример как работать с ЖК дисплеем LMO16L в Proteus с помощью PATTERN GENERATOR
  2. далее, я покажу исходный код для Arduino, с помощью которого мы выведем текст «s-engineer.ru» в Proteus и на реальном LCD не используя библиотеки
  3. после чего, закрепим, я продемонстрирую ассемблерный код для ATmega8, который также, можно попробовать на модели LM016L

P.S. разделы кликабельны, при нажатие вы спускаетесь к соответствующему разделу

 

Для отладки кода, я создал проект в Proteus и назвал его LCD_stand (скачать).

lcd_stand

(картинка кликабельна)
Схема может спугнуть, но поверьте, она очень простая.

  • Красной стрелкой с 1 обозначен микроконтроллер ATmega328P, в нашем случае он выполняет роль Arduino UNO.
  • Красной стрелкой c 2 помечен микроконтроллер ATmega8, на нем мы будем запускать ассемблерный код.
  • Красной стрелкой с 3 показан PATTERN GENERATOR, это виртуальный инструмент Proteus, который позволяет генерировать единицы и нули в соответствие с файлом скрипта.

Все три устройства (ATmega328P или Arduino UNO, ATmega8 и PATTERN GENERATOR) подключены с помощью шин (синие жирные линии) к одному LCD дисплею LM016L.

Зелеными стрелками обозначены ключи, с помощью которых, мы можем отключать то или иное устройство от LCD. Смысл заключается в том, что мы будем по очереди пробовать работать с LCD на каждом из устройстве, начнем как я говорил ранее, с PATTERN GENERATOR, далее, ATmega328P (или Arduino), после чего ATmega8.

P.S. Что-бы, не было тормозов, в добавок я рекомендую отключать не используемые устройства из эмуляции, кликнете два раза по устройству, в низу нового окна, напротив «Exclude from Simulation» установите галочку.

simulation_off

 

Красной стрелкой с 4, показан испытуемый 2-ух строчный 16-и знаковый LCD дисплей LM016L

Красной стрелкой с 5 показан виртуальный инструмент Proteus – логический анализатор, который подключен к общей шине и видит все, что получает LCD. Он представляет собой, что-то вроде осциллографа, но с большим числом измерительных каналов.

 

logic_analyser_proteus

 

 

Поехали…

 

 

PATTERN GENERATOR

 

1. Начнем с PATTERN GENERATOR, т.к. на нем легче отработать протокол, временные задержки мы пока учитывать не будем, модель прекрасно работает без них. Отключите все остальные устройства от шины (ATmega328P, ATmega8), а лучше из эмуляции, как я сказал выше.

PATTENR GENERATOR генерирует на своем выходе параллельный двоичный код в зависимости от содержимого .ptn скрипта. Данный скрипт представляет собой текстовый файл, в котором, в одну строку пишется, что необходимо вывести первым, на второй строке, что вывести вторым и т.п. Данные можно записывать в десятичном, шестнадцатеричном и двоичном виде. Мы будем использовать двоичный вид записи, для этого, перед значением необходимо приписывать знак «%». Однострочный комментарии в ptn скрипте, записываются после символа «;».

Итак скрипт, с помощью которого PATTERN GENERATOR выдаст последовательность единиц и нулей для отображение на LCD дисплеи строки «S-E», скачать можно ниже, кликнув по иконке. Я решил не мусорить им статью.

script_link

 

Для подключения ptn файла к PATTERN GENERATOR, кликните на нем два раза и выберите скрипт напротив «Pattern Generator Script.

Важно заметить, что в LCD дисплеи сначала идет DB4, а потом DB5, т.е. сначала младший разряд, а потом старший, поэтому нам приходится писать код «зеркально». Обратите вниманию на подсказку в начале скрипта

 

 

Она поможет вам определить какой разряд, за что отвечает:

разряд r – отвечает за линию RS (команда или данные);

разряд e – за линию E (стробирующий импульс);

разряды 4,5,6,7 – за линии DB4, DB5, DB6, DB7.

 

Логика работы видна по скрипту, мы выставляем логические единицы и нули на выводах DB4-DB7, далее выводим на линию E – стробирующий импульс, после чего выводим младший полубайт по аналогии. Повторюсь, для первой команды 0x30 младший полубайт не нужен, т.к. LCD работает еще в 8-и разрядном режиме.

После инициализации, мы можем указать место в DDRAM куда писать символ (команда №8), передвинуть курсор (команда №5) и далее послать данные с ASCII кодом символа (команда №9). Самый просто путь, послать данные сразу, ведь курсор изначально стоит в левом верхнем углу, как я и сделал в скрипте.

 

 

Когда посылаются данные, необходимо установить разряд r (линия RS), иначе LCD будет воспринимать это как команды.

 

Далее по аналогии, я вывожу остальные символы, что бы получить “S-E”. При записи каждого нового символа курсор сдвигается автоматически, как и было указано при инициализации.

 

PATTERN GENERATOR в процессе своей работы, отображает выводимые им данные. Разными цветами я обозначил последовательность отвечающая за знак Е-, S.

 

work_pattern_generator_lcd

(картинка кликабельна)

 

Удобно посмотреть, что получает LCD, для этого можно использовать логический анализатор. Для этого нажмите на || (стоп эмуляции), далее правой кнопкой мыши на анализатор, устанавливаете галку напротив «VSM Logic Analyser». С помощью рукоятки «Capture Resolution» опытным путем выбираете время наблюдения и далее жмете кнопку «Capture». Запускаете моделирование, логический анализатор накапливает данные. После чего останавливаете эмуляцию с помощью кнопки ||, и смотрите результат. Для удобства я кадрировал изображение с анализатора и подписал снизу передаваемые данные в HEX.

PATTERN_GENERATOR_time_data

Arduino UNO

2. На данном этапе, я продемонстрирую исходный код для Arduino, который вы сможете опробовать как в Proteus, так и на реальном LCD Shield.

LCD Shield_Arduino.

Отключите все остальные устройства от шины (PATTERN GENERATOR, ATmega8), а лучше из эмуляции, как я сказал выше.

Программа написана без использования библиотек, работаем с LCD на низком уровне.

 

Скачать файл с исходным кодом .ino и готовую прошивку hex для Arduino.

Как самим скомпилировать и загрузить прошивку в модель Proteus?

На всякий, дам еще раз ссылку на проект в Proteus — скачать. Вместо кнопки «Вгрузить» нажмите на «Проверить» в Arduino IDE. В результате в директории «C:\Users\Admin\AppData\Local\Temp» создастся папка с названием buildxxxxxxxxxxxxxxxx.tmp. Что-бы не искать её, рекомендую в поиске вбить «LCD_Arduino.cpp.hex», найденный файл и есть прошивка, скопируйте в удобнее для вас место. Далее, два раза щелкните на модель ATmega328P в Proteus и напротив Program File выберите данный hex файл.

 

Результат работы на модели Atmega328 в Proteus

lcd_stand_Arduino_worl

 

Проверим код на реальном Arduino UNO с LCD шилдом, основу которого составляет LCD WH1602B.

 

LCD_S-E

 

Исходный код достаточно прост, сначала я обозначил ножки через #define. Ножки я подобрал таким образом, что-бы программа могла работать на Arduino с «стандартной» LCD платой расширения на ней.

Далее, константой mks_after_com я обозначил задержку в 4000 мкс для обработки команд (см. таблицу в прошлом посте). Хотя даташит, требует задержку не менее 40мкс, устойчиво LCD у меня стал работать только с 4000 мкс.

Константа mks_strobe обозначает задержку в мкс для стробирующего импульса, подбирается опытным путем, 5 мкс было достаточной длительностью для данного LCD.

Функция send_LCD(byte RS_value,byte DB4_value,byte DB5_value,byte DB6_value,byte DB7_value) выставляет на ножках RS,DB4,DB5,DB6,DB7 логические единицы и нули, в зависимости от входных параметров byte RS_value,byte DB4_value,byte DB5_value,byte DB6_value,byte DB7_value. Далее, посылается на E стробирующий импульс длительностью mks_strobe. С помощью данной функции, я буду производить работу с LCD дисплеем.

Я повторил те-же действия, как и в скрипте ptnPATTERN GENERATOR, добавлены только задержки. Если в вкратце, то в коде происходит следующие:

  1. Выждали 20 мс
  2. Отправили 1100 (команда №6, установим разрядность 8 бит)
  3. Выждали 4000 мкс
  4. Отправили старший полубайт 0100
  5. Отправили старший полубайт 0100 (команда №6, установим разрядность 4 бит)
  6. Отправили младший полубайт 0001
  7. Выждали 4000 мкс
  8. Отправили старший полубайт 0000 (команда №4, выключение дисплея)
  9. Отправили младший полубайт 0001
  10. Выждали 4000 мкс
  11. Отправили старший полубайт 0000 (команда №1, сброс дисплея)
  12. Отправили младший полубайт 1000
  13. Выждали 4000 мкс
  14. Отправили старший полубайт 0000 (команда №3, курсор при записи движется вправо)
  15. Отправили младший полубайт 0110
  16. Выждали 4000 мкс
  17. Отправили старший полубайт 0000 (команда №4, включение дисплея)
  18. Отправили младший полубайт 0011
  19. Выждали 4000 мкс
  20. Установили RS=1
  21. Отправили старший полубайт 1010 (команда №6 , данные – ASCII код символа ‘S’)
  22. Отправили младший полубайт 1100
  23. Выждали 4000 мкс
  24. Отправили старший полубайт 0100 (команда №6 , данные – ASCII код символа ‘-’)
  25. Отправили младший полубайт 1011
  26. Выждали 4000 мкс
  27. Отправили старший полубайт 0010 (команда №6 , данные – ASCII код символа ‘E’)
  28. Отправили младший полубайт 1010

 

 

На ассемблере для Atmega8

 

3.  Ассемблерный код для ATmega8

Отключите все остальные устройства от шины (ATmega328P, PATTERN GENERATOR), а лучше из эмуляции, как я сказал выше.

 

Все предельно просто, на экране все также выводиться три символа «S-E«.

Код состоит из подпрограм:

«initial» — устанавливает вершину стека и инициализирует выводы ATmega8

«send_LCD» — посылает LCD данные/команды в зависимости от значения регистра data_LCD;

«init_LCD» — инициализирует LCD, посылает последовательность команд для инициализации описанную выше с помощью send_LCD;

«pause» — выдерживает задержку с помощью цикла, повторяющегося R17 раз;

«main» — главная программа.

 

Последовательность работы следующая, при запуске мы попадаем в программу initial, которая устанавливает стек и конфигурирует выводы микоконтроллера, после чего запускается подпрограмма инициализации дисплея — init_LCD, далее выполняется программа main, в которой мы передаем ASCII код для LCD, для отображения «S-E«.

Задержка для стробирующего импульса определяет с помощью

т.е. 5 мкс.

Задержка после команд определятся с помощью

 

Повторюсь, задержка после команд согласно даташиту должна быть 40 мкс, я взял больше 255 мкс, т.к. при 40 LCD не работал корректно.

Данный код, я попробовал только на модели LCD, на реальном, думаю могут возникнуть проблемы с задержками. Перед запуском нужно выдержать задержку 40мс.




Буду признателен если вы поделитесь данным постом

Комментарии
  1. Гистерезис пишет:

    Почему все манипуляции с Atmega8 производятся через порт D, хотя RS и E подключены на C, а 2-ой и 3-ий разряды порта D болтаются в воздухе? Программа так работать не будет.
    И ещё:
    ;sbi DDRC,0
    ;cbi PORTC,0

    Это в смысле? Зачем эти строки сделаны комментариями?

  2. admin пишет:

    Добрый день.

    Хм, заметил опечатку в принципиальной схеме. Действительно, выводы RS и E согласно ассемблерному коду должны быть на D2 (RS) и на D3 (E).
    Обязательно подправлю пост.

    Спасибо!

  3. Marson пишет:

    А где раздобыть скрипт для PATTERN GENERATOR? Ссылка в тексте не рабочая (((

  4. admin пишет:

    Я прислал вам файл по почте.

    На сайте сейчас есть проблемы с битыми ссылками, в будущем обязательно подправлю.

  5. Ншколай пишет:

    Спасибо огромное статья очень помогла определить распиновку не стандартного lcd 24х2 (от телефона) !



Ваш комментарий


Ответ в цифрах

 
© s-engineer.ru, 2012-2017 | Все права защищены