Текстовый экран 16×2 / i²c: инструкция по подключению и примеры использования

Содержание

Набор инструкций

Набор команд HD44780 показан ниже:

Набор команд на основе HD44780U
Инструкция Код Описание Время выполнения (макс.) (При f cp = 270 кГц)
RS R / W B7 B6 B5 B4 B3 Би 2 B1 B0
Четкий дисплей 1 Очищает дисплей и возвращает курсор в исходное положение (адрес 0). 1,52 мс
Курсор на главную 1 * Возвращает курсор в исходное положение. Также возвращает дисплей в исходное положение. Содержимое DDRAM остается без изменений. 1,52 мс
Установлен режим входа 1 Я БЫ S Устанавливает направление движения курсора (I / D); указывает на смещение дисплея (S). Эти операции выполняются во время чтения / записи данных. 37 мкс
Управление включением / выключением дисплея 1 D C B Устанавливает включение / выключение всего дисплея (D), включение / выключение курсора (C) и мигание символа позиции курсора (B). 37 мкс
Курсор / смещение дисплея 1 S / C R / L * * Устанавливает перемещение курсора или сдвиг отображения (S / C), направление сдвига (R / L). Содержимое DDRAM остается без изменений. 37 мкс
Набор функций 1 DL N F * * Устанавливает длину данных интерфейса (DL), количество отображаемых строк (N) и шрифт символов (F). 37 мкс
Установить адрес CGRAM 1 CGRAM адрес Устанавливает адрес CGRAM. Данные CGRAM отправляются и принимаются после этой настройки. 37 мкс
Установить адрес DDRAM 1 Адрес DDRAM Устанавливает адрес DDRAM. Данные DDRAM отправляются и принимаются после этой настройки. 37 мкс
Чтение флага занятости и счетчика адресов 1 BF Адрес CGRAM / DDRAM Считывает флаг занятости (BF), указывающий на выполнение внутренней операции, и считывает содержимое счетчика адресов CGRAM или DDRAM (в зависимости от предыдущей инструкции). 0 мкс
Напишите CGRAM или DDRAM 1 Запись данных Записывать данные в CGRAM или DDRAM. 37 мкс
Чтение из CG / DDRAM 1 1 Прочитать данные Считайте данные из CGRAM или DDRAM. 37 мкс
Имена битов команд —

I / D — 0 = уменьшить позицию курсора, 1 = увеличить позицию курсора;
S — 0 = нет сдвига дисплея, 1 = сдвиг дисплея;
D — 0 = дисплей выключен, 1 = дисплей включен;
C — 0 = курсор выключен, 1 = курсор включен;
B — 0 = курсор выключен, 1 = курсор включен;
S / C — 0 = перемещение курсора, 1 = отображение сдвига;
R / L — 0 = сдвиг влево, 1 = сдвиг вправо;
DL — 0 = 4-битный интерфейс, 1 = 8-битный интерфейс;
N — 0 = 1/8 или 1/11 (1 строка), 1 = 1/16 (2 строки);
F — 0 = 5 × 8 точек, 1 = 5 × 10 точек;
BF — 0 = можно принять инструкцию, 1 = выполняется внутренняя операция.

DDRAM — это ОЗУ данных дисплея, а CGRAM — ОЗУ генератора символов. DDRAM имеет адрес 80 байтов (40 на строку) с зазором между двумя строками. Первая строка — это адреса от 0 до 39 в десятичной системе счисления или от 0 до 27 в шестнадцатеричной системе. Вторая строка — это адреса от 64 до 103 в десятичной системе счисления или от 40 до 67 в шестнадцатеричной системе.

CGRAM — это память для чтения / записи, используемая для кодирования до 8 символов в генераторе символов. Он состоит из 64 полей по адресам от 0 до 3F. Каждое поле представляет собой 5-битное сопоставление с строкой пикселей каждого символа. Каждые 8 ​​полей в CGRAM используются для каждого символа. Младшие 3 бита кодов символов 0-7 и 8-15 выбирают группы из 8 полей в памяти CGRAM.

Чтение и запись в DDRAM осуществляется путем установки высокого уровня на входе RS во время передачи данных по шине. DDRAM также необходимо выбрать с помощью команды Set DDRAM address, которая выбирает DDRAM для доступа, а также устанавливает начальный адрес для доступа к DDRAM.

Аналогичным образом чтение и запись в CGRAM выполняется путем установки высокого уровня входа RS во время передачи данных по шине. CGRAM также должен быть выбран командой Set CGRAM address, которая выбирает CGRAM для доступа, а также устанавливает начальный адрес для доступа CGRAM.

Время выполнения, указанное в этой таблице, основано на частоте генератора 270 кГц. В паспорте указано, что для резистора 91 кОм при 5 В Vcc генератор может варьироваться от 190 кГц до 350 кГц, что приводит к времени ожидания от 52,6 до 28,6 мкс вместо 37 мкс. Если дисплей с рекомендованным резистором 91 кОм запитан от 3,3 В, генератор будет работать намного медленнее. Если бит занятости не используется и инструкции синхронизируются внешней схемой, это следует учитывать.

Распиновка 16х02 символов

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

Профессиональный цифровой осциллограф
Количество каналов: 1, размер экрана: 2,4 дюйма, разрешен…

Подробнее

  • GND — должен быть подключен к земле Arduino.
  • VCC — это вывод питание для ЖК-дисплея, к которому мы подключаем 5-вольтовый контакт Arduino.
  • Vo (LCD Contrast) — вывод контролирует контрастность и яркость ЖК-дисплея. Используя простой делитель напряжения с потенциометром, мы можем точно отрегулировать контрастность.
  • RS (Register Select) — этот вывод позволяет Arduino сообщать ЖК-дисплею, отправляются команды или данные. В основном этот вывод используется для дифференциации команд от данных. Например, когда на выводе RS установлено значение LOW, мы отправляем команды на ЖК-дисплей (например, установить курсор в определенном месте, очистить дисплей, сдвинуть дисплей вправо и т. д.). Когда вывод RS установлено значение  HIGH, мы отправляем данные/символы на ЖК-дисплей.
  • R/W (Read/Write) — вывод предназначен для контроля того, что необходимо сделать — считать данные или передать их на ЖК-дисплй. Поскольку мы просто используем этот ЖК-дисплей в качестве устройства вывода, то достаточно на этот вывод подать HIGH уровень, тем самым мы перейдем в режим записи.
  • EN (Enable) — вывод используется для включения дисплея. Это означает, что когда на этом выводе  установлено значение LOW ЖК-дисплей не реагирует на то, что происходит с R/W, RS и линиями шины данных. Когда же на этом выводе HIGH ЖК-дисплей обрабатывает входящие данные.
  • D0-D7 (Data Bus) — это выводы, по которым передаются 8-битные данные на дисплей. Например, если мы хотим отобразить символ «A» в верхнем регистре, мы отправляем на LCD дисплей 0100 0001 (в соответствии с таблицей ASCII) .
  • AK (Anode & Cathode) используются для управления подсветкой LCD дисплея.

Different LCD Panel Sizes

Setting the type field in the TextLCD constructor allows configuration for the different display panel sizes:

TextLCD::LCD16x2     16x2 LCD panel (default) 
TextLCD::LCD16x2B    16x2 LCD panel alternate addressing 
TextLCD::LCD20x2     20x2 LCD panel 
TextLCD::LCD20x4     20x4 LCD panel 

Note: There is now also support for

TextLCD::LCD8x1    8x1 LCD panel
TextLCD::LCD8x2    8x2 LCD panel
TextLCD::LCD16x1  16x1 LCD panel
TextLCD::LCD16x4  16x4 LCD panel
TextLCD::LCD24x2  24x2 LCD panel
TextLCD::LCD24x4  24x4 LCD panel (for KS0078 controller)
TextLCD::LCD40x2  40x2 LCD panel
TextLCD::LCD40x4  40x4 LCD panel (two controllers)

You can find the new lib here

For example:

#include "mbed.h"
#include "TextLCD.h"

TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); // rs, e, d4-d7

int main() {
    lcd.printf("Hello World!\n");
}

Library

Library is aimed for MCU ATmega16 / Atmega8 which supports .

Prior defined for:

  • Atmega16 / Atmega8
  • LCD 16×2

Initializing 4-bit operation

// +---------------------------+
// |         Power on          |
// | Wait for more than 15 ms  |   // 15 ms wait
// | after VCC rises to 4.5 V  |
// +---------------------------+
//              |
// +---------------------------+ 
// |  RS R/W DB7 DB6 DB5 DB4   |
// |   0   0   0   0   1   1   |   // Initial sequence 0x30
// | Wait for more than 4.1 ms |   // 4.1 ms us writing DATA into DDRAM or CGRAM
// +---------------------------+
//              |
// +---------------------------+
// |  RS R/W DB7 DB6 DB5 DB4   |
// |   0   0   0   0   1   1   |   // Initial sequence 0x30
// | Wait for more than 0.1 ms |   // 100 us writing DATA into DDRAM or CGRAM
// +---------------------------+
//              |
// +---------------------------+   // Initial sequence 0x30
// |  RS R/W DB7 DB6 DB5 DB4   |   // 37 us writing DATA into DDRAM or CGRAM
// |   0   0   0   0   1   1   |   // 4us tadd - time after BF disapeared
// | Wait for more than 45 us  |   // 37 us + 4 us = 41 us * (270/250) = 45us
// +---------------------------+
//              |
// +---------------------------+   // 4bit mode 0x20
// |  RS R/W DB7 DB6 DB5 DB4   |   // 37 us writing DATA into DDRAM or CGRAM
// |   0   0   0   0   1   0   |   // 4us tadd - time after BF disapeared
// | Wait for more than 45 us  |   // !!! BUSY FLAG CHECK DOESN'T WORK CORRECTLY !!!
// +---------------------------+
//              |
// +---------------------------+
// |  RS R/W DB7 DB6 DB5 DB4   |   // Display off 0x08
// |   0   0   0   0   0   0   |   // 
// |   0   0   1   0   0   0   |   // 
// |    Wait for BF Cleared    |   // Wait for BF Cleared
// +---------------------------+
//              |
// +---------------------------+
// |  RS R/W DB7 DB6 DB5 DB4   |   // Display clear 0x01
// |   0   0   0   0   0   0   |   //
// |   0   0   0   0   0   1   |   //
// |    Wait for BF Cleared    |   // Wait for BF Cleared
// +---------------------------+
//              |
// +---------------------------+
// |  RS R/W DB7 DB6 DB5 DB4   |   // Entry mode set 0x06
// |   0   0   0   0   0   0   |   // 
// |   0   0   0   1   1   0   |   // shift cursor to the left, without text shifting
// |    Wait for BF Cleared    |   // Wait for BF Cleared
// +---------------------------+

The pins used by the display

First the number of pins

The controller allows the use of 6, 7 or 11 pins. Using 11 pins (with 8-bit data bus) is more efficient than using a 4-bit data bus. However, the gain is minimal compared to the processing time of each command by the controller: approximately 37 µs. In addition the number of pins available on the MCU is limited. So we will use 7 pins:

  • RS : Data / Command
  • WR : To read the BUSY flag
  • E : Strobe
  • D4-D7 : The data bus

Which pins of the STM32 to use?

For commands (RS, WR, E) no problem: they are used independently and can therefore be assigned to any GPIO of the MCU.

For the data bus, it can be tempting to use 4 contiguous pins on the same GPIO port. But this is very restrictive:1) all the pins of the MCUs have several functions and it is rare to be able to have 4 contiguous free pins.2) You must be able to position the data on these pins atomically.

This last point concerns multi-tasking applications, or interruptions routines. You cannot read / modify / write on the GPIO ports. This is why the GPIO ports have registers BSRR and BRR which allow to put at 1 or at 0 a pin in an atomic way.

Since it is agreed to set the pins to 0 or 1 independently of each other using the BSRR and BRR registers, there is no longer any constraint on the arrangement of the data bits on the GPIOs.

All pins on the display can therefore be connected to any unused pins on the MCU.

Conclusion

Here is an efficient implementation of a 1602 library for stm32 or blue pill board. These LCD displays are based on an HD44780 controller which allows:

  • Little constraint on pins to use MCU
  • Timing optimized by direct access to the registers and the use of the BUSY flag of the controller.
  • Easy portage between STM32 families.

On a STM32F103 at 72 MHz it was measured approximately 40 µs per character when displaying a chain.

The library hd44780 to use with AdAstra-RTK is available here. It supports F1xx/L1xx and other families (F4, F7, H7…)

The library is also available in the distribution packages of the “Download” page.

Исходный код программы

Чтобы в программе подключить ЖК дисплей к ARDUINO UNO, необходимо сделать следующие несколько вещей:

Arduino

#include <LiquidCrystal.h>
lcd.begin(16, 2);
LiquidCrystal lcd(0, 1, 8, 9, 10, 11);
lcd.print(«hello, world!»);

1
2
3
4

#include <LiquidCrystal.h>

lcd.begin(16,2);

LiquidCrystallcd(,1,8,9,10,11);

lcd.print(«hello, world!»);

В первую очередь мы должны подключить заголовочный файл (‘#include <LiquidCrystal.h>’), в котором находятся все необходимые инструкции для взаимодействия с ЖК дисплеем, что значительно упростит взаимодействие с ним в 4 битном режиме. Используя этот заголовочный файл нам не нужно будет передавать в ЖК дисплей бит за битом и нам не нужно будет самим программировать какие-либо функции для взаимодействия с ЖК дисплеем.

Во второй строчке мы должны сказать плате ARDUINO UNO какой тип ЖК дисплея мы собираемся использовать, поскольку существует достаточно большое число типов подобных дисплеев, например, 20×4, 16×2, 16×1 и т.д. В нашем проекте мы собираемся подключать к ARDUINO UNO ЖК дисплей 16х2, поэтому мы и должны записать команду ‘lcd.begin(16, 2);’. А если бы мы подключали ЖК дисплей 16х1, то в этом случае изменилась бы и команда соответствующим образом — ‘lcd.begin(16, 1);’.

В следующей инструкции мы сообщаем плате ARDUINO UNO к каким контактам мы подсоединили ЖК дисплей. В нашем случае мы использовали контакты ЖК дисплея “RS, En, D4, D5, D6, D7”, которые подсоединены к контактам «0, 1, 8, 9, 10, 11» ARDUINO UNO, поэтому и приведенная команда выглядит следующим образом — “LiquidCrystal lcd(0, 1, 8, 9, 10, 11);”.

Для того, чтобы напечатать на экране дисплея строку символов, мы использовали команду lcd.print(«hello, world!»), которая выводит на экран дисплея строку ‘hello, world!’.

Как мы видим из представленного кода, нам не нужно заботиться больше ни о каких аспектах взаимодействия с ЖК дисплеем, нам нужно просто инициализировать ЖК дисплей в программе и тогда плата ARDUINO UNO будет готова к отображению информации на экране дисплея.

Далее представлен исходный код программы (с комментариями) для взаимодействия платы ARDUINO UNO с ЖК дисплеем 16х2.

Arduino

#include <LiquidCrystal.h> // инициализируем библиотеку для взаимодействия с ЖК дисплеем
LiquidCrystal lcd(0, 1, 8, 9, 10, 11); /// сообщаем Arduino номера контактов, к которым подключен ЖК дисплей — REGISTER SELECT PIN,ENABLE PIN,D4 PIN,D5 PIN, D6 PIN, D7 PIN
void setup()
{
// устанавливаем число столбцов и строк для ЖК дисплея
lcd.begin(16, 2);
}

void loop()
{
// устанавливаем курсор в нулевой столбец первой строки
lcd.print(» CIRCUIT DIGEST»); //печатаем строку
lcd.setCursor(0, 1); // устанавливаем курсор в нулевой столбец второй строки
lcd.print(«http://www.circuitdigest.com/»);//печатаем строку
delay(750); //задержка на 0.75 сек
lcd.scrollDisplayLeft();// переключаем данные на ЖК дисплее
lcd.setCursor(0, 0);// устанавливаем курсор в нулевой столбец первой строки
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

#include <LiquidCrystal.h> // инициализируем библиотеку для взаимодействия с ЖК дисплеем

LiquidCrystallcd(,1,8,9,10,11);/// сообщаем Arduino номера контактов, к которым подключен ЖК дисплей — REGISTER SELECT PIN,ENABLE PIN,D4 PIN,D5 PIN, D6 PIN, D7 PIN

voidsetup()

{

// устанавливаем число столбцов и строк для ЖК дисплея  

lcd.begin(16,2);

}

voidloop()

{

// устанавливаем курсор в нулевой столбец первой строки  

lcd.print(»   CIRCUIT DIGEST»);//печатаем строку

lcd.setCursor(,1);// устанавливаем курсор в нулевой столбец второй строки  

lcd.print(«http://www.circuitdigest.com/»);//печатаем строку

delay(750);//задержка на 0.75 сек

lcd.scrollDisplayLeft();// переключаем данные на ЖК дисплее

lcd.setCursor(,);// устанавливаем курсор в нулевой столбец первой строки  

}

Шрифт

Желтая подсветка дисплея HD44780

Исходное ПЗУ генератора символов HD44780 содержит 208 символов в точечной матрице 5 × 8 и 32 символа в матрице 5 × 10. Более современные совместимые чипы доступны с более высоким разрешением, подходящим для дисплеев с большим количеством пикселей.

Разработаны две версии ПЗУ:

  • HD44780UA00, стандартная ( японская ) версия, которая включает символы катакана и некоторые греческие буквы и математические символы.
  • HD44780UA02, европейская версия, которая включает полный набор греческих, кириллических и западноевропейских символов (с диакритическими знаками )

7-битное подмножество ASCII для японской версии нестандартно: оно предоставляет символ йены там, где обычно встречается обратная косая черта , и символы стрелок влево и вправо вместо тильды и символа затирания .

Ограниченное количество пользовательских символов может быть запрограммировано в устройство в виде растрового изображения с помощью специальных команд. Эти символы необходимо записывать в устройство каждый раз при его включении, так как они хранятся в энергозависимой памяти .

Описание протокола I2C

Прежде чем обсуждать подключение дисплея к ардуино через i2c-переходник, давайте вкратце поговорим о самом протоколе i2C.

I2C / IIC(Inter-Integrated Circuit) – это протокол, изначально создававшийся для связи интегральных микросхем внутри электронного устройства. Разработка принадлежит фирме Philips. В основе i2c  протокола является использование 8-битной шины, которая нужна для связи блоков в управляющей электронике, и системе адресации, благодаря которой можно общаться по одним и тем же проводам с несколькими устройствами. Мы просто передаем данные то одному, то другому устройству, добавляя к пакетам данных идентификатор нужного элемента.

Самая простая схема I2C может содержать одно ведущее устройство (чаще всего это микроконтроллер Ардуино) и несколько ведомых (например, дисплей LCD). Каждое устройство имеет адрес в диапазоне от 7 до 127. Двух устройств с одинаковым адресом в одной схеме быть не должно.

Плата Arduino поддерживает i2c на аппаратном уровне. Вы можете использовать пины A4 и A5 для подключения устройств по данному протоколу.

В работе I2C можно выделить несколько преимуществ:

  • Для работы требуется всего 2 линии – SDA (линия данных) и SCL (линия синхронизации).
  • Подключение большого количества ведущих приборов.
  • Уменьшение времени разработки.
  • Для управления всем набором устройств требуется только один микроконтроллер.
  • Возможное число подключаемых микросхем к одной шине ограничивается только предельной емкостью.
  • Высокая степень сохранности данных из-за специального фильтра подавляющего всплески, встроенного в схемы.
  • Простая процедура диагностики возникающих сбоев, быстрая отладка неисправностей.
  • Шина уже интегрирована в саму Arduino, поэтому не нужно разрабатывать дополнительно шинный интерфейс.

Недостатки:

  • Существует емкостное ограничение на линии – 400 пФ.
  • Трудное программирование контроллера I2C, если на шине имеется несколько различных устройств.
  • При большом количестве устройств возникает трудности локализации сбоя, если одно из них ошибочно устанавливает состояние низкого уровня.

Custom Characters

Most HD44780 compatible LCDs have 8 memory locations that can be used for creating user defined characters. You create a custom character by putting the character data in to a byte array then passing the array to the library using createChar() command. Each character occupies a 5×8 grid

If you use binary when defining the array you can see the character you are creating. For example, a smily face 🙂 and a sad face 🙁

// Custom characters
 
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
 
//                    ADDR, EN,RW,RS,D4,D5,D6,D7,BL,POLARITY
LiquidCrystal_I2C lcd(0x27, 2, 1, , 4, 5, 6, 7, 3, POSITIVE);  
 
void setup() 
{
    lcd.begin(20, 4);   
    byte chr18 =  { 
                        B00000,
                        B10001,
                        B00000,
                        B00000,
                        B10001,
                        B01110,
                        B00000,
                        B00000
                    };  
    byte chr28 =  { 
                        B00000,
                        B10001,
                        B00000,
                        B00000,
                        B01110,
                        B10001,
                        B00000,
                        B00000
                    };   
 
 
   lcd.createChar(1, chr1);
   lcd.createChar(2, chr2);
 
   lcd.setCursor(, ); lcd.write(1);
   lcd.setCursor(2, ); lcd.write(2);
}
 
void loop() 
{
  ;
}

lcd.createChar(1, chr1); creates character 1 using the data in the array named chr1.
To display this character simply use lcd.write(1);

Although only 8 characters can be created at any one time, the characters can be redefined at anytime and creating new characters on the fly can give the appearance that more than 8 exist, although only 8 can be displayed at any one time.
If you redefine a character while it is being displayed on screen then the character will change to the newly created character.

Online Custom Character Generator

Omer Kilic has created a nice custom character generator that automatically produces the Arduino code.

maxpromer has another, similar, generator here.

Large FontsUsing custom characters it is possible to create large fonts. These were created by digimike on the Arduino forum

Over at AVR Freaks, china92 posted an Excel based design guide.

There are many many more and googling “Arduino LCD large font” will give you a lot of places to look.

Технические параметры

Описание дисплея

LCD 1602A представляет собой электронный модуль основанный на драйвере HD44780 от Hitachi. LCD1602 имеет 16 контактов и может работать в 4-битном режиме (с использованием только 4 линии данных) или 8-битном режиме (с использованием всех 8 строк данных), так же можно использовать интерфейс I2C. В этой статье я расскажу о подключении в 4-битном режиме.

Назначение контактов:
► VSS:   «-» питание модуля
► VDD:  «+» питание модуля
► VO:    Вывод управления контрастом
► RS:     Выбор регистра
► RW:   Выбор режима записи или чтения (при подключении к земле, устанавливается режим записи)
► E:       Строб по спаду
► DB0-DB3: Биты интерфейса
► DB4-DB7: Биты интерфейса
► A:      «+» питание подсветки
► K:      «-»  питание подсветки

На лицевой части модуля располагается LCD дисплей и группа контактов.

На задней части модуля расположено два чипа в «капельном» исполнении (ST7066U и ST7065S) и электрическая обвязка, рисовать принципиальную схему не вижу смысла, только расскажу о резисторе R8 (100 Ом), который служит ограничительным резистором для светодиодной подсветки, так что можно подключить 5В напрямую к контакту A. Немного попозже напишу статью в которой расскажу как можно менять подсветку LCD дисплея с помощью ШИП и транзистора.

Примеры работы для Espruino

В качестве примера подключим дисплей к управляющей плате Iskra JS.

Подключение к Iskra JS

Для коммуникации понадобится Breadboard Half и соединительные провода «папа-папа».

Вывод Обозначение Пин Iskra JS
1 GND GND
2 VCC 5V
3 VO GND
4 RS P11
5 R/W GND
6 E P12
7 DB0
8 DB1
9 DB2
10 DB3
11 DB4 P5
12 DB5 P4
13 DB6 P3
14 DB7 P2
15 VCC 5V
16 GND GND

Вывод текста

Для вывода программы приветствия, воспользуйтесь скриптом:

hello-amperka.js
// создаём переменную для работы с дисплеем
// HD44780 — контроллер монохромных жидкокристаллических знакосинтезирующих дисплеев
var lcd = require("HD44780").connect(P11,P12,P5,P4,P3,P2);
// печатем первую строку
lcd.print("Hello world");
// устанавливаем курсор в колонку 0, строку 1
// на самом деле это вторая строка, т.к. нумерация начинается с нуля
lcd.setCursor(, 1);
// печатаем вторую строку
lcd.print("Do It Yourself");

Кирилица

Вывод кирилицы на дисплей с помощью платформы Iskra JS доступен через встроенную в дисплей таблицу знакогенератора.

Таблица знакогенератора

Дисплейный модуль хранит в памяти две страницы знакогенератора, которые состоят из различных символов и букв.

Для вывода символа на дисплей необходимо передать его номер в шестнадцатеричной системе из таблицы знакогенератора.

Так букве соответствует код в шестнадцатеричной системе. Чтобы передать на экран строку «Яndex», необходимо в явном виде с помощью последовательности встроить в строку код символа:

lcd.print("\xB1ndex");

Вы можете смешивать в одной строке обычные символы и явные коды как угодно. Единственный нюанс в том, что после того, как компилятор в строке видит последовательность , он считывает за ним все символы, которые могут являться разрядами шестнадцатеричной системы даже если их больше двух. Из-за этого нельзя использовать символы из диапазона и следом за двузначным кодом символа, иначе на дисплее отобразится неправильная информация. Чтобы обойти этот момент, можно использовать тот факт, что две строки записанные рядом склеиваются.

Сравните две строки кода для вывода надписи «Яeee»:

lcd.print("\xB1eee"); // ошибка
lcd.print("\xB1"+"eee"); // правильно

Используя полученную информацию выведем на дисплей сообщение «Привет, Амперка!»:

hello-amperka-rus.js
// создаём переменную для работы с дисплеем
// HD44780 — контроллер монохромных жидкокристаллических знакосинтезирующих дисплеев
var lcd = require("HD44780").connect(P11,P12,P5,P4,P3,P2);
// устанавливаем курсор в колонку 5, строку 0
// на самом деле это первая строка, т.к. нумерация начинается с нуля
lcd.setCursor(5, );
// печатаем первую строку
lcd.print("\xA8"+"p"+"\xB8\xB3"+"e\xBF");
// устанавливаем курсор в колонку 3, строку 1
// на самом деле это вторая строка, т.к. нумерация начинается с нуля
lcd.setCursor(3, 1);
// печатаем вторую строку
lcd.print("o\xBF"+" A\xBC\xBE"+"ep\xBA\xB8");;

Переключение страниц знакогенератора

Дисплейный модуль хранит в памяти две страницы знакогенератора. По умолчанию установлена нулевая страница. Для переключения между страницами используйте методы:

// переключение с нулевой страницы на первую
command(0x101010);
// переключение с первой страницы на нулевую
command(0x101000);

Дисплей не может одновременно отображать символы разных страниц.

Рассмотрим пример, в котором одна и та же строка будет отображаться по-разному — в зависимости от выбранной страницы.

change-page.js
// создаём переменную для работы с дисплеем
// HD44780 — контроллер монохромных жидкокристаллических знакосинтезирующих дисплеев
var lcd = require("HD44780").connect(P11,P12,P5,P4,P3,P2);
// создаём переменную состояния
var state = false;
// устанавливаем курсор в колонку 5, строку 0
// на самом деле это первая строка, т.к. нумерация начинается с нуля
lcd.setCursor(5, );
// печатаем первую строку
lcd.print("\x9b\x9c\x9d\x9e\x9f");
 
setInterval(function() {
  // каждую секунду меняем переменую состояния
  state = !state;
  // вызываем функцию смены адреса страницы
  lcdChangePage();
}, 1000);
 
function lcdChangePage () {
  if (state) {
    // устанавливаем 0 станицу знакогенератора (стоит по умолчанию) 
    lcd.write(0b101000, 1);
  } else {
    // устанавливаем 1 станицу знакогенератора
    lcd.write(0b101010, 1);
  }
}

Полную таблицу символов с кодами можно найти в документации к экрану.

How to do this?

You must declare the pins used, for example:

You must then declare the macros that will position the pins at 0 or 1.Macros are used to generate inline code, and they are too simple to justify inline functions. These declarations are independent of the STM32 model used.In fact these declarations are a little more complex for STM32F4. In this family there is no BRR register. The real story: BRR and BSRR are 16-bit registers, but stm32f4xx.h defines them as a single 32-bit register. Sigh…

With these definitions it is easy to manage the pin’s states. For example to send a command to the controller, which requires generating a pulse on pin E:

The setDataPort () function which allows writing a nibble to the data port D7-D4 is hardly more complicated. The function is not that slow: around 1 µs on an STM32F103 at 72 MH.

The last complex function is the initialization of the GPIO pins and of the LCD:

The functions already seen use functions specific to the STM32 model used. In particular, you must be able to configure D7 as output and also as input to be able to read the BUSY flag of the HD44780. For an STM32F103 this gives:

The GPIO initialization is a bit more complicated on an F4, which uses 5 registers instead of 1.Once all of this is defined it is very easy to implement the user API, for example:

Генерация пользовательских символов для LCD

Если вы находите символы на дисплее неподходящими и неинтересными, вы можете создать свои собственные символы (глиф) для своего ЖК-дисплея. Пользовательские символы чрезвычайно полезны в том случае, когда вы хотите отобразить символ, который не является частью стандартного набора символов ASCII.

Как мы уже обсуждали ранее в этом руководстве, символ на дисплее формируется в матрице 5×8 пикселей, поэтому вам нужно определить свой пользовательский символ в этой матрице. Для определения символа необходимо использовать функцию createChar() библиотеки LiquidCrystal.

Для использования  createChar()  сначала необходимо назначить массив из 8 байт. Каждый байт (учитывается только 5 бит) в массиве определяет одну строку символа в матрице 5×8. В то время как нули и единицы в байте указывают, какие пиксели в строке должны быть включены, а какие-выключены.

Генератор символов LCD

Создание собственного символа до сих пор было непросто! Поэтому было создано небольшое приложение под названием «Генератор пользовательских символов» для LCD.

Вы видите синюю сетку ниже? Вы можете нажать на любой из 5 × 8 пикселей, чтобы установить/очистить этот конкретный пиксель. И когда вы нажимаете на пиксели, код для символа генерируется рядом с сеткой. Этот код может быть непосредственно использован в вашем скетче Arduino.

Единственным ограничением является то, что библиотека LiquidCrystal поддерживает только восемь пользовательских символов.

Следующий скриншот демонстрирует, как вы можете использовать эти пользовательские символы на дисплее.

//  подключаем библиотеку LiquidCrystal:
#include <LiquidCrystal.h>

// Создаем LCD объект. Выводы: (rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// создадим несколько пользовательских символов
byte Heart = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};

byte Bell = {
0b00100,
0b01110,
0b01110,
0b01110,
0b11111,
0b00000,
0b00100,
0b00000
};


byte Alien = {
0b11111,
0b10101,
0b11111,
0b11111,
0b01110,
0b01010,
0b11011,
0b00000
};

byte Check = {
0b00000,
0b00001,
0b00011,
0b10110,
0b11100,
0b01000,
0b00000,
0b00000
};

byte Speaker = {
0b00001,
0b00011,
0b01111,
0b01111,
0b01111,
0b00011,
0b00001,
0b00000
};


byte Sound = {
0b00001,
0b00011,
0b00101,
0b01001,
0b01001,
0b01011,
0b11011,
0b11000
};


byte Skull = {
0b00000,
0b01110,
0b10101,
0b11011,
0b01110,
0b01110,
0b00000,
0b00000
};

byte Lock = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11011,
0b11011,
0b11111,
0b00000
};

void setup() 
{
  // инициализируем LCD и устанавливаем количество столбцов и строк: 
  lcd.begin(16, 2);

  // создание нового символа
  lcd.createChar(0, Heart);
  // создание нового символа
  lcd.createChar(1, Bell);
  // создание нового символа
  lcd.createChar(2, Alien);
  // создание нового символа
  lcd.createChar(3, Check);
  // создание нового символа
  lcd.createChar(4, Speaker);
  // создание нового символа
  lcd.createChar(5, Sound);
  // создание нового символа
  lcd.createChar(6, Skull);
  // создание нового символа
  lcd.createChar(7, Lock);

  // Очищаем LCD дисплей 
  lcd.clear();

  // Печатаем сообщение на LCD.
  lcd.print("Custom Character");
}

// Печатаем все пользовательские символы
void loop() 
{ 
  lcd.setCursor(0, 1);
  lcd.write(byte(0));

  lcd.setCursor(2, 1);
  lcd.write(byte(1));

  lcd.setCursor(4, 1);
  lcd.write(byte(2));

  lcd.setCursor(6, 1);
  lcd.write(byte(3));

  lcd.setCursor(8, 1);
  lcd.write(byte(4));

  lcd.setCursor(10, 1);
  lcd.write(byte(5));

  lcd.setCursor(12, 1);
  lcd.write(byte(6));

  lcd.setCursor(14, 1);
  lcd.write(byte(7));
}

После включения библиотеки нам нужно инициализировать пользовательский массив из восьми байтов.

byte Heart = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};

В настройках мы должны создать пользовательский символ, используя функцию createChar(). Эта функция принимает два параметра. Первый — это число от 0 до 7, чтобы зарезервировать один из 8 поддерживаемых пользовательских символов. Второй параметр — это имя массива байтов.

// создание нового символа
lcd.createChar(0, Heart);

Далее в цикле для отображения пользовательского символа мы используем функцию write(), а в качестве параметра мы используем номер символа, который мы зарезервировали.

// byte(0) покажет символ Heart (сердце).
lcd.write(byte(0));