Files
zh_160x_i2c/WIKI_RU.md
T

598 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# zh_160x_i2c - Компонент LCD 1602A/1604A через I2C (PCF8574) для ESP-IDF
## Содержание
- [Обзор](#обзор)
- [Возможности](#возможности)
- [Установка](#установка)
- [Справочник API](#справочник-api)
- [Примеры использования](#примеры-использования)
- [Технические характеристики](#технические-характеристики)
- [Коды ошибок](#коды-ошибок)
- [Подключение](#подключение)
- [Вклад в проект](#вклад-в-проект)
- [Лицензия](#лицензия)
---
## Обзор
`zh_160x_i2c` — это легковесный компонент ESP-IDF для управления LCD-дисплеями 1602A и 1604A через интерфейс I2C с использованием расширителей ввода-вывода PCF8574(A). Этот компонент упрощает процесс отображения текста, чисел и индикаторов прогресса на символьных LCD-модулях, предоставляя простой и интуитивно понятный API.
Компонент разработан специально для микроконтроллеров ESP32 и использует драйвер I2C-мастера ESP-IDF и FreeRTOS для оптимальной производительности во встраиваемых системах.
---
## Возможности
1. **[Простой API]**: Удобные функции для распространенных операций с LCD
2. **[Интерфейс I2C]**: Использует только 2 GPIO-пина (SCL и SDA) через расширитель PCF8574
3. **[Поддержка 1602A и 1604A]**: Поддерживает LCD-модули 16x2 и 16x4
4. **[Множественные LCD]**: До 16 LCD-модулей на одной шине I2C
5. **[Отображение текста]**: Вывод строк, целых чисел и чисел с плавающей точкой
6. **[Управление курсором]**: Включение/выключение курсора с опциональным миганием
7. **[Индикатор прогресса]**: Отображение индикаторов прогресса на LCD
8. **[Операции со строками]**: Очистка конкретных строк
9. **[Оптимизировано под ESP-IDF]**: Использует драйвер I2C-мастера ESP-IDF и FreeRTOS
---
## Установка
Перейдите в каталог компонентов вашего проекта:
```bash
cd ../ваш_проект/components
```
Клонируйте репозиторий:
```bash
git clone https://github.com/aZholtikov/zh_160x_i2c
```
В вашем приложении подключите заголовочный файл:
```c
#include "zh_160x_i2c.h"
```
Компонент будет автоматически собран вместе с вашим проектом.
### Обязательные настройки в menuconfig
Для корректной работы компонента включите следующие настройки в menuconfig:
```text
CONFIG_FREERTOS_HZ=1000
CONFIG_I2C_ISR_IRAM_SAFE
CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM
```
---
## Справочник API
### Типы данных
#### zh_160x_i2c_handle_t
```c
typedef struct _zh_160x_i2c_handle_t zh_160x_i2c_handle_t;
```
Непрозрачный дескриптор LCD-дисплея 160x I2C. Внутренняя структура, содержащая дескриптор расширителя PCF8574 и текущую конфигурацию размера LCD.
---
#### zh_160x_i2c_lcd_size_t
```c
typedef enum
{
ZH_LCD_16X2 = 0, /*!< Размер LCD 16x2 */
ZH_LCD_16X4, /*!< Размер LCD 16x4 */
ZH_LCD_NUM_MAX
} zh_160x_i2c_lcd_size_t;
```
Перечисление поддерживаемых размеров LCD-дисплеев.
| Значение | Описание |
| ---------- | ---------- |
| `ZH_LCD_16X2` | LCD размером 16x2 (2 строки по 16 символов) |
| `ZH_LCD_16X4` | LCD размером 16x4 (4 строки по 16 символов) |
---
### zh_160x_init()
Инициализирует LCD-дисплей 160x.
Выделяет и настраивает дескриптор LCD, затем отправляет последовательность инициализации на контроллер LCD через расширитель I2C PCF8574. Настраивает 4-битный режим и устанавливает параметры дисплея по умолчанию.
**Параметры:**
- `expander` - Указатель на дескриптор расширителя PCF8574. Не должен быть NULL
- `handle` - Выходной указатель для нового выделенного дескриптора LCD. Должен быть NULL
- `size` - Размер LCD (ZH_LCD_16X2 или ZH_LCD_16X4)
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL указатель или неверный размер)
- `ESP_ERR_INVALID_STATE` - Дескриптор уже инициализирован
- `ESP_ERR_NO_MEM` - Ошибка выделения памяти
- `ESP_FAIL` - Сбой последовательности инициализации LCD
**Пример:**
```c
zh_pcf8574_handle_t *lcd_expander = NULL;
zh_160x_i2c_handle_t *lcd_handle = NULL;
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
config.i2c_handle = i2c_bus_handle;
config.i2c_address = 0x27;
esp_err_t err = zh_pcf8574_init(&config, &lcd_expander);
if (err != ESP_OK) {
// Обработка ошибки
}
err = zh_160x_init(&lcd_expander, &lcd_handle, ZH_LCD_16X2);
if (err != ESP_OK) {
// Обработка ошибки
}
```
**Примечание:**
Перед инициализацией LCD необходимо инициализировать расширитель PCF8574.
---
### zh_160x_lcd_clear()
Очищает экран LCD и перемещает курсор в домашнюю позицию.
Отправляет команду очистки LCD (0x01) для стирания всего отображаемого текста и сброса курсора в верхний левый угол (строка 0, столбец 0).
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
- `ESP_FAIL` - Ошибка отправки команды
---
### zh_160x_set_cursor()
Устанавливает курсор в указанную позицию на LCD.
Перемещает курсор в указанную строку и столбец.
Для дисплеев 16x2: строки 0–1, столбцы 0–15.
Для дисплеев 16x4: строки 0–3, столбцы 0–15.
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
- `row` - Номер строки (0–1 для 16x2, 0–3 для 16x4)
- `col` - Номер столбца (0–15)
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или координаты вне диапазона)
- `ESP_FAIL` - Ошибка отправки команды
**Примечание:**
Адресация строк: строка 0 = 0x00, строка 1 = 0x40, строка 2 = 0x10, строка 3 = 0x50.
---
### zh_160x_print_char()
Выводит строку на LCD в текущую позицию курсора.
Передаёт каждый символ строки, завершающейся нулём, на LCD в 4-битном режиме. Курсор автоматически перемещается после каждого символа.
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
- `str` - Указатель на null-terminated строку для отображения. Не должен быть NULL
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или str)
- `ESP_FAIL` - Ошибка передачи символа
---
### zh_160x_print_int()
Выводит целое число на LCD в текущую позицию курсора.
Преобразует целое число в десятичную строку и отображает её.
Поддерживает отрицательные числа (максимум 11 цифр плюс знак).
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
- `num` - Целочисленное значение для отображения
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
- `ESP_FAIL` - Ошибка преобразования строки или печати
---
### zh_160x_print_float()
Выводит число с плавающей точкой на LCD в текущую позицию курсора.
Преобразует значение с плавающей точкой в строку с указанной точностью десятичных знаков и отображает её.
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
- `num` - Значение с плавающей точкой для отображения
- `precision` - Количество знаков после запятой (0–6 рекомендуется)
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
- `ESP_FAIL` - Ошибка преобразования строки или печати
---
### zh_160x_print_progress_bar()
Отображает индикатор прогресса в указанной строке LCD.
Отрисовывает 16-блочный индикатор прогресса с использованием пользовательского символа (0xFF).
Заполненные блоки представляют процент прогресса, пустые блоки показывают остаток.
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
- `row` - Номер строки (0–1 для 16x2, 0–3 для 16x4)
- `progress` - Процент прогресса (0–100)
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle, row вне диапазона или progress > 100)
- `ESP_FAIL` - Ошибка установки курсора или печати символов
---
### zh_160x_clear_row()
Очищает указанную строку на LCD.
Перемещает курсор в начало указанной строки и заполняет все 16 позиций пробелами для стирания содержимого.
Курсор остаётся в начале очищенной строки.
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
- `row` - Номер строки (0–1 для 16x2, 0–3 для 16x4)
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или row вне диапазона)
- `ESP_FAIL` - Ошибка установки курсора или печати символов
---
### zh_160x_on_cursor()
Включает курсор с опциональным режимом мигания.
Включает курсор и при необходимости активирует мигание.
Команда 0x0F включает курсор с миганием, 0x0E включает курсор без мигания.
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
- `blink` - Если true, включается мигающий курсор; если false — статичный курсор
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
- `ESP_FAIL` - Ошибка отправки команды
---
### zh_160x_off_cursor()
Отключает курсор и отключает мигание.
Отправляет команду 0x0C для отключения курсора и мигания курсора.
**Параметры:**
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
**Возвращает:**
- `ESP_OK` - Успех
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
- `ESP_FAIL` - Ошибка отправки команды
---
## Примеры использования
### Базовый пример: Одиночный LCD-дисплей
```c
#include "zh_160x_i2c.h"
#define I2C_PORT (I2C_NUM_MAX - 1)
zh_pcf8574_handle_t *lcd_expander = NULL;
zh_160x_i2c_handle_t *lcd_handle = NULL;
void app_main(void)
{
esp_log_level_set("zh_160x_i2c", ESP_LOG_ERROR);
esp_log_level_set("zh_pcf8574", ESP_LOG_ERROR);
esp_log_level_set("zh_vector", ESP_LOG_ERROR);
i2c_master_bus_config_t i2c_bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = I2C_PORT,
.scl_io_num = GPIO_NUM_22,
.sda_io_num = GPIO_NUM_21,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = true,
};
i2c_master_bus_handle_t i2c_bus_handle = NULL;
i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
config.i2c_handle = i2c_bus_handle;
config.i2c_address = 0x27;
esp_err_t err = zh_pcf8574_init(&config, &lcd_expander);
if (err != ESP_OK) {
return;
}
err = zh_160x_init(&lcd_expander, &lcd_handle, ZH_LCD_16X2);
if (err != ESP_OK) {
return;
}
// Отображение текста
zh_160x_set_cursor(&lcd_handle, 0, 0);
zh_160x_print_char(&lcd_handle, "LCD 160X");
zh_160x_set_cursor(&lcd_handle, 1, 0);
zh_160x_print_char(&lcd_handle, "Привет Мир!");
// Очистка ресурсов
zh_160x_deinit(&lcd_handle);
}
```
### Пример: Индикатор прогресса
```c
#include "zh_160x_i2c.h"
#define I2C_PORT (I2C_NUM_MAX - 1)
zh_pcf8574_handle_t *lcd_expander = NULL;
zh_160x_i2c_handle_t *lcd_handle = NULL;
void app_main(void)
{
// ... код инициализации ...
for (uint8_t i = 0; i <= 100; ++i)
{
zh_160x_set_cursor(&lcd_handle, 0, 10);
zh_160x_print_int(&lcd_handle, i);
zh_160x_print_char(&lcd_handle, "%");
zh_160x_print_progress_bar(&lcd_handle, 1, i);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
// Очистка ресурсов
zh_160x_deinit(&lcd_handle);
}
```
### Пример: Отображение различных типов данных
```c
#include "zh_160x_i2c.h"
#define I2C_PORT (I2C_NUM_MAX - 1)
zh_pcf8574_handle_t *lcd_expander = NULL;
zh_160x_i2c_handle_t *lcd_handle = NULL;
void app_main(void)
{
// ... код инициализации ...
// Отображение строки
zh_160x_set_cursor(&lcd_handle, 0, 0);
zh_160x_print_char(&lcd_handle, "Строка: ");
zh_160x_print_char(&lcd_handle, "Привет");
// Отображение целого числа
zh_160x_set_cursor(&lcd_handle, 1, 0);
zh_160x_print_int(&lcd_handle, 42);
// Отображение числа с плавающей точкой
zh_160x_set_cursor(&lcd_handle, 0, 0);
zh_160x_print_float(&lcd_handle, 3.14159, 2); // 3.14
// Включение курсора
zh_160x_on_cursor(&lcd_handle, true); // Мигающий курсор
vTaskDelay(2000 / portTICK_PERIOD_MS);
// Отключение курсора
zh_160x_off_cursor(&lcd_handle);
// Очистка ресурсов
zh_160x_deinit(&lcd_handle);
}
```
### Пример: Несколько LCD на одной шине
```c
#include "zh_160x_i2c.h"
#define I2C_PORT (I2C_NUM_MAX - 1)
zh_pcf8574_handle_t *lcd1_expander = NULL;
zh_160x_i2c_handle_t *lcd1_handle = NULL;
zh_pcf8574_handle_t *lcd2_expander = NULL;
zh_160x_i2c_handle_t *lcd2_handle = NULL;
void app_main(void)
{
esp_log_level_set("zh_160x_i2c", ESP_LOG_ERROR);
esp_log_level_set("zh_pcf8574", ESP_LOG_ERROR);
esp_log_level_set("zh_vector", ESP_LOG_ERROR);
i2c_master_bus_config_t i2c_bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = I2C_PORT,
.scl_io_num = GPIO_NUM_22,
.sda_io_num = GPIO_NUM_21,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = true,
};
i2c_master_bus_handle_t i2c_bus_handle = NULL;
i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
// Инициализация первого LCD по адресу 0x27
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
config.i2c_handle = i2c_bus_handle;
config.i2c_address = 0x27;
zh_pcf8574_init(&config, &lcd1_expander);
zh_160x_init(&lcd1_expander, &lcd1_handle, ZH_LCD_16X2);
// Инициализация второго LCD по адресу 0x26
config.i2c_address = 0x26;
zh_pcf8574_init(&config, &lcd2_expander);
zh_160x_init(&lcd2_expander, &lcd2_handle, ZH_LCD_16X2);
// Отображение на первом LCD
zh_160x_set_cursor(&lcd1_handle, 0, 0);
zh_160x_print_char(&lcd1_handle, "LCD 1");
// Отображение на втором LCD
zh_160x_set_cursor(&lcd2_handle, 0, 0);
zh_160x_print_char(&lcd2_handle, "LCD 2");
// Очистка ресурсов
zh_160x_deinit(&lcd1_handle);
zh_160x_deinit(&lcd2_handle);
}
```
---
## Технические характеристики
| Параметр | Значение |
| ---------- | ---------- |
| **Типы LCD** | 1602A (16x2), 1604A (16x4) |
| **Интерфейс** | I2C через PCF8574(A) |
| **Диапазон адресов I2C** | 0x20-0x27 (PCF8574), 0x38-0x3F (PCF8574A) |
| **Макс. LCD на шине** | 16 |
| **Использование GPIO** | 2 (SCL, SDA) |
| **Версия ESP-IDF** | >= 5.0 |
| **Платформа** | Серия ESP32 |
| **Язык** | C (C99) |
---
## Коды ошибок
| Код ошибки | Описание |
| ------------ | ---------- |
| `ESP_OK` | Операция выполнена успешно |
| `ESP_ERR_INVALID_ARG` | Неверный аргумент (NULL указатель или неверное значение) |
| `ESP_ERR_INVALID_STATE` | Дескриптор не инициализирован |
| `ESP_FAIL` | Общий сбой (ошибка связи I2C) |
---
## Подключение
### Подключение 1602A/1604A к PCF8574
| Пин LCD | Пин PCF8574 | Описание |
|---------|-------------|----------|
| RS | P0 | Выбор регистра |
| E | P2 | Enable |
| D4 | P4 | Бит данных 4 |
| D5 | P5 | Бит данных 5 |
| D6 | P6 | Бит данных 6 |
| D7 | P7 | Бит данных 7 |
### Подключение I2C
| LCD-модуль | PCF8574 | ESP32 |
|------------|---------|-------|
| VCC | VCC | 3.3V |
| GND | GND | GND |
| SDA | SDA | GPIO21 |
| SCL | SCL | GPIO22 |
| RW | GND | GND |
**Примечание:** Пин RW должен быть подключен к GND для операции только записи.
---
## Вклад в проект
Вклад приветствуется! Чтобы внести свой вклад:
1. Сделайте форк репозитория
2. Создайте ветку функции (`git checkout -b feature/AmazingFeature`)
3. Закоммитьте ваши изменения (`git commit -m 'Add some AmazingFeature'`)
4. Отправьте в ветку (`git push origin feature/AmazingFeature`)
5. Откройте Pull Request
Пожалуйста, убедитесь, что ваш код следует существующему стилю и включает соответствующую документацию.
---
## Лицензия
Этот проект лицензирован по лицензии Apache, версия 2.0 - см. файл [LICENSE](LICENSE) для подробной информации.
### Apache License, Version 2.0
Авторское право (c) 2026 Алексей Жолтиков
Лицензировано по лицензии Apache License, Version 2.0 (далее — "Лицензия");
вы не можете использовать этот файл, кроме случаев, предусмотренных Лицензией.
Копию Лицензии можно получить по адресу:
http://www.apache.org/licenses/LICENSE-2.0
Если иное не требуется действующим законодательством или не согласовано в письменном виде,
программное обеспечение, распространяемое по Лицензии, распространяется на условиях "КАК ЕСТЬ",
БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, явных или подразумеваемых, включая, но не ограничиваясь, гарантии
ТОВАРНОГО СОСТОЯНИЯ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ.
Смотрите Лицензию для получения конкретных прав и ограничений.
---
## Дополнительные заметки
- **Подтягивающие резисторы I2C**: Используйте резисторы 4.7 кОм на линиях SDA и SCL для надежной связи
- **Питание**: Обеспечьте стабильное питание 5 В для LCD-модуля (PCF8574 совместим с 5 В)
- **Настройка контраста**: Используйте встроенный подстроечный резистор для настройки контраста LCD для оптимальной видимости
- **Подсветка**: Подсветка LCD обычно подключается к VCC через резистор ограничения тока
- **Производительность**: Операции блокирующие и используют задержки FreeRTOS для правильного тайминга
- **I2C_ISR_IRAM_SAFE**: Для правильной работы включите `I2C_ISR_IRAM_SAFE` и `I2C_MASTER_ISR_HANDLER_IN_IRAM` в menuconfig
- **FreeRTOS**: Для корректной работы настройте `CONFIG_FREERTOS_HZ=1000` в menuconfig
- **Лучшие практики**:
- Всегда инициализируйте PCF8574 перед инициализацией LCD
- Проверьте адрес I2C с помощью сканера, если LCD не отвечает
- Учитывайте ограничения скорости шины I2C при использовании нескольких устройств
---
*Generated for zh_160x_i2c v5.0.1*