Підключення LCD1602 дисплея по I2C до STM32 HAL

У даній статті розглядається приклад підключення РК-дисплеїв LCD1602, LCD2004 до мікроконтролера STM32 з використанням бібліотеки HAL по шині I2C. Буде використовуватись мікроконтролер STM32G030F6P6, перевагами даного мікроконтролера розмір мінімальна кількість додаткових компонентів доступність та ціна, що для DIY пристроїв є вагомим фактором. Даний приклад підходить до всієї лінійки STM32.

Вольтметр на STM32

Для початку створимо проект у STMCubeMX, у вкладці System Core -> SYS увімкнемо Serial Wire. Також у Connectivity увімкнемо I2C, налаштування I2C залишимо без змін. Та згенеруємо проект.

Імпорт проекту STMCubeMX в PlatfornIO

Підключення LCD1602, LCD2004

Підключення відбувається згідно з обраною шиною I2C, в нашому випадку PB7_PB8 SCL, та PC14 SDA

STMLCD
PB7_PB8 SCLSCL
PC14 SDASDA
5V5V
GNDGND

Код програми

Використаємо міні бібліотеку HAL_STM32_I2C_LCD. Для використання у PlatformIO та VSCode потрібно додати наступний код у platformio.ini файл.

lib_deps = qazf/HAL_STM32_I2C_LCD@^1.0.0

Повний вміст platformio.ini файлу

[platformio]
src_dir = ./Core/
include_dir = Core/Inc/

[env:stm]
platform = ststm32
board = genericSTM32G030F6
framework = stm32cube
lib_deps = qazf/HAL_STM32_I2C_LCD@^1.0.0

Для інших потрібно скопіювати ‘lcd.c’, та ‘lcd.h’ файли у проект.

Наступним кроком підключаємо бібліотеку у наш ‘main.c’ файл.

/* USER CODE BEGIN Includes */
#include "lcd.h"
/* USER CODE END Includes */

Встановлюємо адресу дисплея, зазвичай це ‘0x27’.

/* USER CODE BEGIN PD */
#define LCD_ADDR 0x27
/* USER CODE END PD */

Пошук адрес пристроїв на I2C шині

У функції main після ініціалізації I2C, та ініціалізуємо бібліотеку.

 /* USER CODE BEGIN 2 */
  init(&hi2c1, LCD_ADDR);
  /* USER CODE END 2 */

Де ‘hi2c1’ I2C інтерфейс, який був обраний при створенні проекту.

Далі приклад ‘Hello, World!’ текст у першому рядку, та лічильник у другому який збільшується кожну секунду.


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  char *text = "Hello, World!";
  write_str(text);

  int counter = 0;
  uint32_t timer = 0;

  while (1)
  {
    if (HAL_GetTick() - timer >= 1000)
    {
      timer = HAL_GetTick();
      counter++;
      set_pos(0, 1);

      char num[10];
      sprintf(num, "%d", counter);

      write_str(num);
    }


    // your code

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

За умовчанням у бібліотеці використовується дисплей LCD1602, тобто 16 колонок 2 рядки. Для дисплеїв LCD2004, 20 колонок 4 рядки, потрібно змінити функцію ініціалізації на наступну.

init_custom(&hi2c1, LCD_ADDR, 20, 4);

Також змінимо код, у першому рядку виведемо текст ‘Increment’, у другому рядку значення лічильника яке збільшується кожну секунду. У третьому рядку текст ‘Decrement’, та у четвертому рядку лічильник який зменшується кожну секунду.

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  char *increment = "Increment";
  write_str(increment);

  char *decrement = "Decrement";
  set_pos(0, 2);
  write_str(decrement);

  int counter_i = 0;
  int counter_d = 0;
  uint32_t timer = 0;

  while (1)
  {

    if (HAL_GetTick() - timer >= 1000)
    {
      timer = HAL_GetTick();
      counter_i++;
      counter_d--;

      set_pos(0, 1);
      char num_i[10];
      sprintf(num_i, "%d", counter_i);
      write_str(num_i);

      set_pos(0, 3);
      char num_d[10];
      sprintf(num_d, "%d", counter_d);
      write_str(num_d);
    }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

В результаті отримаємо.

Опис функції бібліотеки HAL_STM32_I2C_LCD

  • init(I2C_HandleTypeDef *i2c, uint8_t lcd_addr); – ініціалізація, вхідні аргументи: інтерфейс I2C та адреса дисплея на шині. За умовчанням 16 колонок 2 рядки.
  • init_custom(I2C_HandleTypeDef *_i2c, uint8_t lcd_addr, uint8_t column, uint8_t rows); – ініціалізація з додатковими аргументами, кількість колонок та рядків дисплея.
  • clear(); – очистити весь дисплей.
  • home(); – перемістити курсор на позицію (0 . 0).
  • set_pos(uint8_t column, uint8_t row); – перемістити курсор у задану позицію.
  • backlight(uint8_t state); – увімкнути або вимкнути підсвітку. Якщо значення ‘state’ ‘0’ вимикає, інакше вмикає.
  • cursor(uint8_t cursor); – вмикає або вимикає курсор. Якщо значення ‘cursor’ ‘0’ вимикає, інакше вмикає.
  • blink(uint8_t blink); – вмикає або вимикає блимання комірки в якій знаходиться курсор. Якщо значення ‘blink’ ‘0’ вимикає, інакше вмикає.
  • LCD_off(); – вимикає дисплей.
  • LCD_on(); – вмикає дисплей.
  • write_str(char *str); – виводить на дисплей текст.
  • write_data(uint8_t *data, size_t size); – виводить на дисплей як текст, так і довільні символи.

Внутрішні та довільні символи на дисплеях LCD1602 та LCD2004

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *