У даній статті розглядається приклад підключення РК-дисплеїв LCD1602, LCD2004 до мікроконтролера STM32 з використанням бібліотеки HAL по шині I2C. Буде використовуватись мікроконтролер STM32G030F6P6, перевагами даного мікроконтролера розмір мінімальна кількість додаткових компонентів доступність та ціна, що для DIY пристроїв є вагомим фактором. Даний приклад підходить до всієї лінійки STM32.
Для початку створимо проект у STMCubeMX, у вкладці System Core -> SYS увімкнемо Serial Wire. Також у Connectivity увімкнемо I2C, налаштування I2C залишимо без змін. Та згенеруємо проект.
Імпорт проекту STMCubeMX в PlatfornIO
Підключення LCD1602, LCD2004
Підключення відбувається згідно з обраною шиною I2C, в нашому випадку PB7_PB8 SCL, та PC14 SDA
STM | LCD |
---|---|
PB7_PB8 SCL | SCL |
PC14 SDA | SDA |
5V | 5V |
GND | GND |
Код програми
Використаємо міні бібліотеку 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