doc: added wiki
This commit is contained in:
1 parent
107e1e3e9c
commit
7649522057
1 file changed
+231
+231
@@ -0,0 +1,231 @@
|
||||
# Описание компонента zh_160x_i2c
|
||||
|
||||
## Общие сведения
|
||||
|
||||
**zh_160x_i2c** — это драйвер для ESP-IDF, реализующий управление 16x2 и 16x4 LCD-дисплеями (HD44780-совместимыми) через I2C-расширитель PCF8574.
|
||||
|
||||
Компонент предоставляет высокоуровневый API для вывода текста, управления курсором, отображения индикатора прогресса и работы с числовыми данными на жидкокристаллических дисплеях.
|
||||
|
||||
## Основные возможности
|
||||
|
||||
1. **Поддержка дисплеев 16x2 и 16x4** — автоматическое определение конфигурации экрана.
|
||||
2. **4-битный режим интерфейса** — эффективная передача данных через линии D4–D7 (пин P4–P7 PCF8574).
|
||||
3. **Вывод строк, целых и вещественных чисел** — функции для форматированного вывода числовых данных.
|
||||
4. **Отображение индикатора прогресса** — 16-блочный прогресс-бар с настраиваемым процентом.
|
||||
5. **Управление курсором** — включение/выключение курсора и режима мерцания (blink).
|
||||
6. **Построчная очистка** — очистка произвольной строки дисплея.
|
||||
|
||||
## Внутреннее устройство
|
||||
|
||||
### Структура `zh_160x_i2c_handle_t`
|
||||
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| `zh_pcf8574_handle` | `zh_pcf8574_handle_t *` | Указатель на управляющую структуру расширителя PCF8574 |
|
||||
| `zh_160x_i2c_lcd_size` | `zh_160x_i2c_lcd_size_t` | Конфигурация размера LCD (16x2 или 16x4) |
|
||||
|
||||
Управляющая структура содержит ссылку на расширитель PCF8574 (который принадлежит вызывающей стороне) и текущую конфигурацию размера дисплея для расчёта адресов строк.
|
||||
|
||||
### Управление памятью
|
||||
|
||||
Память под структуру `zh_160x_i2c_handle_t` выделяется функцией `heap_caps_calloc()` с флагом `MALLOC_CAP_8BIT` при вызове `zh_160x_init()`. Освобождение происходит через `heap_caps_free()` в функции `zh_160x_deinit()`, после чего указатель устанавливается в `NULL` для предотвращения use-after-free.
|
||||
|
||||
### Адресация строк HD44780
|
||||
|
||||
HD44780-совместимые контроллеры используют нестандартную адресную карту строк:
|
||||
|
||||
| Физическая строка | Адрес DDRAM |
|
||||
| ------------------- | ------------- |
|
||||
| 0 | `0x00` |
|
||||
| 1 | `0x40` |
|
||||
| 2 | `0x10` |
|
||||
| 3 | `0x50` |
|
||||
|
||||
Массив `_lcd_row_addresses` содержит эти адреса и используется функцией `zh_160x_set_cursor()` для корректного позиционирования курсора.
|
||||
|
||||
### Протокол инициализации LCD
|
||||
|
||||
Инициализация follows HD44780 initialization protocol:
|
||||
|
||||
1. Задержка 20 мс для стабилизации питания.
|
||||
2. Три команды `0x30` с импульсами Enable — перевод в 4-битный режим (последовательность «warm-up»).
|
||||
3. Команда `0x20` — установка 4-битного режима.
|
||||
4. Команда `0x28` — функция set: 4-бит, 2 строки, 5x8 точки.
|
||||
5. Команда `0x0C` — display on, cursor off, blink off.
|
||||
6. Команда `0x01` — clear display.
|
||||
7. Команда `0x06` — entry mode: cursor increment, no shift.
|
||||
|
||||
## API (интерфейс)
|
||||
|
||||
### Инициализация и освобождение
|
||||
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| `zh_160x_init()` | Инициализирует LCD-дисплей, выделяет и настраивает управляющую структуру, отправляет последовательность инициализации контроллеру LCD через расширитель PCF8574. |
|
||||
| `zh_160x_deinit()` | Освобождает выделенную память управляющей структуры и устанавливает указатель в `NULL`. |
|
||||
|
||||
### Позиционирование и очистка
|
||||
|
||||
| Функция | Описание |
|
||||
| --------- | ---------- |
|
||||
| `zh_160x_lcd_clear()` | Очищает весь экран LCD и перемещает курсор в домашнюю позицию (строка 0, столбец 0). |
|
||||
| `zh_160x_set_cursor()` | Устанавливает курсор в указанную позицию (строка и столбец). Для 16x2: строки 0–1, столбцы 0–15. Для 16x4: строки 0–3, столбцы 0–15. |
|
||||
| `zh_160x_clear_row()` | Очищает указанную строку (заполняет 16 пробелами) и возвращает курсор в начало строки. |
|
||||
|
||||
### Вывод данных
|
||||
|
||||
| Функция | Описание |
|
||||
| --------- | ---------- |
|
||||
| `zh_160x_print_char()` | Выводит строку символов в текущую позицию курсора. Курсор автоматически перемещается после каждого символа. |
|
||||
| `zh_160x_print_int()` | Преобразует целое число (signed 32-bit) в десятичную строку и выводит на дисплей. |
|
||||
| `zh_160x_print_float()` | Преобразует число с плавающей точкой в строку с указанным количеством знаков после запятой и выводит на дисплей. |
|
||||
|
||||
### Прогресс-бар и курсор
|
||||
|
||||
| Функция | Описание |
|
||||
| --------- | ---------- |
|
||||
| `zh_160x_print_progress_bar()` | Отображает 16-блочный прогресс-бар на указанной строке. Заполненные блоки отображаются как символ с кодом `0xFF` (требует настройки CGRAM). |
|
||||
| `zh_160x_on_cursor()` | Включает курсор с опциональным режимом мерцания (blink). |
|
||||
| `zh_160x_off_cursor()` | Выключает курсор и режим мерцания. |
|
||||
|
||||
## Потокобезопасность
|
||||
|
||||
Компонент **не является потокобезопасным**. Все операции с LCD-дисплеем требуют внешних механизмов синхронизации (мьютексов, критических секций) при доступе из нескольких задач FreeRTOS. Управляющая структура `zh_160x_i2c_handle_t` не содержит внутренних примитивов синхронизации.
|
||||
|
||||
## Алгоритмы
|
||||
|
||||
### Отправка данных в 4-битном режиме
|
||||
|
||||
Команды и данные передаются в два этапа (старший и младший нибблы) через линии D4–D7:
|
||||
|
||||
1. **Отправка команды (`_zh_160x_send_command`)** — старший ниббл команды записывается на шины с маской `0x08` (RS=0, P3=1), затем генерируется импульс Enable. Затем младший ниббл (сдвинутый на 4 бита) записывается с той же маской и снова импульс Enable.
|
||||
2. **Отправка данных (`_zh_160x_send_data`)** — аналогично, но с маской `0x09` (RS=1 для режима данных, P3=1).
|
||||
3. **Импульс Enable (`_zh_160x_pulse`)** — установка пина P2 в HIGH, задержка 1 мс, установка в LOW, задержка 1 мс. Этот импульс Latch-ит данные в LCD-контроллер.
|
||||
|
||||
### Прогресс-бар
|
||||
|
||||
Процент прогресса конвертируется в количество заполненных блоков по формуле:
|
||||
|
||||
```
|
||||
blocks = (progress * 16) / 100
|
||||
```
|
||||
|
||||
Где `progress` — значение от 0 до 100. Заполненные блоки выводятся как `0xFF` (сплошной блок), пустые — как пробелы.
|
||||
|
||||
## Примеры использования
|
||||
|
||||
### Базовый вывод текста
|
||||
|
||||
```c
|
||||
#include "zh_160x_i2c.h"
|
||||
|
||||
zh_pcf8574_handle_t *pcf8574_handle = NULL;
|
||||
zh_160x_i2c_handle_t *lcd_160x_handle = NULL;
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Настройка I2C-шины и инициализация PCF8574...
|
||||
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, &pcf8574_handle);
|
||||
|
||||
// Инициализация LCD 16x2
|
||||
zh_160x_init(&pcf8574_handle, &lcd_160x_handle, ZH_LCD_16X2);
|
||||
|
||||
// Вывод текста на дисплей
|
||||
zh_160x_set_cursor(&lcd_160x_handle, 0, 0);
|
||||
zh_160x_print_char(&lcd_160x_handle, "Hello, LCD!");
|
||||
zh_160x_set_cursor(&lcd_160x_handle, 1, 0);
|
||||
zh_160x_print_char(&lcd_160x_handle, "ESP32 Ready");
|
||||
|
||||
// Очистка и освобождение ресурсов
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
zh_160x_lcd_clear(&lcd_160x_handle);
|
||||
zh_160x_deinit(&lcd_160x_handle);
|
||||
}
|
||||
```
|
||||
|
||||
### Вывод числовых данных
|
||||
|
||||
```c
|
||||
// Вывод целого числа
|
||||
int temperature = 25;
|
||||
zh_160x_set_cursor(&lcd_160x_handle, 0, 0);
|
||||
zh_160x_print_char(&lcd_160x_handle, "Temp: ");
|
||||
zh_160x_print_int(&lcd_160x_handle, temperature);
|
||||
zh_160x_print_char(&lcd_160x_handle, " C");
|
||||
|
||||
// Вывод числа с плавающей точкой (2 знака после запятой)
|
||||
float voltage = 3.315f;
|
||||
zh_160x_set_cursor(&lcd_160x_handle, 1, 0);
|
||||
zh_160x_print_char(&lcd_160x_handle, "VCC: ");
|
||||
zh_160x_print_float(&lcd_160x_handle, voltage, 2);
|
||||
zh_160x_print_char(&lcd_160x_handle, " V");
|
||||
```
|
||||
|
||||
### Отображение прогресс-бара
|
||||
|
||||
```c
|
||||
// Прогресс-бар требует настройки CGRAM:
|
||||
// DDRAM адрес 0xFF должен быть сопоставлен с пользовательским символом (CGRAM pattern 7)
|
||||
|
||||
for (uint8_t i = 0; i <= 100; i += 10)
|
||||
{
|
||||
zh_160x_set_cursor(&lcd_160x_handle, 0, 0);
|
||||
zh_160x_print_char(&lcd_160x_handle, "Progress: ");
|
||||
zh_160x_print_int(&lcd_160x_handle, i);
|
||||
zh_160x_print_char(&lcd_160x_handle, "%");
|
||||
zh_160x_print_progress_bar(&lcd_160x_handle, 1, i);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
zh_160x_lcd_clear(&lcd_160x_handle);
|
||||
zh_160x_deinit(&lcd_160x_handle);
|
||||
```
|
||||
|
||||
## Логирование
|
||||
|
||||
Компонент использует ESP-IDF логирование с тегом `"zh_160x_i2c"`.
|
||||
|
||||
```c
|
||||
esp_log_level_set("zh_160x_i2c", ESP_LOG_ERROR);
|
||||
```
|
||||
|
||||
Для включения подробного логирования установите уровень `ESP_LOG_DEBUG`.
|
||||
|
||||
## Ошибки
|
||||
|
||||
| Код | Описание |
|
||||
| ----- | ---------- |
|
||||
| `ESP_OK` | Успешное выполнение |
|
||||
| `ESP_ERR_INVALID_ARG` | Неверный аргумент (NULL-указатель, недопустимый размер дисплея, координаты вне диапазона) |
|
||||
| `ESP_ERR_INVALID_STATE` | LCD уже инициализирован (повторная инициализация без деинициализации) |
|
||||
| `ESP_ERR_NO_MEM` | Не удалось выделить память под управляющую структуру |
|
||||
| `ESP_FAIL` | Ошибка записи/чтения через PCF8574 или сбой последовательности инициализации |
|
||||
|
||||
## Ограничения
|
||||
|
||||
1. **Зависимость от компонента `zh_pcf8574`** — требуется установка и инициализация драйвера PCF8574 перед использованием LCD.
|
||||
2. **Буфер 16 символов** — функция `zh_160x_print_float()` использует внутренний буфер фиксированной длины; длинные числа могут быть усечены.
|
||||
3. **Отсутствие потокобезопасности** — все операции с LCD требуют внешней синхронизации при работе из нескольких задач FreeRTOS.
|
||||
4. **Прогресс-бар требует CGRAM** — для отображения заполненных блоков символ с кодом `0xFF` должен быть настроен как пользовательский символ в CGRAM (паттерн 7 HD44780).
|
||||
5. **Один I2C-адрес** — компонент рассчитан на один LCD-модуль на шину; множественные дисплеи требуют дополнительных расширителей или мультиплексирования.
|
||||
|
||||
## Требования для сборки
|
||||
|
||||
- ESP-IDF v5.0 или новее
|
||||
- Компонент `zh_pcf8574` (зависимость, устанавливается автоматически через idf_component_manager)
|
||||
- FreeRTOS (входит в состав ESP-IDF)
|
||||
- Настройка `CONFIG_FREERTOS_HZ=1000` в menuconfig
|
||||
|
||||
## Установка
|
||||
|
||||
```bash
|
||||
cd ваш_проект/components
|
||||
git clone https://github.com/aZholtikov/zh_160x_i2c
|
||||
```
|
||||
|
||||
```c
|
||||
#include "zh_160x_i2c.h"
|
||||
```
|
||||
Reference in new issue
Block a user