Interfacing 16x2 Alphanumeric LCD display with STM8 Microcontroller

Published  August 12, 2020   3
User Avatar Aswinth Raj
Author
Interfacing 16x2 Alphanumeric LCD with STM8 Microcontroller

The 16x2 Alphanumeric LCD display is the most commonly used display among hobbyists and enthusiasts. The display is very useful when you want to display basic information to the user and can also help in testing or debugging our code. This particular 16x2 LCD module is easily available and has been popular for a long time. You can learn more about the basics of the 16x2 LCD module in the linked article.

To continue with our series of STM8 Microcontroller tutorials, in this tutorial, we will learn how to interface a LCD with STM8 Microcontroller. We have previously interfaced 16x2 LCD with many other microcontrollers as well, the tutorials are listed below and you can check them if interested.

If you are new to STM8, do check out the getting started with the STM8 Microcontroller article to understand the basics of the controller board and programming environment. We will not be covering the basics in this tutorial.

Working of 16x2 LCD Display

As the name suggests, a 16x2 LCD will have 16 Columns and 2 Rows. So in total, we will be able to display 32 characters on this display and these characters can be alphabets or numbers or even symbols. A simple 16x2 LCD pinout that we use in this tutorial is shown below-

16x2 LCD display

As you can see, the display has 16 pins and we can divide it into five categories, Power Pins, contrast pin, Control Pins, Data pins, and Backlight pins as shown in the table below. We will get into the details of each pin when we discuss the circuit diagram of this tutorial.

Category Pin NO. Pin Name Function
Power Pins 1 VSS Ground Pin, connected to Ground
2 VDD or Vcc Voltage Pin +5V
Contrast Pin 3 V0 or VEE Contrast Setting, connected to Vcc through a variable resistor.
Control Pins 4 RS Register Select Pin, RS=0 Command mode, RS=1 Data mode
5 RW Read/ Write pin, RW=0 Write mode, RW=1 Read mode
6 E Enable, a high to low pulse need to enable the LCD
Data Pins 7-14 D0-D7 Data Pins, Stores the Data to be displayed on LCD or the command instructions
Backlight Pins 15 LED+ or A To power the Backlight +5V
16 LED- or K Backlight Ground

On the backside of the LCD, as shown in the image below, you will find two black dots, inside which we have the HD44780 LCD driver IC (encircled in red). Our microcontroller should communicate with this IC which in turn will control what is being displayed on the LCD. If you are curious to know how exactly all this works you should check out the working of 16x2 LCD display where we have already discussed how the LCD works in detail.

HD44780 LCD Driver IC

In this tutorial, we will discuss the circuit diagram and code to display alphamerical characters (alphabets and numbers) on a 16x2 LCD display using simple LCD_print_char and LCD_print_string commands. These commands can directly be used in the program after including our header file. The header file deals with all most of the stuff for you so it is not mandatory to know how the display or the HD44780 driver IC works.

Circuit Diagram to Interface LCD with STM8 Microcontroller

The complete STM8 LCD Circuit can be found in the below image. As you can see the connection for STM8S103F3P6 Controller with LCD is very simple, we have the LCD display directly connected to our board and the ST-link is also connected to program the board.

Interface LCD with STM8 Microcontroller Circuit Diagram

The power pins Vss and Vcc are connected to the 5V pin on the STM8S board, note that the operating voltage of LCD is 5V and is connected to operate on 3.3V. So even though the STM8S103F3P6 Microcontroller operates on 3.3V is mandatory to have a 5V supply for the LCD, you can avoid this by using a charge controller IC but we won’t be discussing that in this tutorial.

Next, we have the contrast pin which is used to set the contrast of the LCD, we have connected it to the potentiometer so that we can control the contrast. We have used a 10k pot, but you can also use other nearby values, the pot acts as a potential divider to provide 0-5 V to the contrast pin, typically you can also use a resistor directly to provide around 2.2V for reasonable contrast value. Then we have the reset (RS), Read/Write (RW), and Enable (E) pins. The read-write pin is grounded because we won’t be reading anything from the LCD we will only perform write operations. The other two control pins Rs and E are connected to PA1 and PA2 pins respectively.

Then we have the data pins DB0 to DB7. The 16x2 LCD can operate in two modes, one is an 8-bit operation mode where we have to use all the 8 data pins (DB0-DB7) on the LCD and the other is the 4-bit operation mode where we only need 4 data pins (DB4-DB7). The 4-bit mode is commonly used because it requires less GPIO pins from the controller, so we have also used 4-bit mode in this tutorial and have connected only pins DB4, DB5, DB6, and DB7 to pins PD1, PD2, PD3, and PD4 respectively.

The last two pins BLA and BLK are used to power the internal backlight LED, we have used a 560-ohm resistor as a current limiting resistor. The ST-Link programmer is connected as always like in our previous tutorial. I made the complete connection on the breadboard and my set-up looks like this shown in the image below.

Interface LCD with STM8 Microcontroller

STM8 LCD Library – Header File for STM8S103F3P6

Before we proceed in the circuit diagram, let's get the STM8 LCD header file from GitHub using the following link-

STM8S 16x2 LCD header file

You can either download the complete repo and get the stm8s103_LCD_16x2.h file or simple the code from the above link. While setting the project, make sure you include all the required header files in the inc directory along with this header file.

STM8 LCD Header File

If you are not sure how to add the header files and compile the program, follow the video at the bottom of this page. And if you are curious about how the code inside the header file works, you can check out the PIC with an LCD tutorial. The header file used in this project is very similar to the one explained there, so we will not get into details of that.  

LCD Program for STM8S Microcontroller

For the demonstration, we will program our STM8S controller to display a simple string like “Circuit Digest” and then we will increment a “Test” value for every one second in the second line. The complete program can be found at the bottom of this page. The explanation is as follows.

We start our program by defining the pins and adding the required header files as always. In our above discussed circuit diagram, we have connected LCD_RS to PA1 so we have defined it as LCD_RS GPIOA, GPIO_PIN_1. Similarly, we have done the same for other pins as well. If they are following a different circuit, make sure you change these values accordingly.

#define LCD_RS     GPIOA, GPIO_PIN_1
#define LCD_EN      GPIOA, GPIO_PIN_2
#define LCD_DB4    GPIOD, GPIO_PIN_1
#define LCD_DB5    GPIOD, GPIO_PIN_2
#define LCD_DB6    GPIOD, GPIO_PIN_3
#define LCD_DB7    GPIOD, GPIO_PIN_4
#include "STM8S.h"
#include "stm8s103_LCD_16x2.h"

Next inside our main program, we have declared the variables required for this sample code. We have a test variable called test_var which is initialized to zero, we will increment the variable and display it on the LCD. The characters d1 to d4 represents the 4 digits of the test variable because our LCD cannot display int value directly, we have to convert them to characters.

//Variable declarations
int test_var = 0;
char d4,d3,d2,d1;

The LCD_Begin() function is used to initialize the LCD. This function will initialize all the required GPIO pins and also set the LCD in 16x2 LCD mode. Then we have the LCD_Clear() function which is used to clear all the values on the LCD, this will erase everything on LCD so that it is clean to write new values. Then we have the LCD_Set_Cursor(x,y) function where x and y are the positions at which we need to write our new character. For example, (1,1) means first row and first Colum, similarly (2,12) means second row 12 column, likewise. Note that we have 2 rows and 16 columns here as we discussed earlier.

Lcd_Begin();
Lcd_Clear();
Lcd_Set_Cursor(1,1);

Now, the LCD is set, cleared, and the cursor is at the place. Next thing is to print something on the screen. We can use the LCD_Print_String(“Sample String”) to print a string to LCD and LCD_Print_Char(a) to print a character value to the LCD. In our program here we have printed “STM8S103F3P3 LCD” and created a delay of 5 seconds using the below code.

Lcd_Print_String("STM8S103F3P3 LCD");
delay_ms(5000);

After the 5 second delay, we clear the LCD again and display “Circuit Digest” in the first row and “Test:” I the second row.

Lcd_Clear();              
Lcd_Set_Cursor(1,1);
Lcd_Print_String("Circuit Digest");            
Lcd_Set_Cursor(2,1);
Lcd_Print_String("Test: ");

Inside the while loop, we will split the value on integer variable test_var into individual characters so that it can be displayed on the LCD using simple division and modulus operators. We have also added ‘0’ to convert the ASCII value to the character.

d4 = test_var%10 + '0';
d3 = (test_var/10)%10 + '0';
d2 = (test_var/100)%10 + '0';
d1 = (test_var/1000) + '0';

Then we have set the cursor to (2,6) because we have already written “Test:” in the second row which is  6 characters. If we overwrite, the existing character will be replaced with a new character on LCD. We have also added a delay 1 second and increment the variable.

Lcd_Set_Cursor(2,6);
Lcd_Print_Char(d1);
Lcd_Print_Char(d2);
Lcd_Print_Char(d3);
Lcd_Print_Char(d4);                              
delay_ms(1000);
test_var++;

STM8 with LCD – Working

To test our program, simply upload the code to our controller and power it up with the micro-USB port. Note that the LCD requires 5V for working so it is mandatory to power the board from the USB port. We have previously powered it directly from ST-link because we did not need the 5V supply.

Interface LCD with STM8 Microcontroller

As you can see the LCD is working as expected with the test variable value being increment for every second approximately. Also, note that we have not used timers and have only used delay function to create this delay so do not expect the delay duration to be accurate, we will use timers later in another tutorial for that purpose.

The complete working of the project can be found in the video linked below. Hope you enjoyed the tutorial and learned something useful. If you have any questions, leave them in the comment section or use our forums for other technical queries.

Code
 /*Tutorial Number:4 Interfcaing 16x2 LCD with STM8s103F3
 * Website: https://circuitdigest.com/search/node/STM8S
 * Code by: Aswinth Raj
 */

 /*LCD --> STM8s
 * LCD_RS --> PA1
 * LCD_EN --> PA2
 * LCD_DB4 --> PD1
 * LCD_DB5 --> PD2
 * LCD_DB6 --> PD3
 * LCD_DB7 --> PD4
 */

 #define LCD_RS     GPIOA, GPIO_PIN_1
 #define LCD_EN     GPIOA, GPIO_PIN_2
 #define LCD_DB4    GPIOD, GPIO_PIN_1
 #define LCD_DB5    GPIOD, GPIO_PIN_2
 #define LCD_DB6    GPIOD, GPIO_PIN_3
 #define LCD_DB7    GPIOD, GPIO_PIN_4
 #include "STM8S.h"
 #include "stm8s103_LCD_16x2.h"
main()

{

//Variable declarations

int test_var = 0;
char d4,d3,d2,d1;
Lcd_Begin();
Lcd_Clear();
Lcd_Set_Cursor(1,1);
Lcd_Print_String("STM8S103F3P3 LCD");

delay_ms(5000);
Lcd_Clear();
Lcd_Set_Cursor(1,1);
Lcd_Print_String("Circuit Digest");
Lcd_Set_Cursor(2,1);
Lcd_Print_String("Test: ");

while (1)
{ 
d4 = test_var%10 + '0';
d3 = (test_var/10)%10 + '0';
d2 = (test_var/100)%10 + '0';
d1 = (test_var/1000) + '0';

Lcd_Set_Cursor(2,6);
Lcd_Print_Char(d1);
Lcd_Print_Char(d2);
Lcd_Print_Char(d3);
Lcd_Print_Char(d4);
delay_ms(1000);
test_var++;
}
}
Video

Have any question realated to this Article?

Ask Our Community Members

Comments

Hello sir,

very nice explanation for LCD interfacing

i am working on 7 Segment display interfacing with Stm8s103f3p3

i am having experience of Pic microcontroller

ST microcontrollers are new for me 

i am facing difficulty for 7 Segment display interfacing with Stm8s103f3p3

can you please help