Toby's Study Blog
article thumbnail

๐Ÿงฟ ์‹ค์Šต ๋ชฉํ‘œ

1. F429zi์™€ HD44780 ์—ฐ๊ฒฐ
2. i2c_HD44780.h, i2c_HD44780.c, app.c ํŒŒ์ผ ์ƒ์„ฑ
3. LCD ๋ฌธ์ž์—ด ์ถœ๋ ฅ ํ™•์ธ

 

๐Ÿงฟ I2C ์„ค์ •

๐Ÿงฟ ์‹ค์Šต ๊ฒฐ๊ณผ

https://github.com/Tobbyvv/stm32-project/tree/main/lcd_I2c

F429zi์™€ HD44780 ์—ฐ๊ฒฐ

I2C ๋ชจ๋“ˆ์˜ VCC, ๋ฐฑ๋ผ์ดํŠธ, GND๋ฅผ CN8 ์ปค๋„ฅํ„ฐ์˜ 5V์™€ GND์— ์—ฐ๊ฒฐ
I2C ๋ชจ๋“ˆ์˜ SCL๊ณผ SDA๋ฅผ CN7 ์ปค๋„ฅํ„ฐ์˜ PB8, PB9ํ•€๊ณผ ์—ฐ๊ฒฐ

F429zi CN7, CN8 ์ปค๋„ฅํ„ฐ
I2C ๋ชจ๋“ˆ

 

i2c_HD44780.h, i2c_HD44780.c, app.c ํŒŒ์ผ ์ƒ์„ฑ

 2.1 i2c_HD44780.h

#ifndef __I2C_HD44780__H__
#define __I2C_HD44780__H__

#ifdef __cplusplus
extern "C" {
#endif

void lcd_init (void);   // LCD๋ฅผ ์ดˆ๊ธฐํ™”
//void lcd_send_cmd (char cmd);  // LCD์— ๋ช…๋ น์„ ์ „์†ก
//void lcd_send_data (char data);  // LCD์— ๋ฐ์ดํ„ฐ ์ „์†ก
void lcd_disp_on(void);  // LCD ๋””์Šคํ”Œ๋ ˆ์ด ํ™œ์„ฑํ™”
void lcd_disp_off(void);  // LCD ๋””์Šคํ”Œ๋ ˆ์ด ๋น„ํ™œ์„ฑํ™”
void lcd_home(void);  // ์ปค์„œ๋ฅผ ํ™ˆ ์œ„์น˜๋กœ ์ด๋™
void lcd_clear_display(void);  // LCD ๋””์Šคํ”Œ๋ ˆ์ด ํด๋ฆฌ์–ด
void lcd_locate(uint8_t row, uint8_t column);  // ์ปค์„œ๋ฅผ ์ง€์ •ํ•œ ํ–‰๊ณผ ์—ด๋กœ ์ด๋™
void lcd_printchar(unsigned char ascode);  // ๋ฌธ์ž๋ฅผ LCD์— ์ถœ๋ ฅ
void lcd_print_string (char *str);  // ๋ฌธ์ž์—ด์„ LCD์— ์ถœ๋ ฅ
void lcd_printf(const char *fmt, ...);  // ์„œ์‹์„ ์ง€์ •ํ•˜์—ฌ LCD์— ์ถœ๋ ฅ

#ifdef __cplusplus
}
#endif

#endif

 2.2  i2c_HD44780.c

#include "main.h"
#include "stm32f4xx_hal.h"
#include "i2c_HD44780.h"

#include <stdarg.h>
#include <stdio.h>
extern I2C_HandleTypeDef hi2c1;

#define SLAVE_ADDRESS_LCD (0x27<<1) //I2C ์ฃผ์†Œ๋ฅผ ์ง€์ • F429zi์˜ ๊ฒฝ์šฐ 0x27 
/**
  * @brief  HD44780 LCD ๋ชจ๋“ˆ์— ๋ช…๋ น์„ I2C๋ฅผ ํ†ตํ•ด ์ „์†ก
  * @param  cmd: ์ „์†กํ•  ๋ช…๋ น์–ด(์ตœ๋Œ€ 8๋น„ํŠธ๊นŒ์ง€ ์ „์†ก ๊ฐ€๋Šฅ)
  * @retval None
  */
static void lcd_send_cmd(char cmd)
{
  char data_u, data_l;	// ๋ช…๋ น์–ด๋ฅผ ์ƒ์œ„ 4๋น„ํŠธ์™€ ํ•˜์œ„ 4๋น„ํŠธ๋กœ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜ ์„ ์–ธ
  uint8_t data_t[4];     // I2C๋ฅผ ํ†ตํ•ด ์ „์†กํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฐ์—ด ์„ ์–ธ
  data_u = (cmd & 0xf0);        // ๋ช…๋ น์˜ ์ƒ์œ„ 4๋น„ํŠธ ์ถ”์ถœ
  data_l = ((cmd << 4) & 0xf0);  // ๋ช…๋ น์˜ ํ•˜์œ„ 4๋น„ํŠธ๋ฅผ ์ƒ์œ„ 4๋น„ํŠธ๋กœ ์ด๋™ํ•˜์—ฌ ์ถ”์ถœ
  data_t[0] = data_u | 0x0C;  //en=1, rs=0 -> en, rs ๋น„ํŠธ ์ถ”๊ฐ€, ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์™€ ๋ช…๋ น ์ฒ˜๋ฆฌ ์ƒํƒœ 
  data_t[1] = data_u | 0x08;  //en=0, rs=0 -> enm rs ๋น„ํŠธ ์ถ”๊ฐ€, ๋Œ€๊ธฐ ์ƒํƒœ 
  data_t[2] = data_l | 0x0C;  //en=1, rs=0
  data_t[3] = data_l | 0x08;  //en=0, rs=0
  /*
  ๋ช…๋ น์–ด๋ฅผ ์ƒ์œ„ ํ•˜์œ„๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ 4๋น„ํŠธ๋กœ ๋‚˜๋ˆˆ ์ด์œ ๋Š” ๋ฐ์ดํ„ฐ์— en, rs ๊ฐ’์„ ์ถ”๊ฐ€ํ•ด 8๋น„ํŠธ๋กœ ๋งŒ๋“ค๊ณ 
  4๋น„ํŠธ ๋‹จ์œ„๋กœ LCD ๋ชจ๋“ˆ์— ์ „๋‹ฌํ•ด์•ผ ํ•˜๋‹ˆ 4๋น„ํŠธ๋กœ 2๋ฒˆ ๋‚˜๋ˆ ์„œ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์ด ํšจ์œจ์ ์ด๊ธฐ ๋•Œ๋ฌธ  
  */
  while (HAL_I2C_Master_Transmit(&hi2c1, SLAVE_ADDRESS_LCD, (uint8_t *)data_t, 4, 100) != HAL_OK)
  {
    // I2C๋กœ ๋ฐ์ดํ„ฐ๋ฅผ LCD ๋ชจ๋“ˆ์— ์ „์†กํ•˜๊ณ , ์„ฑ๊ณตํ•  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
    // Timeout ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ Error_Handler() ํ˜ธ์ถœ
    if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }}}
/**
  * @brief  HD44780 LCD ๋ชจ๋“ˆ์— ๋ฐ์ดํ„ฐ๋ฅผ I2C๋ฅผ ํ†ตํ•ด ์ „์†ก
  * @param  data: ์ „์†กํ•  ๋ฐ์ดํ„ฐ
  * @retval None
  */
static void lcd_send_data(char data)
{
  char data_u, data_l;
  uint8_t data_t[4];
  data_u = (data & 0xf0);
  data_l = ((data << 4) & 0xf0);
  data_t[0] = data_u | 0x0D;  //en=1, rs=0
  data_t[1] = data_u | 0x09;  //en=0, rs=0
  data_t[2] = data_l | 0x0D;  //en=1, rs=0
  data_t[3] = data_l | 0x09;  //en=0, rs=0

  while (HAL_I2C_Master_Transmit(&hi2c1, SLAVE_ADDRESS_LCD, (uint8_t *)data_t, 4, 100) != HAL_OK)
  {
    // Timeout ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ Error_Handler() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ
    if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }}}
/**
  * @brief  4-bit ๋ชจ๋“œ์—์„œ HD44780 LCD ๋ชจ๋“ˆ ์ดˆ๊ธฐํ™”
  * @param  None
  * @retval None
  */
void lcd_init(void)
{
  lcd_send_cmd(0x33);   // ํ™•์žฅ ๋ช…๋ น ๋ชจ๋“œ ์„ค์ •
  lcd_send_cmd(0x32);   // 4๋น„ํŠธ ๋ชจ๋“œ ์„ค์ • 
  lcd_send_cmd(0x28);   // 4-bit ๋ชจ๋“œ, 2์ค„ ๋””์Šคํ”Œ๋ ˆ์ด, 5x8 ํฐํŠธ ์„ค์ •
  lcd_send_cmd(0x0C);   // ๋””์Šคํ”Œ๋ ˆ์ด ์ผœ๊ธฐ, ์ปค์„œ ๋น„ํ™œ์„ฑํ™”, ์ปค์„œ ๊นœ๋นก์ž„ ๋น„ํ™œ์„ฑํ™”
  lcd_send_cmd(0x06);   // ์ปค์„œ ์ด๋™ ๋ฐฉํ–ฅ ์„ค์ • (์ปค์„œ๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™, ํ™”๋ฉด ์ด๋™)
  lcd_send_cmd(0x02);   // ๋””์Šคํ”Œ๋ ˆ์ด clear
  // LCD ๋ชจ๋“ˆ์„ ๊ตฌ๋™ํ•˜๊ธฐ ์ „์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ์ง€์—ฐ ์‹œ๊ฐ„ ์„ค์ •
  HAL_Delay(200);
}
/**
  * @brief  ๋””์Šคํ”Œ๋ ˆ์ด ํ™œ์„ฑํ™”
  * @param  None
  * @retval None
  */
void lcd_disp_on(void)
{
  lcd_send_cmd(0x0C);
}
/**
  * @brief  ๋””์Šคํ”Œ๋ ˆ์ด ๋น„ํ™œ์„ฑํ™”
  * @param  None
  * @retval None
  */
void lcd_disp_off(void)
{
  lcd_send_cmd(0x08);
}
/**
  * @brief  ์ปค์„œ๋ฅผ ํ™ˆ ์œ„์น˜๋กœ ์ด๋™
  * @param  None
  * @retval None
  */
void lcd_home(void)
{
  lcd_send_cmd(0x02);
  HAL_Delay(2);
}
/**
  * @brief  LCD ๋ชจ๋“ˆ ๋””์Šคํ”Œ๋ ˆ์ด clear
  * @param  None
  * @retval None
  */
void lcd_clear_display(void)
{
  lcd_send_cmd(0x01);
  HAL_Delay(2);
}

/**
  * @brief  ํŠน์ • ์œ„์น˜๋กœ ์ปค์„œ ์ด๋™
  * @param  row: ์ด๋™ํ•  ํ–‰ (1์—์„œ 4๊นŒ์ง€)
  * @param  column: ์ด๋™ํ•  ์—ด (1์—์„œ 20๊นŒ์ง€, 4x20 ๋ฌธ์ž ๋””์Šคํ”Œ๋ ˆ์ด ๊ธฐ์ค€)
  * @retval None
  */
void lcd_locate(uint8_t row, uint8_t column)
{
  column--;
  switch (row)
  {
    case 1:
      // 1ํ–‰ ์ฃผ์†Œ๋กœ ์ปค์„œ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€
      lcd_send_cmd(0x80);
      break;
    case 2:
      // 2ํ–‰ ์ฃผ์†Œ๋กœ ์ปค์„œ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€
      lcd_send_cmd(0xc0);
      break;
    case 3:
      // 3ํ–‰ ์ฃผ์†Œ๋กœ ์ปค์„œ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€
      lcd_send_cmd(column |= 0x94);
      break;
    case 4:
      // 4ํ–‰ ์ฃผ์†Œ๋กœ ์ปค์„œ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€
      lcd_send_cmd(column |= 0xd4);
      break;
    default:
      break;
  }}
/**
  * @brief  LCD ๋ชจ๋“ˆ์— ๋ฌธ์ž ์ถœ๋ ฅ
  * @param  ์ถœ๋ ฅํ•  ๋ฌธ์ž์˜ ASCII ๊ฐ’
  * @retval None
  */
void lcd_printchar(unsigned char ascode)
{
	lcd_send_data(ascode);
}
/**
  * @brief  ๋ฌธ์ž์—ด์„ LCD ๋ชจ๋“ˆ์— ํ‘œ์‹œ
  * @param  ํ‘œ์‹œํ•  ํ…์ŠคํŠธ
  * @retval None
  */
void lcd_print_string(char *str)
{
	while (*str)
    lcd_send_data(*str++); // ๋ฌธ์ž์—ด์˜ ๊ฐ ๋ฌธ์ž๋ฅผ LCD ๋ชจ๋“ˆ์— ์ „์†กํ•˜์—ฌ ํ‘œ์‹œ
}

/**
  * @brief  ํ˜•์‹ ์ง€์ •๋œ ๋ฌธ์ž์—ด์„ LCD์— ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜
  * @param  ํ‘œ์ค€ ์ •์˜ ํ˜•์‹ ์ง€์ • ๋ฌธ์ž์—ด
  * @param  ๊ฐ€๋ณ€ ์ธ์ˆ˜ ๋ชฉ๋ก
  * @retval None
  */
void lcd_printf(const char *fmt, ...)
{
  uint32_t i;
  uint32_t text_size, letter;
  static char text_buffer[32];
  va_list args;
  va_start(args, fmt);
  text_size = vsprintf(text_buffer, fmt, args); // ํ˜•์‹ ์ง€์ • ๋ฌธ์ž์—ด์„ ํ…์ŠคํŠธ ๋ฒ„ํผ์— ํฌ๋งท

  // ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ
  for (i = 0; i < text_size; i++)
  {
    letter = text_buffer[i];
    if (letter == 10) // ๊ฐœํ–‰ ๋ฌธ์ž์ธ ๊ฒฝ์šฐ ์ฒ˜๋ฆฌ ์ค‘๋‹จ
      break;
    else
    {
      if ((letter > 0x1F) && (letter < 0x80)) // ์ธ์‡„ ๊ฐ€๋Šฅํ•œ ASCII ๋ฌธ์ž ๋ฒ”์œ„์ธ ๊ฒฝ์šฐ ์ถœ๋ ฅ
        lcd_printchar(letter);
    }}}

2.3 app.c

#include "main.h"
#include "app.h"
#include "stm32f4xx_hal.h"
#include "cmsis_os2.h"
#include "i2c_hd44780.h"
#include <stdio.h>

extern UART_HandleTypeDef huart3;

void app_main(void)
{
    lcd_init(); // LCD ์ดˆ๊ธฐํ™”
    lcd_disp_on(); //ํ™”๋ฉด ํ‘œ์‹œ ํ™œ์„ฑํ™”
    lcd_clear_display(); //ํ™”๋ฉด ์ดˆ๊ธฐํ™”
    lcd_home(); //์ปค์„œ ์ด๋™
    lcd_print_string("Hello22"); //๋ฌธ์ž์—ด LCD์˜ˆ ์ถœ๋ ฅ
}

int fputc(int ch, FILE *f)
{
    // UART๋กœ ๋ฌธ์ž ์ถœ๋ ฅ
    HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 100);
    return ch;
}

void app(void)
{
    app_main();
    while (1);
}

LCD ๋ฌธ์ž์—ด ์ถœ๋ ฅ ํ™•์ธ

๋ฌธ์ž์—ด ์ถœ๋ ฅ๋จ ํ™•์ธ

 

'embedded' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[stm32] RTOS ์‹ค์Šต  (0) 2023.09.18
[stm32] RTOS ์ด๋ก  ์ •๋ฆฌ  (0) 2023.09.11
[stm32] I2C ํ†ต์‹  ์ด๋ก  ์ •๋ฆฌ  (0) 2023.09.11
[stm32] ADC & DMA ์‹ค์Šต  (0) 2023.09.06
[stm32] ADC & DMA ์ด๋ก  ์ •๋ฆฌ  (0) 2023.09.06
profile

Toby's Study Blog

@Toby12

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!

๊ฒ€์ƒ‰ ํƒœ๊ทธ