Library 16- Interfacing HD44780 LCD controller with STM32F4

HD44780 LCD on STM32F4xx16th library is here. We will interfacing HD44780 (and its compatible) driver for alpha-numeric LCDs. Library supports up to 20 x 4 LCD size. It was tested with 20 x 4 (on picture) and with 16 x 2.

HD44780 Library


  • 4bit operation mode
  • Minimum GPIOs used (6)
  • Supports different LCD sizes
  • Supports up to 8 custom characters
  • Enable/disable cursor blinking
  • Show/hide cursor
  • Shift content in ram left/right
  • Connection pins to board are user selectable
  • Automatically jumps to new line when you reach max X on LCD
  • Strings with \n, \r or \n\r
    • With \n in string LCD jumps to lower line, but X position stays the same
    • With \r in string LCD jumps to the beginning of the line
    • With \n\r in string LCD jumps to the beginning of a new line

Library dependencies

    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
  • TM
    • TM DELAY
    • TM GPIO
    • defines.h
GND GND Ground
VCC +5V Power supply for LCD
V0 Potentiometer Contrast voltage. Connect to potentiometer
RS PB2 Register select, can be overwritten in your project’s defines.h file
RW GND Read/write
E PB7 Enable pin, can be overwritten in your project’s defines.h file
D0 Data 0 – doesn’t care
D1 Data 1 – doesn’t care
D2 Data 2 – doesn’t care
D3 Data 3 – doesn’t  care
D4 PC12 Data 4, can be overwritten in your project’s defines.h file
D5 PC13 Data 5, can be overwritten in your project’s defines.h file
D6 PB12 Data 6, can be overwritten in your project’s defines.h file
D7 PB13 Data 7, can be overwritten in your project’s defines.h file
A +3V3 Backlight positive power
K GND Ground for backlight

If you need to change your pins, open defines.h files, add lines below and edit them.

Functions and enumerations

All possible functions are listed below.


Project is available on Github, download library below.

TM STM32F4 HD44780 Library

HD44780 (and compatible) LCD driver controller


Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • octopus

    nice library, but can I display a numerical values with that? For example uint8_t, how can I display value of that type on lcd with this library?

    • You can display numbers on lcd. You have to convert them first to string. You can use sprintf function for that.

      • octopus

        Ok, I supposed that, thx

  • stm32

    Why are you not settings the RW pin for the LCD, or am I missing something?

    • R/W pin is used to read data. Do you need to read anything from LCD?
      Maybe “ready” bit, but it’s not so necessary.

      • stm32

        Ah right, when I last used an HD44780 it was wired to the board, so I assumed it was necessary. So instead of letting the chip control it, I should just wire it to ground for write mode? I’m trying to get this working and I’m just seeing a blank screen.

        • You are right. Connect it to ground.
          Please re-download library, because I’ve made some changes 10-15 minutes ago. I’ve changed default D7 and D6 pins. Read new pinout table.

          • stm32

            I had actually changed all of the pins, I’m using a Fez Cerb40 II( ), so some of the pins you had chosen were inaccessible to me. I’m using A5 downto A0.

          • Still not working?

            Well, I was testing now again, and works great. Maybe contrast pin is not set correctly?

          • stm32

            I tried messing with my potentiometer a bit more. It’s possible that the LCD is broken, I can see the cursor flashing but the text I told it to put is not displayed correctly. I’ll need to get a new one and swap it out to see. Thanks for your help, I really appreciate it!

          • Huh. It might be broken. Well, report here what was the problem if you found it. Have a nice day 🙂

          • stm32

            Will do, I am also considering that my potentiometer is not large enough. You have a good one too!

  • ali


    can i use this library for stm32f103?

    i changed all stm32f4xx.h and stm32f4xx_xxx.h(like stm32f4xx_rcc.h)to
    stm32f10x.h and stm32f10x_xxx.h.

    but now i have an error( in the tm_stm32f4_delay.h) :

    (this error is related to the “__STATIC_INLINE void Delay(uint32_t micros)”
    function and in line 122)

    compiling main.c…

    ..tm_stm32f4_delay.h(122): error: #77-D: this declaration has no storage
    class or type specifier

    ..tm_stm32f4_delay.h(122): error: #65: expected a “;”

    ..tm_stm32f4_delay.h(155): warning: #12-D: parsing restarts here after
    previous syntax error

    ..tm_stm32f4_delay.h(157): error: #169: expected a declaration

    ..tm_stm32f4_delay.h(178): warning: #12-D: parsing restarts here after
    previous syntax error

    ..main.c(36): warning: #223-D: function ”

    please help me

  • Pingback: COIDE İLE NUCLEO-F401RE PROGRAMLAMA – Karakter LCD Uygulaması -

  • Morten Gjedrem

    Thank you for this driver. It works as it should. Only thing is that when I am using it, it really slows down my code. I have the STM32F4 Discovery setup with 4 ADC channels sampling at 2000Hz, also I have a working CAN bus going. When I am not including the write function in my loop I measure around 100 microsends for the code to make one loop. If I include TM_HD44780_Puts(0, 0, “STM32F4/29 Discovery”); then it takes around 1 second to make one loop (in while loop in main function). Should it behave this slowly?

  • John Mavericks

    Thanks for the library!

    I’m struggling to get it to work with a 16×2 HD44780 LCD though. I’ve modified the pin allocations to match mine:

    My allocations:
    D0-D7: GPIOD.0-7
    RS: GPIOB.0
    R/W: GPIOB.1
    E: GPIOB.2

    The code:

    #define TM_HD44780_RS_RCC RCC_AHB1Periph_GPIOB
    #define TM_HD44780_RS_PORT GPIOB
    #define TM_HD44780_RS_PIN GPIO_Pin_0
    /* E – Enable pin */
    #define TM_HD44780_E_RCC RCC_AHB1Periph_GPIOB
    #define TM_HD44780_E_PORT GPIOB
    #define TM_HD44780_E_PIN GPIO_Pin_2

    /* D4 – Data 4 pin */
    #define TM_HD44780_D4_RCC RCC_AHB1Periph_GPIOD
    #define TM_HD44780_D4_PORT GPIOD
    #define TM_HD44780_D4_PIN GPIO_Pin_4
    /* D5 – Data 5 pin */
    #define TM_HD44780_D5_RCC RCC_AHB1Periph_GPIOD
    #define TM_HD44780_D5_PORT GPIOD
    #define TM_HD44780_D5_PIN GPIO_Pin_5
    /* D6 – Data 6 pin */
    #define TM_HD44780_D6_RCC RCC_AHB1Periph_GPIOD
    #define TM_HD44780_D6_PORT GPIOD
    #define TM_HD44780_D6_PIN GPIO_Pin_6
    /* D7 – Data 7 pin */
    #define TM_HD44780_D7_RCC RCC_AHB1Periph_GPIOD
    #define TM_HD44780_D7_PORT GPIOD
    #define TM_HD44780_D7_PIN GPIO_Pin_7

    And modified the relevant main code:
    TM_HD44780_Init(16, 2);
    TM_HD44780_Puts(0, 0, “STM32F4/29 Discovery”);
    TM_HD44780_Puts(0, 1, “16×4 HD44780 LCD”);
    TM_HD44780_PutCustom(0, 1, 0);

    Sorry for the long snippets of code! What am I doing wrong? I feel like an idiot for not being able to figure it out :p

    • Hello,

      well, don’t feel like that 😀

      Let’s make some tries now:
      – Library does not use RW pin, so it must be tied to LOW. If you have GPIO pin for that connected to LCD, then init that PIN as output and set it LOW.
      – Connect potentiometer between VCC and GND and connect middle pin to LCD contrast (pin 3). Try to rotate potentiometer to see if anything is there on LCD.

      • John Mavericks

        Thanks for replying! Well I’ve already got a basic library that works and the LCD displays text like it should, but I’d prefer to use your library as it’s much more concise and the functions are much easier to use. I definitely feel like it might be a pin alignment issue. Here’s how they’re currently initialised: (don’t want to fill up comments full of code)

        • Oh maaan..looking at these bits I loose my mind.
          I have no idea looking at this bits if they are set up.

          • John Mavericks

            Haha I know right? I think I’ve managed to sort it out though!

  • Nonthakron Suchittaapirom

    can i use this library with another LCD
    I dont have HD44780 LCD but I have MTC-16204X LCD
    if I connect pin above this library will work with MTC-16204X LCD?

    • Hi,

      I have no idea, but if your controler is compatible with HD44780 then you can use it.

      • Nonthakron Suchittaapirom

        Thanks for replying
        I will use with LCD 16 x 2 so what I need to edit or set in this library?

  • Tôn Quyền Ngô

    Can you write an example code to send a numeral value (eg: uint32_t counter) to LCD using sprintf funtion like you did in other LCD projects? Many thanks in advance.

    • Kidding me, right?
      Look there and thats it.

      • Tôn Quyền Ngô

        Sorry to confuse you, but I mean that for all of your HD44780 library, I can find how to display char on the LCD, not the number (in my case, the encoder value of Phase A and Phase B). To display the number, we have to use sprintf to convert it to char, but I don’t know how. Can you write some lines of code for this?

        • Really?

          Can’t you look at my other examples how to use sprintf?
          Oh man. The time you spend writing this commens, you will have done it.

  • chauvoluuhuong

    hi ! please help me a little bit about TM_HD44780_Cmd4bit() function , according to what i see that it placed in TM_HD44780_Clear() or TM_HD44780_ScrollRight() that
    that meaning it will send a instruction to ic 44780 but in datasheet told that in mode 4bit ( use 4 line to connect with LCD ) the 4bit higher will send
    before 4 low bit , and at function i mention TM_HD44780_Cmd4bit() it just send 4 low bit

    what about 4 higher bit ???
    thank very much

    • This is private function and is not meant for public use.
      Where I need this function, I always make 2 calls with high and low nibbles.

      PS: In Clear function is not CMD4BIT but is CMD only.

      • chauvoluuhuong

        oh thank you was got mistake , sorry about my trouble

  • ismailcal

    I do LCD display control keypad with stm32f4 discovery .
    But this way I describe in the alphabet series LCD screen if I only want what you’re trying to write his letter to the directory LCD.
    After the sequence elements in the code I have written I have written show .

    char *dizi;
    char alfabe[]={‘A’,’B’,’C’,’D’};

    I want to print only the letter B on the LCD screen, but the screen
    BCD writes. = & alfabe[2];
    I do CD writing . I want to write C .
    I’m sorry if my english is bad, very few know the sentence .

    • Use Putc function.

      • ismailcal

        I’m sorry , but did you have to write as follows.
        I get an error if I write in this way.
        I asked if we will show the sequence of the
        alfabe[1] element code you show how it would be

        • This is your C related problem. Check C examples online.

          • ismailcal

            What I do not have tm_stm32f4_hd44780.c file putc function.

          • TM_HD44780_Putc

          • ismailcal

            putc is not about giving error code in the library file. How can I add this command to the library files

          • Not sure i understand you.

          • ismailcal

            I’m sorry for my bad english

  • Karol

    Hey, i have a problem with this library. I am using 16×2 lcd. The text is not displayed correctly. For example, when i put “gowno” the text on the display says “ggwfg” and the text only appears when i set coordinates to [0,0]. When i want to put text in for example [1,0] or skip to the other line the text doesnt show up at all. I think i have proper clock seetings, 180MHz SysClk, HSE set at 8Mhz, here is my RCC config function:

    void RCC_Config(){

    ErrorStatus HSEStartUpStatus;

    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    if(HSEStartUpStatus == SUCCESS){
    while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    while(RCC_GetSYSCLKSource() !=0x08);

  • Karol

    Hey, i have a problem with this library. I am using 16×2 lcd. The text is not displayed correctly. For example, when i put “gowno” the text on the display says “ggwfg” and the text only appears when i set coordinates to [0,0]. When i want to put text in for example [1,0] or skip to the other line the text doesnt show up at all. I think i have proper clock seetings, 180MHz SysClk, HSE set at 8Mhz, I am using STM32F429 Discovery Board. Here is my RCC config function:

    • Hi,

      nice you correct your mistake.
      Well, I run this lib with success. It uses delay so clock MUST be set OK.

      If you send me a project and your pinout to email, I can take a look for you.

      Have a nice day.

  • Christian Julius

    Works straight forward from scratch, 1h from soldering and wiring to display texts 🙂

  • KamykPL

    Hi, thanks for all libs and stuff. Great job!
    Got an issue with defines.h – it doesn’t work.
    I set up my pins for LCD and it doesn’t overwrite them. I set my pins in “tm_stm32f4_hd44780.h” and they work fine (but it’s not how it should be done).
    Project files are in default places. Board: STM32F407VGT6 and Keil V.5.27 with 1.0.8 pack and Libs from your GitHub.
    Do You have any idea?

    • Hello,

      not from here. Can you send me a project? I think you missed something here.

      • KamykPL

        OK, sent

  • dharmendra

    hi, i am using STM32f401 nucleo bord for programing
    i try to write program for lcd 16×2 , but not run((
    i also try your code they also not run.
    plz help me
    pin:-GPIOB, RS=pin0,EN=pin1, D4-D7=pin4-pin7

    • I’m sure you do something wrong then.
      Make sure you did everything before you made a comment.

  • dharmendra

    hi, can you help me??

  • kim

    I want to connect my stm32F407VG to ST7066U driver , is it the same as for HD44780 ?

    • Pradeep Chl

      Hello Kim, Did you find the ST7066U driver for stm32f4 ?

  • Mateusz

    Hi, when I copied all things I have problem, with tm_stm32f4_hd44780.c file,

    I have error in function :

    static void TM_HD44780_Cmd(uint8_t cmd) {
    /* Command mode */
    /* High nibble */
    TM_HD44780_Cmd4bit(cmd >> 4);
    /* Low nibble */
    TM_HD44780_Cmd4bit(cmd & 0x0F);

    and Error is no member named ‘BSRRH’ in GPIO_TypeDef

    • This library is not for HAL drivers.

      • Mateusz

        I dont use HAL
        Can you tell me what Should I do or Can I send You a project ?

        • This lib works for STM32F4xx STD libraries ONLY.

          • Mateusz

            Yes and I use this one.

          • My stm32f4xx.h file has this definition inside GPIO_TypeDef structure.

          • Mateusz

            Ok i will check it, because I downlad this lib STM32F4xx_StdPeriph_Driver

          • Mateusz

            Where Can I find your stm32f4xx.h file ?

          • On Github.

          • Mateusz

            I know but I cant find stm32f4xx.h, in standard libraries

          • STANDARD_LIBRARY/CMSIS/Device/ST/STM32F4xx/Include/

          • Mateusz

            But in this file there isnt GPIO_SetPinLow 🙁

          • I never said it is. I said, in that file is GPIO_TypeDef structure which has member where your problem is.

          • Mateusz

            yes i see the problem, because I have new version with only one register BSRRH

          • Mateusz

            Can you tell me where can I find definition of TM_GPIO_SetPinLow ?

          • TM_GPIO_… means TM, GPIO library.

          • Mateusz

            Ok i find ((GPIOx)->BSRRH = (GPIO_Pin)) and I will change it
            ((GPIOx)->BSRR = (GPIO_Pin))

          • You are doing something wrong! I downloaded latest STD drivers right now, version 1.7. There are still BSRRH and BSRRL members in structure!

            stm32f4xx.h version 1.7.0, 22-april-2016

          • Mateusz

            I will be very grateful if you can look in my project

          • I knew! I told you that you use HAL drivers but you said you are not! Of couse your are using HAL! ALl that libraries in project won’t work ok!

          • Mateusz

            Did You see my project which I send You ?

          • I did. And from that source, I told you. stm32f4xx.h is for HAL drivers designed!

          • Mateusz

            Thanks for it, can you tell me what I should do ?

          • Mateusz

            So How should I proper set the project for STM32f407 ?

          • Mateusz

            I create project on that way :
            1. I chose my stm
            2. I chose CMSIS -> CORE
            3. I chose Device -> Startup

          • 1. Use my libraries for HAL or
            2. Use these libraries but then don’t use HAL

          • Mateusz

            Now i used Hal Drivers but I have error in file hal_rcc.h
            unknow type : uint32_t

          • Would you mind to download my HAL github repository as starting point? And continue there with project? This library is not for HAL. Any further comments in this library regarding HAL problems will be blocked.

          • Mateusz

            Ok, sorry

  • Mateusz

    Hello, I have got question . How Can I put integer to the display. For example I have some data from DHT11 sensor and in my data container i have tempreture dht11Data[0] and humidity in dht11Data[2]. I would like to display the tempreture and humidity on display.
    Which function I shoud use ?

    if (DHT11_OK == DHT11_Read(dht11Data))
    // what function from your lib I should put here ?
    else /* wrong checksum or timeout */
    TM_HD44780_Puts(0, 1, “DHT11: ERROR on read”);

    • Convert int to string, then use string function.

      • Mateusz

        Can you give me any example because itoa doesnt work on STM

        • Mateusz

          It should be something like that :

          char c;

          c = sprintf(buf, “%d”, dht11Data[0]);

          TM_HD44780_PutCustom(0, 1, c);


  • smith

    Hello When I try to include your library to my project i get this error:
    ***_Display***_Display.axf: Error: L6218E: Undefined symbol TM_DELAY_Init (referred from tm_stm32_hd44780.o).

    • smith

      I am using a STM32F030C6T6 and Keil uVision5

    • Dependency section says which files you also need.

  • sill

    Some characters and numbers like “8,k,l,m,n,x,z,…” don’t show up right on the LCD using STM32F429.
    I have changed some part of the code for initializing the GPIOs to be suitable for stm32f107vc MCU and it worked just fine but for my discovery board it doesn’t work. I don’t know what to do…please help me?

  • maryem

    i downlodoad the zip files that you bublished but it seems that they are not compatible with stmcube mx V4.19 can you tell me what should i do ! i’m a bigenner
    thnx 🙂