Interface LCD 16x2 with STM32 by using STM32CubeIDE













πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€

πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€

main.c dosyasΔ± : 

#include "main.h"

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

/* USER CODE BEGIN PFP */

#include "LCD.h"

#include <stdio.h>

/* USER CODE END PFP */





int main(void)

{


  HAL_Init();


  MX_GPIO_Init();

  /* USER CODE BEGIN 2 */

  lcd_init(_LCD_4BIT, _LCD_FONT_5x8, _LCD_2LINE);

  lcd_print(1, 1, "Merhaba"); //1.satΔ±rΔ±n 1. sΓΌtunu

  lcd_print(2, 1, "DΓΌnya"); //2. satΔ±rΔ±n 1. sΓΌtunu

  /* USER CODE END 2 */

char yazi[16] = " " ;//yazi isminde, char tipinde 16 elemanΔ± olan bir dizi

int i = 0;

HAL_Delay(2500);

lcd_clear();

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

    /* USER CODE END WHILE */

i++;

lcd_print(1, 1, "SayΔ± : ");

sprintf(yazi,"%d",i); 

lcd_print(2, 1, yazi);

HAL_Delay(1000);

lcd_clear();

    /* USER CODE BEGIN 3 */

  }

  /* USER CODE END 3 */

}



void SystemClock_Config(void)

{

  RCC_OscInitTypeDef RCC_OscInitStruct = {0};

  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};


  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

  RCC_OscInitStruct.HSEState = RCC_HSE_ON;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

  {

    Error_Handler();

  }


  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;

  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;


  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

  {

    Error_Handler();

  }

}


static void MX_GPIO_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStruct = {0};


  __HAL_RCC_GPIOD_CLK_ENABLE();

  __HAL_RCC_GPIOA_CLK_ENABLE();



  HAL_GPIO_WritePin(GPIOA, LCD_EN_Pin|LCD_RS_Pin|LCD_D4_Pin|LCD_D5_Pin

                          |LCD_D6_Pin|LCD_D7_Pin, GPIO_PIN_RESET);


  GPIO_InitStruct.Pin = LCD_EN_Pin|LCD_RS_Pin|LCD_D4_Pin|LCD_D5_Pin

                          |LCD_D6_Pin|LCD_D7_Pin;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


}


void Error_Handler(void)

{

  __disable_irq();

  while (1)

  {

  }

  /* USER CODE END Error_Handler_Debug */

}


#ifdef  USE_FULL_ASSERT


void assert_failed(uint8_t *file, uint32_t line)

{

  /* USER CODE BEGIN 6 */

  /* User can add his own implementation to report the file name and line number,

     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* USER CODE END 6 */

}

#endif /* USE_FULL_ASSERT */

πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€

πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€


LCD.c dosyasΔ±

/*

       
  No.  | Pin Name| Type | Alt. Func. | Label
  ----------------------------------------------
        xx  | Pxx   | I/O  | GPIO_Output | LCD_RS
  xx  | Pxx   | I/O  | GPIO_Output | LCD_EN
  xx  | Pxx   | I/O  | GPIO_Output | LCD_D4
  xx  | Pxx   | I/O  | GPIO_Output | LCD_D5
  xx  | Pxx   | I/O  | GPIO_Output | LCD_D6
  xx  | Pxx   | I/O  | GPIO_Output | LCD_D7
     
 .      
      
  Init Sample:       
  lcd_init(_LCD_4BIT, _LCD_FONT_5x8, _LCD_2LINE);
     
To set the contrast ...
                            
        VDD-------------LCD VDD
        |
        10K
        |                            
        |---------------LCD VEE
        |
        1K
        |
        GND-------------LCD VSS
*/

#include "stm32f1xx_hal.h"
#include "main.h"
#include "LCD.h"
 
void Delay(uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}
void lcd_delay(void)
{
 Delay(1000);
}

void lcd_cmd(char out_char)
{
 LCD_RS_GPIO_Port->BRR  = LCD_RS_Pin;
 
 LCD_EN_GPIO_Port->BRR  = LCD_EN_Pin;
 LCD_D4_GPIO_Port->BRR  = LCD_D4_Pin;
 LCD_D5_GPIO_Port->BRR  = LCD_D5_Pin;
 LCD_D6_GPIO_Port->BRR  = LCD_D6_Pin;
 LCD_D7_GPIO_Port->BRR  = LCD_D7_Pin;
 
 lcd_delay();
 
 LCD_EN_GPIO_Port->ODR |= LCD_EN_Pin;
  
 if((out_char & 0x10)>>4) LCD_D4_GPIO_Port->BSRR = LCD_D4_Pin; else LCD_D4_GPIO_Port->BSRR = (uint32_t)LCD_D4_Pin << 16;
 if((out_char & 0x20)>>5) LCD_D5_GPIO_Port->BSRR = LCD_D5_Pin; else LCD_D5_GPIO_Port->BSRR = (uint32_t)LCD_D5_Pin << 16;
 if((out_char & 0x40)>>6) LCD_D6_GPIO_Port->BSRR = LCD_D6_Pin; else LCD_D6_GPIO_Port->BSRR = (uint32_t)LCD_D6_Pin << 16;
 if((out_char & 0x80)>>7) LCD_D7_GPIO_Port->BSRR = LCD_D7_Pin; else LCD_D7_GPIO_Port->BSRR = (uint32_t)LCD_D7_Pin << 16;
 
 lcd_delay();
 
 LCD_EN_GPIO_Port->BRR = LCD_EN_Pin;
 LCD_D4_GPIO_Port->BRR = LCD_D4_Pin;
 LCD_D5_GPIO_Port->BRR = LCD_D5_Pin;
 LCD_D6_GPIO_Port->BRR = LCD_D6_Pin;
 LCD_D7_GPIO_Port->BRR = LCD_D7_Pin;
 
 lcd_delay();
 
 LCD_EN_GPIO_Port->ODR |= LCD_EN_Pin;
 
 if(out_char & 0x01) LCD_D4_GPIO_Port->BSRR = LCD_D4_Pin; else LCD_D4_GPIO_Port->BSRR = (uint32_t)LCD_D4_Pin << 16;
 if((out_char & 0x02)>>1) LCD_D5_GPIO_Port->BSRR = LCD_D5_Pin; else LCD_D5_GPIO_Port->BSRR = (uint32_t)LCD_D5_Pin << 16;
 if((out_char & 0x04)>>2) LCD_D6_GPIO_Port->BSRR = LCD_D6_Pin; else LCD_D6_GPIO_Port->BSRR = (uint32_t)LCD_D6_Pin << 16;
 if((out_char & 0x08)>>3) LCD_D7_GPIO_Port->BSRR = LCD_D7_Pin; else LCD_D7_GPIO_Port->BSRR = (uint32_t)LCD_D7_Pin << 16;

 lcd_delay();
 
 LCD_EN_GPIO_Port->BRR = LCD_EN_Pin;
 LCD_D4_GPIO_Port->BRR = LCD_D4_Pin;
 LCD_D5_GPIO_Port->BRR = LCD_D5_Pin;
 LCD_D6_GPIO_Port->BRR = LCD_D6_Pin;
 LCD_D7_GPIO_Port->BRR = LCD_D7_Pin;
}

void lcd_char_cp(char out_char)
{
 LCD_RS_GPIO_Port->ODR |= LCD_RS_Pin;
 
 LCD_EN_GPIO_Port->BRR  = LCD_EN_Pin;
 LCD_D4_GPIO_Port->BRR  = LCD_D4_Pin;
 LCD_D5_GPIO_Port->BRR  = LCD_D5_Pin;
 LCD_D6_GPIO_Port->BRR  = LCD_D6_Pin;
 LCD_D7_GPIO_Port->BRR  = LCD_D7_Pin;
 
 lcd_delay();
 
 LCD_EN_GPIO_Port->ODR |= LCD_EN_Pin;
  
 if((out_char & 0x10)>>4) LCD_D4_GPIO_Port->BSRR = LCD_D4_Pin; else LCD_D4_GPIO_Port->BSRR = (uint32_t)LCD_D4_Pin << 16;
 if((out_char & 0x20)>>5) LCD_D5_GPIO_Port->BSRR = LCD_D5_Pin; else LCD_D5_GPIO_Port->BSRR = (uint32_t)LCD_D5_Pin << 16;
 if((out_char & 0x40)>>6) LCD_D6_GPIO_Port->BSRR = LCD_D6_Pin; else LCD_D6_GPIO_Port->BSRR = (uint32_t)LCD_D6_Pin << 16;
 if((out_char & 0x80)>>7) LCD_D7_GPIO_Port->BSRR = LCD_D7_Pin; else LCD_D7_GPIO_Port->BSRR = (uint32_t)LCD_D7_Pin << 16;
 
 lcd_delay();
 
 LCD_EN_GPIO_Port->BRR = LCD_EN_Pin;
 LCD_D4_GPIO_Port->BRR = LCD_D4_Pin;
 LCD_D5_GPIO_Port->BRR = LCD_D5_Pin;
 LCD_D6_GPIO_Port->BRR = LCD_D6_Pin;
 LCD_D7_GPIO_Port->BRR = LCD_D7_Pin;
 
 lcd_delay();
 
 LCD_EN_GPIO_Port->ODR |= LCD_EN_Pin;
 
 if(out_char & 0x01) LCD_D4_GPIO_Port->BSRR = LCD_D4_Pin; else LCD_D4_GPIO_Port->BSRR = (uint32_t)LCD_D4_Pin << 16;
 if((out_char & 0x02)>>1) LCD_D5_GPIO_Port->BSRR = LCD_D5_Pin; else LCD_D5_GPIO_Port->BSRR = (uint32_t)LCD_D5_Pin << 16;
 if((out_char & 0x04)>>2) LCD_D6_GPIO_Port->BSRR = LCD_D6_Pin; else LCD_D6_GPIO_Port->BSRR = (uint32_t)LCD_D6_Pin << 16;
 if((out_char & 0x08)>>3) LCD_D7_GPIO_Port->BSRR = LCD_D7_Pin; else LCD_D7_GPIO_Port->BSRR = (uint32_t)LCD_D7_Pin << 16;

 lcd_delay();
 
 LCD_EN_GPIO_Port->BRR = LCD_EN_Pin;
 LCD_D4_GPIO_Port->BRR = LCD_D4_Pin;
 LCD_D5_GPIO_Port->BRR = LCD_D5_Pin;
 LCD_D6_GPIO_Port->BRR = LCD_D6_Pin;
 LCD_D7_GPIO_Port->BRR = LCD_D7_Pin;
}

void lcd_out_cp(char *out_char)
{
 while(*out_char)
 {
  lcd_delay();
  lcd_char_cp(*out_char++);
 }
 lcd_delay();
}


void lcd_init(char bits, char font, char lines)
{  
    HAL_Delay(250);
 lcd_cmd(_RETURN_HOME);
    HAL_Delay(50);
    lcd_cmd(0x20 | bits | font | lines);
    HAL_Delay(50);
    lcd_cmd(_LCD_INIT);
    HAL_Delay(50);
    lcd_cmd(0x0E);
    HAL_Delay(50);
    lcd_cmd(0x0C);
    HAL_Delay(50);
    lcd_cmd(0x01);
    HAL_Delay(100);
}

void lcd_gotoxy(unsigned char row, unsigned char column)
 if(row == 1)
 {
  lcd_cmd(0x80 + (column - 1));
 }
 else if(row == 2)
 {
  lcd_cmd(0xC0 + (column - 1));
 } 
}

void lcd_char(unsigned char row, unsigned char column, char out_char)
{
 lcd_gotoxy(row, column);
 lcd_char_cp(out_char);
}

void lcd_print(unsigned char row, unsigned char column, char *out_char)
{
 lcd_gotoxy(row, column);
 lcd_out_cp(out_char);
}
void lcd_clear(void) {
    
 lcd_cmd(_CLEAR);
    HAL_Delay(2);
    
}
void lcd_line1(void) {
 lcd_cmd(0x80);
}

void lcd_line2(void) {
 lcd_cmd(0xC0);
}


πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€

πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€


LCD.h dosyasΔ± : 

#define _TURN_ON     0x0C // Turn Lcd display on

#define _TURN_OFF     0x08 // Turn Lcd display off

#define _FIRST_ROW     0x80 // Move cursor to the 1st row

#define _SECOND_ROW     0xC0 // Move cursor to the 2nd row

#define _CLEAR      0x01 // Clear display

#define _RETURN_HOME    0x02 // Return cursor to home position, returns a shifted display to its original position. Display data RAM is unaffected.

#define _CURSOR_OFF     0x0C // Turn off cursor

#define _UNDERLINE_ON    0x0E // Underline cursor on

#define _BLINK_CURSOR_ON      0x0F // Blink cursor on

#define _MOVE_CURSOR_LEFT      0x10 // Move cursor left without changing display data RAM

#define _MOVE_CURSOR_RIGHT         0x14 // Move cursor right without changing display data RAM

#define _SHIFT_LEFT     0x18 // Shift display left without changing display data RAM

#define _SHIFT_RIGHT    0x1C // Shift display right without changing display data RAM

#define _LCD_4BIT     0x00

#define _LCD_8BIT     0x10

#define _LCD_FONT_5x8    0x00

#define _LCD_FONT_5x10       0x04

#define _LCD_1LINE     0x00

#define _LCD_2LINE     0x08


#define _LCD_INIT     0x06


//#define _LCD_INIT     0x04

//#define _LCD_INIT     0x05

//#define _LCD_INIT     0x07


void lcd_delay(void);

void lcd_cmd(char out_char); 

void lcd_char_cp(char out_char);

void lcd_char(unsigned char row, unsigned char column, char out_char); 

void lcd_out_cp(char *out_char);

void lcd_print(unsigned char row, unsigned char column, char *out_char);

void lcd_gotoxy(unsigned char row, unsigned char column);

void lcd_init(char bits, char font, char lines);

void lcd_clear(void);

void lcd_line1(void);

void lcd_line2(void);

πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€

πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€πŸ˜€


June 17, 2022 Update: In the top image, I have made connections to both the LCD pins and I2C module from the STM32F103C8. This is how the project works incorrectly. To fix it, it is necessary to connect only 1 of the two, either only to the LCD or only to I2C. I connected it to the LCD and adjusted the contrast with 1 resistor, it worked. But the texts on the LCD didn't look good because of the resistance value, those who want to do better can adjust the LCD contrast with, for example, a 10k potentiometer or trimpot.

Comments

Popular posts from this blog

Parking sensor by using STM32CubeIDE and HC-SR04

LED blinking project with STM32