
При разработке микроконтроллерных поделок практически всегда возникает потребность реализации пользовательского ввода и вывода. Часто функции ввода информации берёт на себя клавиатура (реже - энкодер), а для отображения состояния устройства используются либо светодиоды, либо светодиодные семисегментные индикаторы, либо ЖК-дисплеи (текстовые вроде 16х2 или графические). Последний вариант часто выигрывает по соотношению цена/возможности если использовать недорогой экран от телефонов Nokia 5110. Разрешающая способность экрана 84х48 позволяет выводить до 5 строк текста длиной до 16 символов. Естественно, помимо текста можно выводить и графику. С таким экраном обычно можно реализовать горазо более удобный пользовательский интерфейс, по сравнению с экранами 16х2, и тем более, по сравнению с семисегментными индикаторами.
Этот модуль изначально разрабатывался для тестера микросхем, но возможности его применения видятся существенно более широкими. Хотелось сделать нечто вроде ардуины, но более пригодное для практического использования (реализация подобного функционала на ардуине как правило приводит к рождению макаронноно монстра из нескольких плат и кучи проводов).
Модуль содержит:
Схема модуля
В итоге получилась компактная плата, на основе которой можно создать множетсво простых автономных вещей подключив всего несколько деталей (например, метеостанцию, или другие измерительные проборы). Либо можно использовать модуль в составе другой микроконтроллерной системы, подключив его двумя проводами по интерфейсу UART. В частности, модуль можно легко подключить к ПК через преобразователь USB to UART, что удобно, например, для быстрой разработки прототипов пользовательского интерфейса - можно по-быстрому набросать программу управления на каком-нибудь питоне, и при этом нет необходимости постоянного перепрограммирования микроконтроллера.
Печатные платы модуля
Также сделал расширенную версию платы с монтажным полем и дополнительной кнопкой сброса.
Внешний вид модуля
Прошивку для модуля можно взять из репозитория тестера микросхем на гитхабе: github.com/trol73/avr-ic-tester-v2 (директория firmware/display). Для компиляции испольузется avr-builder.
В директории misc/display_python есть питоновская библиотека для работы с дисплеем на ПК и небольшой пример ее использования. В директории firmware/tester/src есть библиотека для управления модулем для AVR (файлы controller.h и controller.c). Библиотеки позвоялют рисовать по экрану, выводить символы и строки, проигрывать звуки разной тональности и длительности, работать с клавиатурой и управлять подсветкой дисплея. При этом, вся работа по отображению выполняется на МК дисплейного модуля, что разгружает основной МК - асинхронная передача нескольких байт по UART занимает гораздо меньше времени, чем отрисовка картинки не экране. Модуль асинхронно принимает команды и складирует их в буффер, параллельно выполняя по очереди. Основному модулю нет необходимости ждать завершения выполнения команд - он только добавляет задачи на отрисовку и продолжает заниматься своим делом. Если же основной модуль хочет дождаться выполнения команд, он может вызвать метод CtrSync(uint8_t code), который передаёт числовой аргумент тестеру и получает его же в ответ (эту функцию можно использовать для контроля ошибок передачи). Так же роль метода синхронизации может выполнять функция опроса клавиатуры uint8_t ReadKeyboard(uint8_t *keys). Этот методы возвращает битовую маску кодов для нажатых клавиш. Если аргумент keys не NULL, а массив размеом 5 байт, то сюда будут сохранены длительности удержания клавиш в нажатом состоянии.
Дисплей управляется по интерфейсу UART, по умолчанию скорость подключения равна 57600 бод. Протокол передачи двоичный - сначала передаётся байт команды, затем, её аргументы (если они есть). Коды команд описаны в файле api_codes.h, в комментариях там указано, сколько байт аргументов принимает команда. У некоторых команд, работающих со строками, количество байт аргументов переменно и зависит от длины строки. Команда может возвращать данные (например, CMD_SYNC или READ_KEYBOARD).
Вот список кодов:
#define CMD_SYNC 0 // 1 bytes #define LCD_SET_CONTRAST 1 // 1 bytes #define LCD_CLEAR 2 // 0 bytes #define DRAW_PIXEL_1 3 // 2 bytes #define DRAW_PIXEL_0 4 // 2 bytes #define INVERT_PIXEL 5 // 2 bytes #define DRAW_LINE_1 6 // 4 bytes #define DRAW_LINE_0 7 // 4 bytes #define FILL_RECT_1 8 // 4 bytes #define FILL_RECT_0 9 // 4 bytes #define DRAW_RECT_1 10 // 4 bytes #define DRAW_RECT_0 11 // 4 bytes #define DRAW_CIRCLE_1 12 // 3 bytes #define DRAW_CIRCLE_0 13 // 3 bytes #define FILL_CIRCLE_1 14 // 3 bytes #define FILL_CIRCLE_0 15 // 3 bytes #define INVERT_AREA 16 // 4 bytes #define DRAW_CHAR_XY 17 // 3 bytes #define DRAW_CHAR 18 // 1 bytes #define DRAW_STRING_XY 19 // variable #define DRAW_STRING 20 // variable #define LCD_WRITE 21 // 0 bytes #define READ_KEYBOARD 22 // 0 bytes #define SET_HIGHLIGHT 23 // 2 bytes #define BEEP 24 // 3 bytes #define DRAW_CENTERED_STRING 25 // variable #define SET_STRING_INTERVAL 26 // 1 bytes #define DRAW_CHAR_XY_OVER 27 // 3 bytes #define DRAW_CHAR_OVER 28 // 1 byte #define SET_KEYBOARD_BEEP 29 // 1 bytes
Основная группа - команды рисования DRAW_xxx, FILL_xxx, INVERT_AREA. Например, команда DRAW_CHAR_XY рисует символ в указанные координаты, после чего устанавливает текущую позицию в конец нарисованного символа. Т.е., если передать команде аргументы (x, y, 'A'), то буква 'A' будет нарисована с начальными координатами (x, y), а после рисования текущими координатами дисплея станут (x + 5, y), тут 5 - это ширина символа. Команда DRAW_CHAR рисует символ в текущую позицию после чего также увеличивает текущую координату X на ширину нарисованного символа. Команды DRAW_CHAR/DRAW_STRING рисуют символы чёрным цветом по белому фону, т.е., явно затирая фон и окрашивая его в белый цвет. Нарисовать символ не трогая фон можно командами DRAW_CHAR_OVER/DRAW_CHAR_XY_OVER. Если хочется нарисовать белый символ на чёрном фоне, то поможет команда INVERT_AREA.
Кроме команд рисования есть команда подачи звукового сигнала требуемой частоты и длительности - BEEP, управления подсветкой экрана - SET_HIGHLIGHT (подсветку пожно включить, выключить или установить авторежим, когда экран будет светится указанное время после каждого нажатия клавиши). Также можно включить режим биппера при нажатии клавиш - SET_KEYBOARD_BEEP.
Фьюзы
Схема модуля в PDF Печатная плата (Gerber-файлы) github.com/trol73/avr-lcd-module-5110