LCD 20X4 using I2C with STM32
In this tutorial we are going to interface LCD 20×4 Display with STM32 using I2C. I am using STM32F103C8 microcontroller and I2C device is PCF8574 with the slave address of 0x4E.
You can use the same code for any other LCD display Type (i.e 16×2, 16X4 etc), except the DDRAM addresses. You can google the addresses for your LCD Type.
ARDUINO ADDRESS
Do not use the address 0x27 and 0x35. This is not arduino and these are not the addresses for your device
Arduino (IDE only… not the mcu) uses 7 bit addressing system and the rest (including STM32) uses 8 bits. Whenever you are using the I2C address, use the full 8 bits for the address. You can find the address for your device in it’s datasheet. The address will (mostly) be either 0x4E for PCF8574, or 0x7E for PCF8574A
Welcome to the real world 🙂
HOW TO
Working with these LCD displays is pretty simple. All we need to do is the following :-
- Initialize the display
- Write the address of the DDRAM
- Write the character to be dispalyed
Initialization
According to the datasheet, To initialize the 20×4 LCD we need to send some sequence of commands to the display. They are as follows:-
Wait for > 45 ms
HAL_Delay(50); // wait for >40ms
lcd_send_cmd (0x30); HAL_Delay(5); // wait for >4.1ms lcd_send_cmd (0x30); HAL_Delay(1); // wait for >100us lcd_send_cmd (0x30); HAL_Delay(10); lcd_send_cmd (0x20); // 4bit mode HAL_Delay(10);
- Send the function set instruction with the command (0x30) 3 times
- The delay between each command varies as shown above.
- This entire process is than followed by another function set command (0x20)
lcd_send_cmd (0x28); // Function set --> DL=0 (4 bit mode), N = 1 (2 line display) F = 0 (5x8 characters) HAL_Delay(1);
Send the function set command (0x28) to set the display in 4 bit mode (DL=0), 2 line display (N=1) and 5×8 fonts (F=0)
lcd_send_cmd (0x08); //Display on/off control --> D=0,C=0, B=0 ---> display off HAL_Delay(1);
- Send the command to the Display On/OFF Control
- Display off (D=0), Cursor off (C=0) and Blink OFF (B=0)
lcd_send_cmd (0x01); // clear display HAL_Delay(1);
Clear the Display by Sending 0x01.
lcd_send_cmd (0x06); //Entry mode set --> I/D = 1 (increment cursor) & S = 0 (no shift) HAL_Delay(1);
Set the entry mode of your choice. I am setting Cursor move as increment (I/D=1) and display shift as OFF (S=0)
lcd_send_cmd (0x0C); //Display on/off control --> D = 1, C and B = 0. (Cursor and blink, last two bits)
Turn the display ON (D=1) along with the choice for cursor and blinking. I am setting both to 0 (C=0, B=0)
DDRAM ADDRESS
Addresses for the DDRAM of the LCD 20×4 is shown below.
While setting an address we need to OR (|) it with the 0x80. For eg if I want to set the cursor to 2nd row, I have to set the address as (0x80|0x40).
If you want to use a 16×4 LCD than the addresses for the DDRAM are shown below. Use the same code with just the change in address.
RESULT
DOWNLOAD
You can buy me a
controllerstechcoffeeSensor by clicking DONATE OR Just click DOWNLOAD to download the code
Recent Posts
- STM32 Ethernet #10 HTTP Server (Basic) using LWIP NETCONN (RTOS) May 18, 2022
- STM32 Ethernet #9 TCP Server and Client using LWIP NETCONN (RTOS) April 26, 2022
- STM32 Ethernet #8 UDP Client using LWIP NETCONN (RTOS) April 16, 2022
- STM32 Ethernet #7 UDP Server using LWIP NETCONN (RTOS) April 9, 2022
- GPS (Neo 6M) with STM32 March 9, 2022
- BME280 with STM32 January 8, 2022