Interface LCD 16×2 via I2C with STM32
NOTE :- The following code is written with STM32CUBEIDE. If you are using keil, or any other IDE, code will still work for you. But you have to create a project and than import those files, as shown in the video.
Today I am going to interface LCD to STM32 using an I2C device (PCF8574). PCF8574 can be used as a port extender, to which LCD will be connected. If you haven’t read my previous post about I2C go check that out HERE.
As you can see above PCF8574 has 4 input pins GND, VCC, SDA, SCLand 16 output pins. We will connect our LCD to these 16 pins.
ADDRESSING of PCF8574
The higher nibble of PCF8574 address is 0100 and this is fixed. But lower nibble can be modified according to our convenience. The question you must be thinking is why we need to modify lower nibble? Well you generally don’t but as I mentioned in my previous article that we can connect upto 128 devices on the same line of I2C and let’s say we want to connect two different LCDs on the same I2C line, than we can’t use two PCF8574 with same addresses and we need to modify one of them.
So how do we modify the address?
The address of the PCF8574 is 0 1 0 0 A2 A1 A0 R/W. To change the address we are provided with A0, A1 and A2 pins.
By default these three pins are high so the address by default is 01001110 which is 0x4E.
To change the address of this device, you have to connect any/all of these three pins to ground, which is provided just above them.
So let’s say you connected A0 to ground, new address will be 01001100 which is 0x4C.
In this manner, we can connect upto 8 LCDs to the same line.
I want to point to one more thing here, the last bit of the address is kept 0 intentionally, because this bit is responsible for read(1)/ write(0) operation.
Connecting LCD to PCF8574
As shown in the figure above, first pin of the device is Vss which is pin 1 of LCD. So all you have to do is connect first pins of the LCD to Vss above and rest will connect accordingly. Starting with Vss as first pin, connection is as follows:-
1 —> Vss
2 —> Vcc
3 —> Vee
4 —> RS —> p0
5 —> R/W —> p1
6 —> En —> p2
7 —> DB0
8 —> DB1
9 —> DB2
10 —> DB3
11 —> DB4 —> p4
12 —> DB5 —> p5
13 —> DB6 —> p6
14 —> DB7 —> p7
15 —> LED+
16 —> LED-
Some Insight into the Code
The default slave address defined in the i2c-lcd.c is 0x4E. This is default for the PCF8574.
The above function will send the command to the device to which our LCD is connected. As we are using 4 bit LCD mode, we have to send command in two parts. First we send the upper nibble, and than the lower one. Both parts are sent along enable pin 1 and than with enable pin 0.
When the data_t is OR(|) with 0x0C, which implies that P2 (En) pin is high and P0 (RS), P1(R/W) are low for the command and write operation. In the second case data is sent along with 0x08 only. This is to ensure that the back light is on and En, RS, R/W are all low.
The above functions ends the data to the device to which our LCD is connected. Similarly like command, We have to send data in two parts, first upper and than lower half. Both parts are sent along enable pin 1 and than with enable pin 0. Data is OR(|) with 0x0D which implies that P2 (En) and P0 (RS) pin are high , P1(R/W) is low and back light is on, for the data and write operation. In second case data is OR(|) with 0x09 to make only RS pin high and for the back light, and all others low.
As according to the datasheet of the LCD 16×2, in order to initialize the LCD, we have to use some sequence of commands. The code is commented properly, so that you can understand it better
To send string directly, there is another function as shown below
- Interface WS2812 with STM32 April 16, 2021
- PWM with DMA in STM32 April 8, 2021
- Control Stepper motor using Rotary Angle Sensor March 21, 2021
- External Interrupt using Registers March 17, 2021
- STM32F103 Clock Setup using Registers March 3, 2021
- STM32 I2C Configuration using Registers February 26, 2021