STM32. 5. Символьный дисплей HD44780

STM32. 4. Последовательный порт (UART)

Для вывода текстовой информации различного содержания удобно применять символьные дисплеи в виду их распространённости и простоты использования. В основе большинства таких дисплеев лежит контроллер HD44780, который позволяет подключаться к дисплею по 4 или 8 линейной шины данных и 3-х линий управления.

WH1602 подключенный к STM32

WH1602 подключенный к STM32

В статье расскажу, как подключить такие дисплеи по упрощенной 4-х проводной линии данных с 2-мя линиями управления к контроллеру STM32F100RB установленному на STM32vlDiscovery с помощью двух библиотек: для дисплеев с HD44780 контроллерами и Standard Peripheral Library.

Как и в предыдущей статье по применению дисплея от nokia1100 с stm32 контроллером за основу возьму свой старый код, написанный под PIC контроллер, адаптирую и оформлю в библиотеку.

Из-за того, что большинство winstar дисплеев (на нашем рынке среди символьных дисплеев на HD44780 преобладают они) имеют 5В питание и логику – это внесёт некоторые особенности их подключения к 3,3В stm32 контроллерам. А именно:
Во-первых: понадобиться 5В источник питания для дисплея, в наше случае на Discovery он есть;
Во-вторых: такой дисплей можно подключить или через согласователь интерфейса , или только к 5В толерантным выводам контроллера с подтяжкой к 5В. Воспользуемся вторым способом. Из таких выходов удобно и подряд расположенные это: RB10 – RB15.

Схема

Схема

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

Небольшой резисторный ад под дисплеем

Небольшой резисторный ад под дисплеем

Вдаваться в специфику работы дисплеев построенных на HD44780 не буду, если кому интересно в Интернете такого материала много, например можно посмотреть на сайте gaw.ru . Способы общения с такими дисплеями давно реализованы, и взяв за основу свой старый код сформировал библиотеку под stm32. О ней и расскажу. Для работы с дисплеем остается только добавить в проект 2 файла: lcd-hd44780.c и lcd-hd44780.h , сконфигурировать выводы для работы с дисплеем и работать в своё удовольствие.

Возможности библиотеки:
lcd44780_init_pins() — конфигурирование выводов дисплея
lcd44780_init() — инициализация дисплея
lcd44780_ClearLCD() – очистка дисплея
lcd44780_SetLCDPosition(x,y) — установка курсора
x, y – положение курсора
lcd44780_ShowChar(c) — вывод символа в ASCII
c – символ
lcd44780_ShowStr(*s) — вывод строки
*s – ссылка на строку (массив символов)

Конфигурация порта для работы с дисплеем, описанная в lcd-hd44780.h

//			Конфигурация порта
//	используемый порт
#define lcd44780_port		GPIOB
//	используемые выводы
#define lcd44780_pin_RS		GPIO_Pin_11
#define lcd44780_pin_E		GPIO_Pin_10
#define lcd44780_pins_data	GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15
//	включить тактирование порта
#define lcd44780_RCC		RCC_APB2Periph_GPIOB
//	смещение начала линии данных
#define lcd44780_offset 	12

Библиотека рассчитана на подключения дисплея с помощью 6-ти линий одного порта контроллера. Две линии управления на этом порте могут быть любыми, а вот 4 линии данных должны идти подряд.

В примере дисплей подключен к 5В толерантным линиям порта B, выводы с открытым коллектором. Линии управления E – PB10, RS – PB11. 4 подряд идущих линии данных: PB12, PB13, PB14, PB15 и ещё указано смещение 12, т.к. начинаем с 12 вывода порта.

После задания конфигурации выводов в коде вызываем конфигурирования выводов дисплея функцией — lcd44780_init_pins(), далее инициализируем дисплей — lcd44780_init() и можно с ним работать.

Код примера:

lcd44780_init_pins();	//	конфигурирование выводов дисплея
lcd44780_init();		//	инициализация дисплея
lcd44780_ShowStr(«wh1602 + STM32»);//	вывод надписи на дисплей
lcd44780_SetLCDPosition(5, 1);// 	установка курсора
lcd44780_ShowStr(«alex-exe.ru»);//	вывод надписи на дисплей
while(1==1){} 			//	основная программа в бесконечном цикле

Скачать библиотеку для работы с дисплеями на основе контроллера HD44780

Скачать файлы проекта

STM32. 6. АЦП, RTC или что-то другое

37 комментариев »

Alex_EXE | 14.09.2013 | STM32 |

37 комментариев на « STM32. 5. Символьный дисплей HD44780»

  1. Nobody пишет 16.09.2013 в 09:49 #

    А не пробовали подключить дисплей с питанием от 3.3 В?
    По идее на самом дисплее есть место для установки микросхемы 7660 и пары конденсаторов, для получения отрицательного напряжения для контрастности. Утверждается что будет работать даже от 2.5 В.
    Так же без проблем можно вывести на одну из ножек контролера меандр. Резистор, пара конденсаторов и диодов и получим отрицательное напряжение.

  2. Alex_EXE пишет 16.09.2013 в 23:35 #

    5В дисплей от 3,3 не заводиться, а 3,3В дисплея у меня нет.
    О допиливании дисплея не задумывался + для цикла обучающих статей лучше использовать стандартный и распространённый дисплей.
    В интернете посмотрел, как народ дорабатывал дисплей, несложно, может как-нибудь попробую.

  3. Тимофей пишет 24.09.2013 в 15:33 #

    напиши скорее статью о ШИМ на stm32

  4. Alex_EXE пишет 24.09.2013 в 17:52 #

    Могу огорчить, до ШИМ еще далеко.

  5. Алексей пишет 23.10.2013 в 15:51 #

    Как быть если линии данных и линии управления дисплея подключены к разным портам микроконтроллера? Линии данных — один порт, линии управления — другой порт.

  6. Alex_EXE пишет 29.10.2013 в 00:20 #

    Тогда придётся подкорректировать библиотеку:
    #define lcd44780_RS_1 GPIO_SetBits(lcd44780_port, lcd44780_pin_RS);
    #define lcd44780_E_1 GPIO_SetBits(lcd44780_port, lcd44780_pin_E);
    #define lcd44780_RS_0 GPIO_ResetBits(lcd44780_port, lcd44780_pin_RS);
    #define lcd44780_E_0 GPIO_ResetBits(lcd44780_port, lcd44780_pin_E);

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

  7. Boyko пишет 30.01.2014 в 19:30 #

    Alex_EXE — огромное спасибо 🙂 помогла статья безмерно. Но инструкцию по подключению таки надо было мне выполнить полностью 🙂 пока подтяжку не подключил — фигвам, а не работа. Единственная модификация — 15-16 выводы дисплея на питание и землю — чтоб подсветку включить — с ней прикольнее. Спасибо за науку.

  8. Alex_EXE пишет 01.02.2014 в 03:04 #

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

  9. Aleksandr пишет 05.02.2014 в 17:46 #

    Здравствуйте
    А кириллицу может выводить? Или это от дисплея зависит?
    Подключил китайский клон keypad shield for arduino. Англ.буквы выводит, а русские нет.

  10. Пономарев Андрей Викторович пишет 05.02.2014 в 19:37 #

    Здравствуйте!
    Спасибо большое за статью. Предложенное решение заработало без вопросов с малыми коррективами и на STM32F051, даже не пришлось с таймингами возиться, хотя чип работает на частоте 48 МГц. Хоть и сам не первый год преподаю электронику в УрФУ (Екб) — но за всем угнаться не получается. И ПЛИС и «Дельты» и AVR ещё не успел до конца освоить, как STM на пороге.
    Уже возраст — и новое дается не так быстро. Но изучать приходится. Хорошо, что есть интернет и добрые люди, которые могут помочь и у которых не грех самому поучиться.
    А.В. Пономарев, cнc лаборатории импульсной техники ИЭФ УрО РАН, доцент каф. электрофизики УрФУ.

  11. Alex_EXE пишет 06.02.2014 в 03:38 #

    Aleksandr
    У символных дисплеев от дисплея зависит, одни содержат кирилицу, точнее кирилические символы (Б,Ю,Ы,Я… , остальные, точнее похожие на латинские берутся из латинских — A,E,m…), другие содержат китайские символы, третьи …
    Пономарев Андрей Викторович
    Рад, что материал оказался полезен. УрФУ хорошо знаю, так то местный.

  12. apon62 (АВПономарев) пишет 06.02.2014 в 19:26 #

    Эх! К этой замечательной библиотеке ещё бы аналоги функций CodeVision, таких как ftoa и itoa для преобразования числовых данных в строку для последующего вывода их на экран!

  13. Aleksandr пишет 08.02.2014 в 14:13 #

    Возник вопрос.
    Пусть данные записались на экран.
    Как сделать чтобы они исчезли и снова появились?
    Есть бит D, который отвечает за вкл/выкл экран. Есть вот эта команда lcd44780_WriteByte(0x0C); Как я понял она включает экран. Я попробовал записать lcd44780_WriteByte(0x08); но ничего не изменилось. Данные как были на экране, так и остались.

  14. Alex_EXE пишет 12.02.2014 в 00:57 #

    apon62 (АВПономарев)
    К сожалению таким функционалом пока не располагаем, но Вы можете его добавить 🙂
    Aleksandr
    Эту команду не проверял и сейчас возможности проверить нет. Ещё может быть, что используемый дисплей данную команду не поддерживает.

  15. Роман пишет 15.02.2014 в 15:50 #

    Допустим имеется переменная tmp в которую записываются разные числа от 1 до 10. Как вывести на дисплей то что заносится в переменную?

  16. Alex_EXE пишет 16.02.2014 в 23:17 #


    void lcd_int(unsigned long p)
    {
    while(p>0)
    {
    lcd44780_ShowChar(p%10+'0');
    if(p==10)
    lcd44780_ShowChar('0');
    p=p/10;
    }
    }

    Простая функция вывода числа на экран, нет ничего сложного.

  17. Yura пишет 24.02.2014 в 19:11 #

    Подключил четырех строчный дисплей — не работает. Как адаптировать библиотеку ?

  18. Yura пишет 24.02.2014 в 21:34 #

    Все получилось. вместо подстроечника на контрастность был впаян резистор 4,7 ком. все двухстрочные дисплеи (2 шт) работали нормально. для 4-ех строчного надо другой номинал. впаял подстроечный резистор — все ок.
    Только с русским языком проблемы. может это кейл чудит….

  19. Alex_EXE пишет 24.02.2014 в 22:45 #

    Кейл чудит. Или пишите ASCI кодами или можете русские символы набирать в другом текстовом редакторе, но придется с кодировки помучаться. Подробнее об этих мучениях можете почитать в статье по подключении дисплея от nokia1100 к stm32.

  20. Yura пишет 25.02.2014 в 19:08 #

    Спасибо. Кстати исправьте номинал подстроечного резистора на схеме. Указано 470 Ом. Лучше 5 кОм.

  21. Max пишет 10.03.2014 в 21:54 #

    Подскажите пожалуйста что может быть не так. Залил проект через кеил, подключил все по схеме. На экране один ряд из черных квадратов.. Экран WH1602D.

  22. Alex_EXE пишет 11.03.2014 в 14:33 #

    Подкрутите или замените резистор, что отвечает за контрастность.

  23. Max пишет 11.03.2014 в 16:19 #

    Был на 10k. заменил на 5k. Если крутить резистор — строка плавно исчезает и появляется. На 0 яркие квадраты, на +5 их нет вообще.
    И еще Keil ругается на ShowStr — Warning: passing ‘char [15]’ to parameter of type ‘unsigned char *’ converts between pointers to integer types whith different sign.

  24. Max пишет 11.03.2014 в 17:00 #

    И при нажатии reset на stm ничего не происходит. Квадраты так и остаются. Догадываюсь, что проблема с инициализацией. Подсоединил экран qc1602a v2.0. Та же история.

  25. Alex_EXE пишет 13.03.2014 в 15:44 #

    Эти квадраты — не связаны с кодом, это так себя ведет дисплей при изменении контрастности.
    Если на дисплей не чего не выводится — то смотрите правильность подключения и правильно ли назначены выводы на МК. Ещё можно проверить задержки.
    Ругань компиляторов на строки — нечего страшного. Если всё таки напрягает — то можете в функциях:
    void lcd44780_ShowChar(ubsigned char c)
    void lcd44780_ShowStr(ubsigned char *s)
    заменить ubsigned char на простой char, в файлах lcd-hd44780.c и lcd-hd44780.h

  26. Максим пишет 04.04.2014 в 21:57 #

    Добрый день подключил к 103 изменил только в настройках камень и всё пошло) Спасибо!!!

  27. ALEN пишет 08.04.2014 в 18:31 #

    Спасибо за простую и лаконичную реализацию!
    После небольших танцев с бубном запустил и адаптировал под себя.
    1. Делать выход с поддяжкой, имхо, нет смысла. Современные индикаторы без проблем работают от имеющихся 3В.
    в файле lcd-hd44780.c строку
    lcd44780_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // выходы с открытым коллектором, нужна подвязка к +5В
    меняем на
    lcd44780_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // выходы PP
    Резисторы подтяжки на выброс.

    2. Приведённый автором вариант вывода числа работает криво. Я набросал следующую функцию:

    void lcd44780_dig(unsigned long p, unsigned char l)
    {
    if (l>7) lcd44780_ShowChar((p/10000000)%10+’0′);
    if (l>6) lcd44780_ShowChar((p/1000000)%10+’0′);
    if (l>5) lcd44780_ShowChar((p/100000)%10+’0′);
    if (l>4) lcd44780_ShowChar((p/10000)%10+’0′);
    if (l>3) lcd44780_ShowChar((p/1000)%10+’0′);
    if (l>2) lcd44780_ShowChar((p/100)%10+’0′);
    if (l>1) lcd44780_ShowChar((p/10)%10+’0′);
    if (l>0) lcd44780_ShowChar(p%10+’0′);
    else
    { if (p>10000000) lcd44780_ShowChar((p/10000000)%10+’0′);
    if (p>1000000) lcd44780_ShowChar((p/1000000)%10+’0′);
    if (p>100000) lcd44780_ShowChar((p/100000)%10+’0′);
    if (p>10000) lcd44780_ShowChar((p/10000)%10+’0′);
    if (p>1000) lcd44780_ShowChar((p/1000)%10+’0′);
    if (p>100) lcd44780_ShowChar((p/100)%10+’0′);
    if (p>10) lcd44780_ShowChar((p/10)%10+’0′);
    }
    lcd44780_ShowChar(p%10+’0′);//p=p/10;
    }

    Функция выводит целое число длиной до 8 знаков (можно добавить строки, если надо больше) фиксированной длины (l) либо переменной, с гашением незначащих нулей (если указать l=0).
    Функцию кидаем в библиотеку, объявляем её в .h файле и вуаля!

    Уточню схемотехнические нюансы.
    Подсветку подключаем к +5В через резистор 10…20 Ом. Если напряжение больше, сопротивление увеличиваем на 10…20 Ом на каждый вольт.
    Подстроечник регулировки контрастности может быть хоть 470 Ом, хоть 47 кОм и более, это не критично.

  28. ALEN пишет 09.04.2014 в 13:11 #

    >Современные индикаторы без проблем работают от имеющихся 3В.

    Уточню. Я имел в виду около 3В — питание МК, т.е. напряжение логической единицы на входе индикатора. Сам индикатор у меня запитан от +5В.

    >И еще Keil ругается на ShowStr — Warning: passing ‘char [15]‘ to parameter of type ‘unsigned char *’ converts between pointers to integer types whith different sign.

    Тип переменных здесь не при чем. У меня была аналогичная ошибка, когда в свежесозданный проект забыл вложить пару файлов библиотеки SPL.

  29. Виктор Всеволодович пишет 21.09.2014 в 23:17 #

    для кириллицы
    const unsigned char ansii_table_for_epson[256]=
    {
    /*0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    /*1*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    /* ! » # $ % & ‘ ( ) * + , — . */ /*in*/
    /* ! » # $ % & ‘ ( ) * + , — . */ /*out*/
    /*2*/ ‘ ‘,’!’ ,'»‘ ,’#’ ,’$’ ,’%’ ,’&’ ,0x27,'(‘ ,’)’ ,’*’ ,’+’ ,’,’ ,’-‘ ,’.’ ,’/’ ,
    /* 0 1 2 3 4 5 6 7 8 9 : ; ?*/
    /*3*/ ‘0’,’1′ ,’2′ ,’3′ ,’4′ ,’5′ ,’6′ ,’7′ ,’8′ ,’9′ ,’:’ ,’;’ ,» ,’?’ ,
    /*4*/ ‘@’,’A’ ,’B’ ,’C’ ,’D’ ,’E’ ,’F’ ,’G’ ,’H’ ,’I’ ,’J’ ,’K’ ,’L’ ,’M’ ,’N’ ,’O’ ,
    /* P Q R S T U V W X Y Z [ \ ] ^ _ */
    /* P Q R S T U V W X Y Z [ Ф ] ^ _ */
    /*5*/ ‘P’,’Q’ ,’R’ ,’S’ ,’T’ ,’U’ ,’V’ ,’W’ ,’X’ ,’Y’ ,’Z’ ,'[‘ ,0x4C,0x4D,’^’ ,’_’ ,
    /* ‘ a b c d e f g h i j k l m n o*/
    /*6*/ 0x60,’a’ ,’b’ ,’c’ ,’d’ ,’e’ ,’f’ ,’g’ ,’h’ ,’i’ ,’j’ ,’k’ ,’l’ ,’m’ ,’n’ ,’o’ ,
    /* p q r s t u v w x y z { | } ~ ~ */
    /* p q r s t u v w x y z 10 12 15 cr ~ */
    /*7*/ ‘p’,’q’ ,’r’ ,’s’ ,’t’ ,’u’ ,’v’ ,’w’ ,’x’ ,’y’ ,’z’ ,0x7b,0x7c,0x7d,0x7e,0xe9,
    /*остальные спецсимволы перенесены в стобцы 8 и 9 */
    /*<> » inv№ inv? integr ‘ e’ ii o O */
    /*8*/ 0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xe7,0xe8,0xea,0xeb,0xec,0xed,0xee,0xef,
    /* epsilon */
    /*9*/ 0x7f, ‘ ‘,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,’ ‘ ,
    /*столбец D таблицы Epson перенесен в A-й*/
    /*A*/ 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
    /*столбец F таблицы Epson перенесен в B-й т.е вместо 0xf2 указываем 0xb2*/
    /*B*/ 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,
    /* А Б В Г Д Е Ж З И Й К Л М Н О П*/
    /*C*/ ‘A’,0xa0,’B’ ,0xa1,0xe0,’E’ ,0xa3,0xa4,0xa4,0xa6,’K’ ,0xa7,’M’ ,’H’ ,’O’ ,0xa8,
    /* Р С Т У Ф Х Ц Ч Ш Щ Ъ Ь Ы Э Ю Я*/
    /*D*/ ‘P’,’C’ ,’T’ ,0xa9,0xaa,’X’ ,0xe1,0xab,0xac,0xe2,0xad,0xc4,0xae,0xaf,0xb0,0xb1,
    /*а б в г д е ж з и й к л м н о п*/
    /*E*/ ‘a’,0xb2,0xb3,0xb4,0xe3,’e’ ,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,’o’ ,0xbe,
    /* р с т у ф х ц ч ш щ ъ ы ь э ю я*/
    /*F*/ ‘p’,’c’ ,0xbf,’y’,0xe4,’x’,0xe5,0xc0,0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7

    };
    ===============
    void lcd44780_ShowStr(unsigned char *s)
    {
    while (*s != 0) lcd44780_ShowChar(ansii_table_for_epson[*s++]);
    }

  30. Алексашка пишет 25.09.2015 в 12:15 #

    С вашего позволения переделал вашу функцию вывода целых чисел, т.к. из поста выше она выводит цифры задом наперёд.

    void PrintInt(unsigned int p)
    {
    char i = 0;
    unsigned char out[16];
    while(p > 0)
    {
    out[i] = p%10;
    if(p == 10) out[i] = 0;
    p = p/10;
    i++;
    }
    while(i) //while(i > -1)
    {
    i--;
    lcd44780_ShowChar(out[i]+'0');
    }
    }

  31. Денис пишет 01.08.2017 в 12:09 #

    Автору спасибо за библиотеку. Долго пытался запустить свой WH1602 на stm32f100…пока не вписал в задержку __NOP();

  32. Андрей пишет 08.01.2018 в 17:07 #

    А как применительно к этому примеру вывести на экран свои символы, не входящие в стандартные таблицы? Например символ «эпсилон» или значок «микро»?

  33. Alex_EXE пишет 08.01.2018 в 18:35 #

    Микро по аналогии с конденсаторами легко заменяется буквой u, т.е. 0.1uF.
    В закогенерирующих дисплея есть небольшой ограниченный объем памяти в которую можно записать свои символы (вроде 8). Данного отработанного материала у меня нет, точнее не подскажу.

  34. Denis Malenda пишет 10.09.2019 в 13:04 #

    Alex_exe где найти твой урок по ацп ,или его нет???

  35. Alex_EXE пишет 10.09.2019 в 14:19 #

    Его нет

  36. Павел пишет 27.04.2020 в 13:36 #

    Помогите начинающему пожалуйста.
    Не совсем понял смысл подтяжки ног к 5в через 4к7. При наличии 1 на выходе МК на вход lcd попадает 3.3в, при 0 на ноге -> на дисплее 0в, греем резистор. То же самое получается БЕЗ подтяжки, при прямом соединении с МК. Что я упускаю?

  37. Павел пишет 27.04.2020 в 14:06 #

    Разобрался ))) Режим Open Drain решает

Комментарии RSS

Оставьте отзыв