Урок 25. Подключение знакосинтезирующих LCD дисплеев к STM32. Библиотека LCD780.

LCD и STM32

В уроке расскажу об использовании совместно с контроллерами STM32 знакосинтезирующих жидкокристаллических (LCD) дисплеев. Представлю свою библиотеку для управления ими.

Предыдущий урок     Список уроков     Следующий урок

Речь идет о LCD дисплеях с управляющими контроллерами HD44780 или совместимыми с ними (SPLC780, KS0066 и подобными).

 

На рынке существует громадное число разнообразных дисплеев этого класса. Они имеют разную организацию отображаемой информации. Мне известны дисплеи с форматами от 1 строка 8 символов до 4 строки 40 символов. Но при этом у всех LCD дисплеев практически одинаковые параметры, одни и те же сигналы интерфейса и команды.

Достаточно подробно об этом я писал в уроке 23 Ардуино. Там есть справочная информация, описаны сигналы подключения к микроконтроллеру. Не буду повторяться.

 

Аппаратное подключение LCD дисплея к плате STM32.

Я буду использовать в примерах урока индикатор WH2004A (4 строки по 20 символов) в четырех битном режиме обмена.

Схема подключения к плате STM32 выглядит так.

Схема подключения LCD к STM32

Я выбрал первые попавшиеся выводы из разных портов, пропуская те, что уже заняты кнопкой, светодиодом и UART1. Дисплей питается от 5 В, значит выводы должны быть толерантными к 5 В.

О назначении резисторов можно почитать в уроке 23 Ардуино.

Дисплей я припаял к отладочной плате из предыдущих уроков.

LCD и STM32

Теперь есть все, чтобы использовать его в программе.

 

Библиотека LCD780.

Я разработал библиотеку для управления LCD дисплеями. Как мне кажется, работать с ней очень удобно.

Библиотека LCD780 предназначена для управления знакосинтезирующими LCD дисплеями с контролерами HD44780 и совместимыми с ними.

Интерфейс подключения дисплея к STM32 – параллельный в 4х битном режиме. Я посчитал, что необходимости в 8ми битном подключении нет. Зачем тратить для связи с индикатором 10 выводов, когда можно обойтись шестью.

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

Не требуются предварительные установки режимов выводов для подключения дисплея. Конфигурация выводов происходит в функции инициализации. Вы вызываете функцию с заданными в параметрах номерами выводов и можно работать с дисплеем.

Временные задержки, необходимые для сигналов связи с дисплеем, рассчитываются с учетом тактовой частоты STM32. Используется библиотека DelayDWT.

Поддерживаются разные форматы дисплеев (число строк, число символов).

Может быть включен режим поддержки кириллических символов.

Используются следующие команды-функции:

  • Инициализация дисплея.
  • Вывод символа с заданным кодом.
  • Вывод массива символов.
  • Вывод на экран числа uint32_t с выбранной системой исчисления.
  • Вывод на экран числа int32_t с выбранной системой исчисления.
  • Вывод текстовой строки.
  • Вывод числа float с выбранным количеством разрядов после запятой.
  • Очистка экрана.
  • Перемещение курсора в начало экрана.
  • Установка курсора в заданную позицию.
  • Выключение и включение дисплея.
  • Выключение и включение отображения курсора.
  • Выключение и включение режима мигания курсора.
  • Установка направления сдвига при печати символов.
  • Выключение и включение автопрокрутки.
  • Создание пользовательского символа.
  • Запись байта в контроллер дисплея.

Несмотря на обилие функций и широкие функциональные возможности библиотека компактная. Она занимает менее 2 кбайт программной памяти.

Библиотеку можно загрузить по ссылке LCD780.

  Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!  

Я буду рассказывать о функциях библиотеки и одновременно демонстрировать ее работу на примерах.

 

Я создал проект Lesson25_1, в котором конфигурировал только систему тактирования на частоту 72 мГц. Все остальные установки сделает библиотека при инициализации.

Еще необходимо создать в проекте папку Libraries и копировать в нее папки с библиотеками LCD780 и DelayDWT.

В Atollic TrueStudio:

Подключаем библиотеки.

/* USER CODE BEGIN Includes */
#include "LCD780.h"
#include "DelayDWT.h"
/* USER CODE END Includes */

  • Правой кнопкой мыши нажимаем на папку LCD780 в проекте, Add/Remove Include Path -> OK
  • Ту же операцию повторяем с папкой DelayDWT.
  • Правой кнопкой по Libraries, Properties -> C/C++ General -> Paths and Symbols -> Source Location -> Add Folder -> Apply

Теперь можно работать с функциями библиотеки.

 

Функции библиотеки LCD780.

void init_LCD( GPIO_TypeDef *GPIOx_RS, uint16_t GPIO_Pin_RS, GPIO_TypeDef *GPIOx_EN, uint16_t GPIO_Pin_EN, GPIO_TypeDef *GPIOx_D4, uint16_t GPIO_Pin_D4, GPIO_TypeDef *GPIOx_D5, uint16_t GPIO_Pin_D5, GPIO_TypeDef *GPIOx_D6, uint16_t GPIO_Pin_D6, GPIO_TypeDef *GPIOx_D7, uint16_t GPIO_Pin_D7, uint8_t col, uint8_t row, uint8_t cirill)

Инициализация дисплея. Параметры:

  • GPIO_TypeDef *GPIOx_RS, uint16_t GPIO_Pin_RS – порт и вывод сигнала RS;
  • GPIO_TypeDef *GPIOx_EN, uint16_t GPIO_Pin_EN – порт и вывод сигнала EN;
  • GPIO_TypeDef *GPIOx_D4, uint16_t GPIO_Pin_D4 – порт и вывод сигнала D4;
  • GPIO_TypeDef *GPIOx_D5, uint16_t GPIO_Pin_D5 – порт и вывод сигнала D5;
  • GPIO_TypeDef *GPIOx_D6, uint16_t GPIO_Pin_D6 – порт и вывод сигнала D6;
  • GPIO_TypeDef *GPIOx_D7, uint16_t GPIO_Pin_D7 – порт и вывод сигнала D7;
  • uint8_t col – число символов в строке;
  • uint8_t row – число строк;
  • uint8_t cirill – признак поддержки кириллических символов.

Функция должна вызываться до работы с дисплеем. До функции инициализации необходимо разрешить тактирование используемых портов и инициализировать библиотеку DelayDWT.

Перед циклом while добавляем в проект

// инициализация дисплея
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN ;
initDelayDwt();
init_LCD(GPIOA, 1<<12, GPIOA, 1<<15, GPIOB, 1<<14, GPIOB, 1<<15, GPIOA, 1<<8, GPIOA, 1<<11, 20, 4, 1);

Выводы я определил в соответствии со схемой урока. Дисплей у меня 4 строки по 20 символов. Включил поддержку кириллических символов.

void write_LCD(uint8_t valChar)

Выводит на экран символ с кодом, заданным в параметре uint8_t valChar.

Следующий код напечатает ”Проверка дисплея!”.

write_LCD('П');
write_LCD('р');
write_LCD('о');
write_LCD('в');
write_LCD('е');
write_LCD('р');
write_LCD('к');
write_LCD('а');
write_LCD(' ');
write_LCD('д');
write_LCD('и');
write_LCD('с');
write_LCD('п');
write_LCD('л');
write_LCD('е');
write_LCD('я');
write_LCD('!');

Напечатал.

LCD и STM32

void writeBuf_LCD(uint8_t * buf, uint16_t length)

Вывод массива символов на экран.

  • uint8_t * buf – указатель на массив.
  • uint16_t length – количество символов.

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

uint8_t str[] = "Проверка дисплея!";
writeBuf_LCD(str, 17);

void print_uint_LCD(uint32_t n, uint8_t base)

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

  • uint32_t n – число.
  • uint8_t base – основание системы исчисления.

Следующий код печатает в цикле числа от 0 в десятичной, двоичной и шестнадцатеричной системах исчисления.

for( uint16_t i=0; ; i++) {
  clear_LCD();
  print_uint_LCD(i, 10);
  write_LCD(' ');
  print_uint_LCD(i, 2);
  write_LCD(' ');
  print_uint_LCD(i, 16);
  HAL_Delay(1000);
}

LCD и STM32

void print_int_LCD(int32_t n, uint8_t base)

Выводит текстовое представление знакового целочисленного числа в заданной системе исчисления. Аналог предыдущей функции, только с учетом знака числа.

  • int32_t n – число.
  • uint8_t base – основание системы исчисления.

for( int16_t i=-10; ; i++) {
  clear_LCD();
  print_int_LCD(i, 10);
  HAL_Delay(1000);
}

void print_float_LCD(float number, uint8_t digits)

Вывод числа float в текстовом виде.

  • float number – число.
  • uint8_t digits – количество знаков после запятой.

Программа выводит числа с плавающей запятой.

print_float_LCD(3.1415926, 5);
write_LCD(' ');
print_float_LCD(3.1415926, 1);
write_LCD(' ');
print_float_LCD(-3256.123, 2);

LCD и STM32

void print_str_LCD(const uint8_t str[])

Печатает текстовую строку. Конец строки определяется байтом 0.

uint8_t str[] = "Проверка print_str\0";
print_str_LCD(str);

LCD и STM32

Можно так.

print_str_LCD("Проверка print");

void clear_LCD(void)

Очищает экран, курсор устанавливает в верхнюю левую позицию.

void home_LCD(void);

Курсор устанавливает в верхнюю левую позицию.

void setCursor_LCD(uint8_t col, uint8_t row)

Устанавливает курсор в заданную позицию.

  • uint8_t col – позиция в строке, начиная с 1.
  • uint8_t row – номер строки, начиная с 1.

Следующий код выводит число в заданной позиции, увеличивая его  в цикле.

print_str_LCD("Число в строке 4");
setCursor_LCD(1, 2);
print_str_LCD("в позиции 10");
for( uint16_t i=0; ; i++) {
  setCursor_LCD(10, 4);
  print_uint_LCD(i, 10);
  HAL_Delay(1000);
}

LCD и STM32

void noDisplay_LCD()

Выключение дисплея.

void display_LCD()

Включение дисплея.

При выключении данные экрана не теряются. Следующая программа выводит на экране сообщение ”Проверка выключения”, через секунду выключает дисплей. Когда еще через секунду дисплей включается, то надпись появляется на экране, хотя была напечатана до выключения.

print_str_LCD("Проверка выключения");
HAL_Delay(1000);
noDisplay_LCD();
HAL_Delay(1000);
display_LCD();

void cursor_LCD()

Включение отображения курсора.

void noCursor_LCD()

Выключение отображения курсора.

После инициализации библиотеки курсор не отображается на экране. Этими 2мя функциями можно включить и отключить его.

cursor_LCD();
print_str_LCD("Проверка курсора");

LCD и STM32

void blink_LCD()

Включение мигания курсора.

void noBlink_LCD()

Выключение мигания курсора.

Можно включить и отключить мигание знакоместа курсора.

cursor_LCD();
blink_LCD();
print_str_LCD("Проверка курсора");

void scrollDisplayLeft_LCD()

Сдвиг информации на экране влево.

void scrollDisplayRight_LCD()

Сдвиг информации на экране вправо.

Можно сдвигать текст на экране влево и вправо. Следующая программа 2 раза сдвигает текст вправо, а затем возвращает его назад.

print_str_LCD("Проверка сдвига");
HAL_Delay(1000);
scrollDisplayRight_LCD();
HAL_Delay(1000);
scrollDisplayRight_LCD();
HAL_Delay(1000);
scrollDisplayLeft_LCD();
HAL_Delay(1000);
scrollDisplayLeft_LCD();

void leftToRight_LCD()

Вывод символов слева направо.

void rightToLeft_LCD()

Вывод символов справа налево.

По умолчанию символы печатаются слева направо. Так мы пишем. Но можно изменить на противоположное направление.  Даже не могу предположить, кому это может потребоваться. Следующий код выводит символы с 10 позиции справа налево.

rightToLeft_LCD();
setCursor_LCD(10, 1);
write_LCD('1');
HAL_Delay(1000);
write_LCD('2');
HAL_Delay(1000);
write_LCD('3');
HAL_Delay(1000);
write_LCD('4');

LCD и STM32

void autoscroll_LCD()

Включение автопрокрутки.

void noAutoscroll_LCD()

Выключение автопрокрутки.

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

void createChar_LCD(uint8_t location, uint8_t charmap[])

Функция позволяет создать пользовательский символ.

  • uint8_t location – код символа (0…7).
  • uint8_t charmap[] – массив пикселей символа (5x8).

Следующий код задает и выводит новый символ – ”рожицу”.

uint8_t smile[8] = {
  0B00000000,
  0B00010001,
  0B00000000,
  0B00000000,
  0B00010001,
  0B00001110,
  0B00000000,
  0B00000000
};

createChar_LCD(1, smile); // создаем символ
clear_LCD();
print_str_LCD("Новый символ: ");
write_LCD(1);

LCD и STM32

void writeByte_LCD(uint8_t dt)

Запись байта в контроллер дисплея. Функция может быть использована для реализации пользовательских  команд.

Все примеры урока есть в этом проекте.

  Зарегистрируйтесь и оплатите. Всего 40 руб. в месяц за доступ ко всем ресурсам сайта!  

Библиотека LCD780 не использует объектно-ориентированные возможности программирования. Ее можно применять в обоих вариантах языка: С и C++. Скорее это положительное свойство. Я специально создавал не объектно-ориентированный вариант библиотеки.

 

Но планирую сделать и ООП-вариант библиотеки. Конечно,  если у меня до этого ”дойдут руки” или ”голова”. Постараюсь.

Предыдущий урок     Список уроков     Следующий урок

0

Автор публикации

не в сети 1 день

Эдуард

123
Комментарии: 1548Публикации: 160Регистрация: 13-12-2015

8 комментариев на «Урок 25. Подключение знакосинтезирующих LCD дисплеев к STM32. Библиотека LCD780.»

  1. Вот сколько не смотрел вариантов,а захотелось свой велосипед ,так сказать максимально универсальный,где можно выбрать как с проверкой флага bf и 8 или 4bit и чтоб легко настраивать gpio, не через hal и с любыми ногами : https://mega.nz/#!DfoDDaRa!H8ye_xw6tgihfLWiLQlHswaV6xheoUQYA1uU-Y-51Q0

    0
  2. Эдуард спасибо за урок. Хотелось бы увидеть урок, в котором измеряется аналоговый сигнал и значение АЦП выводится на подключенный индикатор. Я все это делал на Microchipe используя assembler. Теперь изучаю STM32 и планирую собрать стенд, который будет измерять температуру объекта при помощи
    1) MCP9700 (измеряется напряжение на выходе датчика и потом высчитывается темпетатура Uo=500mV+10mV/C*t)
    2) 1- Wire датчика
    3) ИК датчика
    Я всё это делал на ассемблере на PIC. Алгоритмически всё понятно. Теперь буду привыкать к С.

    0
    • Здравствуйте!
      Именно это и будет в следующих уроках про АЦП. Один уже написан, но все время меняю представление материала. Очень много регистров АЦП, много информации.

      1
  3. Добрый день, Эдуард! Огромное Вам спасибо за Ваш огромный труд. Уроки замечательные. У меня вопрос. Скажите, пожалуйста, можно применять библиотеки, написанные для различных датчиков Ардуино в среде Keil для stm32. Не хочется (вернее хочется, но нет времени) изучать Datasheet на все цифровые датчики (температуры, освещенности, тока и т.п.). Я искал в интернете подобную информацию, но пока безрезультатно Заранее спасибо.

    0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".