Interfacing 16X2 LCD With STM32 & Cube IDE
by vanshika4566_be23 in Circuits > Microcontrollers
592 Views, 1 Favorites, 0 Comments
Interfacing 16X2 LCD With STM32 & Cube IDE
Hello!
In this tutorial, you’ll learn how to interface STM32 with LCD 16×2 display and integrate the STM32 LCD library into your project.
Supplies
- STM32 Black pill board
- STM32 Cube IDE Software
- 16*2 LCD Display
- Jumper wires (M-M, F-M)
- USB –Type C cable
- Potentiometer- 10K
- Breadboard
MAKE CONNECTIONS
- The first step is to make connections between the components.
- Make pin connection between LCD display and STM32 black pill board as shown in the images.
- Also use breadboard to connect potentiometer and resistor to LCD display and STM32 board.
- The project will work without making use of potentiometer and resistor but it is better to use potentiometer for display quality and resistor for durability.
STM32 Cube IDE Pin Settings
- Open Cube IDE and go to Pinout and Configuration
- Now in Pinout view select the pins that you used in the hardware connections
- Here from the above step set PA1, PA3, PB0, PB1, PB10 and PB11 to GPIO_Output
- Now, to setup timer to create delay in microseconds, click on clock configuration >>HSE>>PLL CLK
- Now, select resolve clock issues from the top in the center
- Save the settings
Program : Code for Libraries(Inside Core/Inc Folder)
- Add code in Inc folder that is inside Core
- The code is given below:
/*
* lcd.h
*
* Created on: 10/06/2018
* Author: Olivier Van den Eede
*/
#ifndef LCD_H_
#define LCD_H_
#include "stm32f1xx_hal.h"
#include "string.h"
#include "stdio.h"
#include "main.h"
// #define LCD20xN // For 20xN LCDs
#define LCD16xN // For 16xN LCDs
// For row start addresses
extern const uint8_t ROW_16[];
extern const uint8_t ROW_20[];
/************************************* Command register **************************************/
#define CLEAR_DISPLAY 0x01
#define RETURN_HOME 0x02
#define ENTRY_MODE_SET 0x04
#define OPT_S 0x01 // Shift entire display to right
#define OPT_INC 0x02 // Cursor increment
#define DISPLAY_ON_OFF_CONTROL 0x08
#define OPT_D 0x04 // Turn on display
#define OPT_C 0x02 // Turn on cursor
#define OPT_B 0x01 // Turn on cursor blink
#define CURSOR_DISPLAY_SHIFT 0x10 // Move and shift cursor
#define OPT_SC 0x08
#define OPT_RL 0x04
#define FUNCTION_SET 0x20
#define OPT_DL 0x10 // Set interface data length
#define OPT_N 0x08 // Set number of display lines
#define OPT_F 0x04 // Set alternate font
#define SETCGRAM_ADDR 0x040
#define SET_DDRAM_ADDR 0x80 // Set DDRAM address
/************************************** Helper macros **************************************/
#define DELAY(X) HAL_Delay(X)
/************************************** LCD defines **************************************/
#define LCD_NIB 4
#define LCD_BYTE 8
#define LCD_DATA_REG 1
#define LCD_COMMAND_REG 0
/************************************** LCD typedefs **************************************/
#define Lcd_PortType GPIO_TypeDef*
#define Lcd_PinType uint16_t
typedef enum {
LCD_4_BIT_MODE,
LCD_8_BIT_MODE
} Lcd_ModeTypeDef;
typedef struct {
Lcd_PortType * data_port;
Lcd_PinType * data_pin;
Lcd_PortType rs_port;
Lcd_PinType rs_pin;
Lcd_PortType en_port;
Lcd_PinType en_pin;
Lcd_ModeTypeDef mode;}
Lcd_HandleTypeDef;
/************************************** Public functions **************************************/
void Lcd_init(Lcd_HandleTypeDef * lcd);
void Lcd_int(Lcd_HandleTypeDef * lcd, int number);
void Lcd_string(Lcd_HandleTypeDef * lcd, char * string);
void Lcd_cursor(Lcd_HandleTypeDef * lcd, uint8_t row, uint8_t col);
Lcd_HandleTypeDef Lcd_create(
Lcd_PortType port[], Lcd_PinType pin[],
Lcd_PortType rs_port, Lcd_PinType rs_pin,
Lcd_PortType en_port, Lcd_PinType en_pin, Lcd_ModeTypeDef mode);
void Lcd_define_char(Lcd_HandleTypeDef * lcd, uint8_t code, uint8_t bitmap[]);
void Lcd_clear(Lcd_HandleTypeDef * lcd);
#endif /* LCD_H_ */
Program : Code for Libraries(Inside Core/Src Folder)
/*
* lcd.c
*
* Created on: 10/06/2018
* Author: Olivier Van den Eede
*/
#include "lcd.h"
const uint8_t ROW_16[] = {0x00, 0x40, 0x10, 0x50};
const uint8_t ROW_20[] = {0x00, 0x40, 0x14, 0x54};
/************************************** Static declarations **************************************/
static void lcd_write_data(Lcd_HandleTypeDef * lcd, uint8_t data);
static void lcd_write_command(Lcd_HandleTypeDef * lcd, uint8_t command);
static void lcd_write(Lcd_HandleTypeDef * lcd, uint8_t data, uint8_t len);
/************************************** Function definitions **************************************/
/**
* Create new Lcd_HandleTypeDef and initialize the Lcd
*/
Lcd_HandleTypeDef Lcd_create(
Lcd_PortType port[], Lcd_PinType pin[],
Lcd_PortType rs_port, Lcd_PinType rs_pin,
Lcd_PortType en_port, Lcd_PinType en_pin, Lcd_ModeTypeDef mode)
{
Lcd_HandleTypeDef lcd;
lcd.mode = mode;
lcd.en_pin = en_pin;
lcd.en_port = en_port;
lcd.rs_pin = rs_pin;
lcd.rs_port = rs_port;
lcd.data_pin = pin;
lcd.data_port = port;
Lcd_init(&lcd);
return lcd;
}
/**
* Initialize 16x2-lcd without cursor
*/
void Lcd_init(Lcd_HandleTypeDef * lcd)
{if(lcd->mode == LCD_4_BIT_MODE)
{lcd_write_command(lcd, 0x33);
lcd_write_command(lcd, 0x32);
lcd_write_command(lcd, FUNCTION_SET | OPT_N); // 4-bit mode
}
else
lcd_write_command(lcd, FUNCTION_SET | OPT_DL | OPT_N);
lcd_write_command(lcd, CLEAR_DISPLAY); // Clear screen
lcd_write_command(lcd, DISPLAY_ON_OFF_CONTROL | OPT_D); // Lcd-on, cursor-off, no-blink
lcd_write_command(lcd, ENTRY_MODE_SET | OPT_INC); // Increment cursor
}
/**
* Write a number on the current position
*/
void Lcd_int(Lcd_HandleTypeDef * lcd, int number)
{
char buffer[11];
sprintf(buffer, "%d", number);
Lcd_string(lcd, buffer);
}
/**
* Write a string on the current position
*/
void Lcd_string(Lcd_HandleTypeDef * lcd, char * string)
{
for(uint8_t i = 0; i < strlen(string); i++)
{lcd_write_data(lcd, string[i]);
}
}
/**
* Set the cursor position
*/
void Lcd_cursor(Lcd_HandleTypeDef * lcd, uint8_t row, uint8_t col)
{
#ifdef LCD20xN
lcd_write_command(lcd, SET_DDRAM_ADDR + ROW_20[row] + col);
#endif
#ifdef LCD16xN
lcd_write_command(lcd, SET_DDRAM_ADDR + ROW_16[row] + col);
#endif
}
/**
* Clear the screen
*/
void Lcd_clear(Lcd_HandleTypeDef * lcd) {
lcd_write_command(lcd, CLEAR_DISPLAY);
}
void Lcd_define_char(Lcd_HandleTypeDef * lcd, uint8_t code, uint8_t bitmap[]){
lcd_write_command(lcd, SETCGRAM_ADDR + (code << 3));
for(uint8_t i=0;i<8;++i){
lcd_write_data(lcd, bitmap[i]);
}
}
/************************************** Static function definition **************************************/
/**
* Write a byte to the command register
*/
void lcd_write_command(Lcd_HandleTypeDef * lcd, uint8_t command)
{
HAL_GPIO_WritePin(lcd->rs_port, lcd->rs_pin, LCD_COMMAND_REG); // Write to command register
if(lcd->mode == LCD_4_BIT_MODE)
{lcd_write(lcd, (command >> 4), LCD_NIB);
lcd_write(lcd, command & 0x0F, LCD_NIB);}
else
{lcd_write(lcd, command, LCD_BYTE);}
}
/**
* Write a byte to the data register
*/
void lcd_write_data(Lcd_HandleTypeDef * lcd, uint8_t data)
{
HAL_GPIO_WritePin(lcd->rs_port, lcd->rs_pin, LCD_DATA_REG); // Write to data register
if(lcd->mode == LCD_4_BIT_MODE)
{lcd_write(lcd, data >> 4, LCD_NIB);
lcd_write(lcd, data & 0x0F, LCD_NIB);}
else
{lcd_write(lcd, data, LCD_BYTE);}
}
/**
* Set len bits on the bus and toggle the enable line
*/
void lcd_write(Lcd_HandleTypeDef * lcd, uint8_t data, uint8_t len
{
for(uint8_t i = 0; i < len; i++)
{HAL_GPIO_WritePin(lcd->data_port[i], lcd->data_pin[i], (data >> i) & 0x01);}
HAL_GPIO_WritePin(lcd->en_port, lcd->en_pin, 1);
DELAY(1);
HAL_GPIO_WritePin(lcd->en_port, lcd->en_pin, 0); // Data receive on falling edge
}
- Save and close the files
Program for Main.c
- Add #include "lcd.h" under /* USER CODE BEGIN Includes */
- Additional code on top of STM32CubeIDE generated code is given below:
// Lcd_PortType ports[] = { D4_GPIO_Port, D5_GPIO_Port, D6_GPIO_Port, D7_GPIO_Port };
Lcd_PortType ports[] = { GPIOB, GPIOB, GPIOB, GPIOB };
// Lcd_PinType pins[] = {D4_Pin, D5_Pin, D6_Pin, D7_Pin};
Lcd_PinType pins[] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_10, GPIO_PIN_11};
Lcd_HandleTypeDef lcd;
// Lcd_create(ports, pins, RS_GPIO_Port, RS_Pin, EN_GPIO_Port, EN_Pin, LCD_4_BIT_MODE);
lcd = Lcd_create(ports, pins, GPIOA, GPIO_PIN_1, GPIOA, GPIO_PIN_3, LCD_4_BIT_MODE);
Lcd_cursor(&lcd, 0,1);
Lcd_string(&lcd, "Vanshika Rana");
for ( int x = 1; x <= 200 ; x++ )
{
Lcd_cursor(&lcd, 1,7);
Lcd_int(&lcd, x);
HAL_Delay (1000);}
Cube Programmer
- Now, copy path of project file generated
- Open STM32 cube programmer>>main.c (beside Device memory)>> Open file
- Enter file path and connect the STM32 black pill via USB cable
- Click on Download and fill the blank space with file path. Check the boxes and click on Start Automatic Mode
- The LCD displays your name