Добавлен вывод текста и чисел
This commit is contained in:
@@ -34,12 +34,12 @@
|
|||||||
#define ST7789V_CMD_COLMOD 0x3A
|
#define ST7789V_CMD_COLMOD 0x3A
|
||||||
|
|
||||||
/* Варианты ориентации экрана */
|
/* Варианты ориентации экрана */
|
||||||
typedef enum {
|
typedef enum DS_ST7789V_Orientation{
|
||||||
DS_ST7789V_ORIENTATION_PORTRAIT = 0,
|
DS_ST7789V_ORIENTATION_PORTRAIT = 0,
|
||||||
DS_ST7789V_ORIENTATION_LANDSCAPE,
|
DS_ST7789V_ORIENTATION_LANDSCAPE,
|
||||||
DS_ST7789V_ORIENTATION_PORTRAIT_REV,
|
DS_ST7789V_ORIENTATION_PORTRAIT_REV,
|
||||||
DS_ST7789V_ORIENTATION_LANDSCAPE_REV
|
DS_ST7789V_ORIENTATION_LANDSCAPE_REV
|
||||||
} DS_ST7789V_Orientation_t;
|
} DS_ST7789V_Orientation;
|
||||||
|
|
||||||
/* Структура конфигурации пинов (аналогично DS_Button) */
|
/* Структура конфигурации пинов (аналогично DS_Button) */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -55,7 +55,7 @@ typedef struct DS_ST7789V {
|
|||||||
DS_ST7789V_Pin_t RES; // Пин аппаратного сброса
|
DS_ST7789V_Pin_t RES; // Пин аппаратного сброса
|
||||||
uint16_t Width; // Текущая ширина с учетом поворота
|
uint16_t Width; // Текущая ширина с учетом поворота
|
||||||
uint16_t Height; // Текущая высота с учетом поворота
|
uint16_t Height; // Текущая высота с учетом поворота
|
||||||
DS_ST7789V_Orientation_t Orientation; // Текущая ориентация
|
DS_ST7789V_Orientation Orientation; // Текущая ориентация
|
||||||
} DS_ST7789V;
|
} DS_ST7789V;
|
||||||
|
|
||||||
/**@brief Инициализация дескриптора дисплея и передача начальных команд
|
/**@brief Инициализация дескриптора дисплея и передача начальных команд
|
||||||
@@ -68,7 +68,7 @@ void DS_ST7789V_Init(DS_ST7789V *lcd, SPI_HandleTypeDef *hspi,
|
|||||||
|
|
||||||
/**@brief Установка ориентации экрана*/
|
/**@brief Установка ориентации экрана*/
|
||||||
void DS_ST7789V_SetOrientation(DS_ST7789V *lcd,
|
void DS_ST7789V_SetOrientation(DS_ST7789V *lcd,
|
||||||
DS_ST7789V_Orientation_t orientation);
|
DS_ST7789V_Orientation orientation);
|
||||||
|
|
||||||
/**@brief Заливка экрана или выделенной области цветом (RGB565)*/
|
/**@brief Заливка экрана или выделенной области цветом (RGB565)*/
|
||||||
void DS_ST7789V_FillRect(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t w,
|
void DS_ST7789V_FillRect(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t w,
|
||||||
@@ -80,4 +80,77 @@ void DS_ST7789V_WriteCommand(DS_ST7789V *lcd, uint8_t cmd);
|
|||||||
|
|
||||||
void DS_ST7789V_WriteData(DS_ST7789V *lcd, uint8_t *data, uint16_t size);
|
void DS_ST7789V_WriteData(DS_ST7789V *lcd, uint8_t *data, uint16_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Отрисовка одиночного пикселя заданным цветом (RGB565)
|
||||||
|
* @param lcd Указатель на структуру дисплея
|
||||||
|
* @param x Координата по горизонтали
|
||||||
|
* @param y Координата по вертикали
|
||||||
|
* @param color Цвет пикселя в формате 16-бит RGB565
|
||||||
|
*/
|
||||||
|
void DS_ST7789V_DrawPixel(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t color);
|
||||||
|
void DS_ST7789V_DrawHLine(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t length, uint16_t color);
|
||||||
|
void DS_ST7789V_DrawVLine(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t length, uint16_t color);
|
||||||
|
|
||||||
|
|
||||||
|
/* Компактный растровый шрифт 5x7 (95 символов ASCII, начиная с пробела 0x20) */
|
||||||
|
static const uint8_t DS_Font5x7[] = {
|
||||||
|
0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x5F,0x00,0x00, 0x00,0x07,0x00,0x07,0x00, 0x14,0x7F,0x14,0x7F,0x14,
|
||||||
|
0x24,0x2A,0x7F,0x2A,0x12, 0x23,0x13,0x08,0x64,0x62, 0x36,0x49,0x55,0x22,0x50, 0x00,0x05,0x03,0x00,0x00,
|
||||||
|
0x00,0x1C,0x22,0x41,0x00, 0x00,0x41,0x22,0x1C,0x00, 0x08,0x2A,0x1C,0x2A,0x08, 0x08,0x08,0x3E,0x08,0x08,
|
||||||
|
0x00,0x50,0x30,0x00,0x00, 0x08,0x08,0x08,0x08,0x08, 0x00,0x60,0x60,0x00,0x00, 0x20,0x10,0x08,0x04,0x02,
|
||||||
|
0x3E,0x51,0x49,0x45,0x3E, 0x00,0x42,0x7F,0x40,0x00, 0x42,0x61,0x51,0x49,0x46, 0x21,0x41,0x45,0x4B,0x31,
|
||||||
|
0x18,0x14,0x12,0x7F,0x10, 0x27,0x45,0x45,0x45,0x39, 0x3C,0x4A,0x49,0x49,0x30, 0x01,0x71,0x09,0x05,0x03,
|
||||||
|
0x36,0x49,0x49,0x49,0x36, 0x06,0x49,0x49,0x29,0x1E, 0x00,0x36,0x36,0x00,0x00, 0x00,0x56,0x36,0x00,0x00,
|
||||||
|
0x00,0x08,0x14,0x22,0x41, 0x14,0x14,0x14,0x14,0x14, 0x41,0x22,0x14,0x08,0x00, 0x02,0x01,0x51,0x09,0x06,
|
||||||
|
0x32,0x49,0x79,0x41,0x3E, 0x7E,0x11,0x11,0x11,0x7E, 0x7F,0x49,0x49,0x49,0x36, 0x3E,0x41,0x41,0x41,0x22,
|
||||||
|
0x7F,0x41,0x41,0x22,0x1C, 0x7F,0x49,0x49,0x49,0x41, 0x7F,0x09,0x09,0x09,0x01, 0x3E,0x41,0x41,0x51,0x72,
|
||||||
|
0x7F,0x08,0x08,0x08,0x7F, 0x00,0x41,0x7F,0x41,0x00, 0x20,0x40,0x41,0x3F,0x01, 0x7F,0x08,0x14,0x22,0x41,
|
||||||
|
0x7F,0x40,0x40,0x40,0x40, 0x7F,0x02,0x0C,0x02,0x7F, 0x7F,0x04,0x08,0x10,0x7F, 0x3E,0x41,0x41,0x41,0x3E,
|
||||||
|
0x7F,0x09,0x09,0x09,0x06, 0x3E,0x41,0x51,0x21,0x5E, 0x7F,0x09,0x19,0x29,0x46, 0x46,0x49,0x49,0x49,0x31,
|
||||||
|
0x01,0x01,0x7F,0x01,0x01, 0x3F,0x40,0x40,0x40,0x3F, 0x1F,0x20,0x40,0x20,0x1F, 0x3F,0x40,0x38,0x40,0x3F,
|
||||||
|
0x63,0x14,0x08,0x14,0x63, 0x03,0x04,0x78,0x04,0x03, 0x61,0x51,0x49,0x45,0x43, 0x00,0x7F,0x41,0x41,0x00,
|
||||||
|
0x02,0x04,0x08,0x10,0x20, 0x00,0x41,0x41,0x7F,0x00, 0x04,0x02,0x01,0x02,0x04, 0x40,0x40,0x40,0x40,0x40,
|
||||||
|
0x00,0x01,0x02,0x04,0x00, 0x20,0x54,0x54,0x54,0x78, 0x7F,0x48,0x44,0x44,0x38, 0x38,0x44,0x44,0x44,0x20,
|
||||||
|
0x38,0x44,0x44,0x48,0x7F, 0x38,0x54,0x54,0x54,0x18, 0x08,0x7E,0x09,0x01,0x02, 0x98,0xA4,0xA4,0xA4,0x7C,
|
||||||
|
0x7F,0x08,0x04,0x04,0x38, 0x00,0x44,0x7D,0x40,0x00, 0x20,0x40,0x44,0x3D,0x00, 0x7F,0x10,0x28,0x44,0x00,
|
||||||
|
0x00,0x41,0x7F,0x40,0x00, 0x7C,0x04,0x18,0x04,0x78, 0x7C,0x08,0x04,0x04,0x78, 0x38,0x44,0x44,0x44,0x38,
|
||||||
|
0xFC,0x24,0x24,0x24,0x18, 0x18,0x24,0x24,0x24,0xFC, 0x7C,0x08,0x04,0x04,0x08, 0x48,0x54,0x54,0x54,0x20,
|
||||||
|
0x04,0x3F,0x44,0x40,0x20, 0x3C,0x40,0x40,0x20,0x7C, 0x1C,0x20,0x40,0x20,0x1C, 0x3C,0x40,0x30,0x40,0x3C,
|
||||||
|
0x44,0x28,0x10,0x28,0x44, 0x4C,0x50,0x50,0x50,0x3C, 0x44,0x64,0x54,0x4C,0x44, 0x00,0x08,0x36,0x41,0x00,
|
||||||
|
0x00,0x00,0x77,0x00,0x00, 0x00,0x41,0x36,0x08,0x00, 0x08,0x08,0x2A,0x1C,0x08
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Отрисовка одного символа текста с масштабированием
|
||||||
|
*/
|
||||||
|
void DS_ST7789V_DrawChar(DS_ST7789V *lcd, uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_color, uint8_t scale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Отрисовка строки текста с масштабированием
|
||||||
|
*/
|
||||||
|
void DS_ST7789V_DrawString(DS_ST7789V *lcd, uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color, uint8_t scale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Вывод целого числа на дисплей
|
||||||
|
*/
|
||||||
|
void DS_ST7789V_DrawInt(DS_ST7789V *lcd, uint16_t x, uint16_t y, int32_t num, uint16_t color, uint16_t bg_color, uint8_t scale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Вывод числа с плавающей точкой (float) на дисплей
|
||||||
|
* @param decimals Количество знаков после запятой (обычно 1 или 2)
|
||||||
|
*/
|
||||||
|
void DS_ST7789V_DrawFloat(DS_ST7789V *lcd, uint16_t x, uint16_t y, float num, uint8_t decimals, uint16_t color, uint16_t bg_color, uint8_t scale);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Прозрачная отрисовка одного символа текста с масштабированием
|
||||||
|
*/
|
||||||
|
void DS_ST7789V_DrawCharTransparent(DS_ST7789V *lcd, uint16_t x, uint16_t y, char ch, uint16_t color, uint8_t scale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Прозрачная отрисовка строки текста с масштабированием
|
||||||
|
*/
|
||||||
|
void DS_ST7789V_DrawStringTransparent(DS_ST7789V *lcd, uint16_t x, uint16_t y, const char *str, uint16_t color, uint8_t scale);
|
||||||
|
|
||||||
|
|
||||||
#endif // DS_ST7789V_H
|
#endif // DS_ST7789V_H
|
||||||
301
Src/DS_ST7789V.c
301
Src/DS_ST7789V.c
@@ -26,30 +26,30 @@ void DS_ST7789V_WriteData(DS_ST7789V *lcd, uint8_t *data, uint16_t size) {
|
|||||||
CS_IDLE(lcd);
|
CS_IDLE(lcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DS_ST7789V_SetAddressWindow(DS_ST7789V *lcd, uint16_t x0,
|
static void DS_ST7789V_SetAddressWindow(DS_ST7789V *lcd, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||||
uint16_t y0, uint16_t x1, uint16_t y1) {
|
uint8_t data[4];
|
||||||
uint8_t data[4];
|
|
||||||
|
|
||||||
/* Настройка столбцов (X) */
|
/* Настройка столбцов (X) */
|
||||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_CASET);
|
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_CASET);
|
||||||
data[0] = (x0 >> 8) & 0xFF;
|
data[0] = (x0 >> 8) & 0xFF;
|
||||||
data[1] = x0 & 0xFF;
|
data[1] = x0 & 0xFF;
|
||||||
data[2] = (x1 >> 8) & 0xFF;
|
data[2] = (x1 >> 8) & 0xFF;
|
||||||
data[3] = x1 & 0xFF;
|
data[3] = x1 & 0xFF;
|
||||||
DS_ST7789V_WriteData(lcd, data, 4);
|
DS_ST7789V_WriteData(lcd, data, 4); // Передаем пачку строго из 4 байт
|
||||||
|
|
||||||
/* Настройка строк (Y) */
|
/* Настройка строк (Y) */
|
||||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_RASET);
|
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_RASET);
|
||||||
data[0] = (y0 >> 8) & 0xFF;
|
data[0] = (y0 >> 8) & 0xFF;
|
||||||
data[1] = y0 & 0xFF;
|
data[1] = y0 & 0xFF;
|
||||||
data[2] = (y1 >> 8) & 0xFF;
|
data[2] = (y1 >> 8) & 0xFF;
|
||||||
data[3] = y1 & 0xFF;
|
data[3] = y1 & 0xFF;
|
||||||
DS_ST7789V_WriteData(lcd, data, 4);
|
DS_ST7789V_WriteData(lcd, data, 4); // Передаем пачку строго из 4 байт
|
||||||
|
|
||||||
/* Готовность к записи в RAM */
|
/* Готовность к записи в RAM дисплея */
|
||||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_RAMWR);
|
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_RAMWR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DS_ST7789V_Init(DS_ST7789V *lcd, SPI_HandleTypeDef *hspi,
|
void DS_ST7789V_Init(DS_ST7789V *lcd, SPI_HandleTypeDef *hspi,
|
||||||
GPIO_TypeDef *cs_port, uint16_t cs_pin,
|
GPIO_TypeDef *cs_port, uint16_t cs_pin,
|
||||||
GPIO_TypeDef *dc_port, uint16_t dc_pin,
|
GPIO_TypeDef *dc_port, uint16_t dc_pin,
|
||||||
@@ -102,7 +102,7 @@ void DS_ST7789V_Init(DS_ST7789V *lcd, SPI_HandleTypeDef *hspi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DS_ST7789V_SetOrientation(DS_ST7789V *lcd,
|
void DS_ST7789V_SetOrientation(DS_ST7789V *lcd,
|
||||||
DS_ST7789V_Orientation_t orientation) {
|
DS_ST7789V_Orientation orientation) {
|
||||||
lcd->Orientation = orientation;
|
lcd->Orientation = orientation;
|
||||||
uint8_t madctl_val = 0;
|
uint8_t madctl_val = 0;
|
||||||
switch (orientation) {
|
switch (orientation) {
|
||||||
@@ -131,26 +131,247 @@ void DS_ST7789V_SetOrientation(DS_ST7789V *lcd,
|
|||||||
DS_ST7789V_WriteData(lcd, &madctl_val, 1);
|
DS_ST7789V_WriteData(lcd, &madctl_val, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DS_ST7789V_FillRect(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t w,
|
void DS_ST7789V_FillRect(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) {
|
||||||
uint16_t h, uint16_t color) {
|
if ((x >= lcd->Width) || (y >= lcd->Height)) return;
|
||||||
if ((x >= lcd->Width) || (y >= lcd->Height))
|
if ((x + w) > lcd->Width) w = lcd->Width - x;
|
||||||
return;
|
if ((y + h) > lcd->Height) h = lcd->Height - y;
|
||||||
if ((x + w) > lcd->Width)
|
|
||||||
w = lcd->Width - x;
|
|
||||||
if ((y + h) > lcd->Height)
|
|
||||||
h = lcd->Height - y;
|
|
||||||
DS_ST7789V_SetAddressWindow(lcd, x, y, x + w - 1, y + h - 1);
|
|
||||||
|
|
||||||
uint8_t color_bytes[2];
|
DS_ST7789V_SetAddressWindow(lcd, x, y, x + w - 1, y + h - 1);
|
||||||
color_bytes[0] = (color >> 8) & 0xFF; // Старший байт цвета (MSB)
|
|
||||||
color_bytes[1] = color & 0xFF; // Младший байт цвета (LSB)
|
|
||||||
uint32_t total_pixels = w * h;
|
|
||||||
DC_DATA(lcd);
|
|
||||||
CS_ACTIVE(lcd);
|
|
||||||
|
|
||||||
/* Передача массива пикселей через HAL блоками для экономии ОЗУ */
|
// Выделяем буфер под увеличенный блок (например, 20 строк экрана за раз)
|
||||||
for (uint32_t i = 0; i < total_pixels; i++) {
|
// 240 пикселей * 20 строк * 2 байта = 9600 байт (у STM32G0B1 целых 144 КБ ОЗУ, это неощутимо)
|
||||||
|
#define CHUNK_ROWS 20
|
||||||
|
static uint8_t chunk_buffer[DS_ST7789V_HEIGHT * CHUNK_ROWS * 2];
|
||||||
|
|
||||||
|
uint8_t high_byte = (color >> 8) & 0xFF;
|
||||||
|
uint8_t low_byte = color & 0xFF;
|
||||||
|
|
||||||
|
// Заполняем этот большой буфер один раз
|
||||||
|
uint32_t pixels_in_chunk = w * CHUNK_ROWS;
|
||||||
|
uint32_t idx = 0;
|
||||||
|
for (uint32_t i = 0; i < pixels_in_chunk; i++) {
|
||||||
|
chunk_buffer[idx++] = high_byte;
|
||||||
|
chunk_buffer[idx++] = low_byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
DC_DATA(lcd);
|
||||||
|
CS_ACTIVE(lcd);
|
||||||
|
|
||||||
|
uint32_t total_pixels = w * h;
|
||||||
|
uint32_t pixels_left = total_pixels;
|
||||||
|
|
||||||
|
// Отправляем данные огромными блоками
|
||||||
|
while (pixels_left > 0) {
|
||||||
|
uint32_t current_chunk_pixels = (pixels_left > pixels_in_chunk) ? pixels_in_chunk : pixels_left;
|
||||||
|
uint32_t bytes_to_send = current_chunk_pixels * 2;
|
||||||
|
|
||||||
|
// Отправка всего блока на максимальной скорости аппаратного SPI
|
||||||
|
HAL_SPI_Transmit(lcd->hspi, chunk_buffer, bytes_to_send, HAL_MAX_DELAY);
|
||||||
|
|
||||||
|
pixels_left -= current_chunk_pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
CS_IDLE(lcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DS_ST7789V_DrawPixel(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t color) {
|
||||||
|
if ((x >= lcd->Width) || (y >= lcd->Height)) return;
|
||||||
|
|
||||||
|
DS_ST7789V_SetAddressWindow(lcd, x, y, x, y);
|
||||||
|
|
||||||
|
uint8_t color_bytes[2]; // Явно объявляем массив из 2 элементов
|
||||||
|
color_bytes[0] = (color >> 8) & 0xFF; // Старший байт (MSB)
|
||||||
|
color_bytes[1] = color & 0xFF; // Младший байт (LSB)
|
||||||
|
|
||||||
|
DC_DATA(lcd);
|
||||||
|
CS_ACTIVE(lcd);
|
||||||
|
|
||||||
|
// Передаем строго массив color_bytes размером 2 байта
|
||||||
HAL_SPI_Transmit(lcd->hspi, color_bytes, 2, HAL_MAX_DELAY);
|
HAL_SPI_Transmit(lcd->hspi, color_bytes, 2, HAL_MAX_DELAY);
|
||||||
}
|
|
||||||
CS_IDLE(lcd);
|
CS_IDLE(lcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Быстрая горизонтальная линия — это прямоугольник высотой в 1 пиксель
|
||||||
|
void DS_ST7789V_DrawHLine(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t length, uint16_t color) {
|
||||||
|
DS_ST7789V_FillRect(lcd, x, y, length, 1, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Быстрая вертикальная линия — это прямоугольник шириной в 1 пиксель
|
||||||
|
void DS_ST7789V_DrawVLine(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t length, uint16_t color) {
|
||||||
|
DS_ST7789V_FillRect(lcd, x, y, 1, length, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS_ST7789V_DrawChar(DS_ST7789V *lcd, uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_color, uint8_t scale) {
|
||||||
|
if (ch < 0x20 || ch > 0x7E) return;
|
||||||
|
if (scale == 0) scale = 1; // Защита от нулевого масштаба
|
||||||
|
|
||||||
|
uint16_t font_index = (ch - 0x20) * 5;
|
||||||
|
|
||||||
|
for (uint8_t col = 0; col < 5; col++) {
|
||||||
|
uint8_t line = DS_Font5x7[font_index + col];
|
||||||
|
for (uint8_t row = 0; row < 7; row++) {
|
||||||
|
// Вычисляем координаты увеличенного "пикселя"
|
||||||
|
uint16_t px = x + (col * scale);
|
||||||
|
uint16_t py = y + (row * scale);
|
||||||
|
|
||||||
|
if (line & (1 << row)) {
|
||||||
|
// Вместо одной точки рисуем закрашенный квадрат размером scale x scale
|
||||||
|
DS_ST7789V_FillRect(lcd, px, py, scale, scale, color);
|
||||||
|
} else {
|
||||||
|
DS_ST7789V_FillRect(lcd, px, py, scale, scale, bg_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS_ST7789V_DrawString(DS_ST7789V *lcd, uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color, uint8_t scale) {
|
||||||
|
if (scale == 0) scale = 1;
|
||||||
|
|
||||||
|
// Шаг смещения: ширина символа (5) * масштаб + 1 пиксель межсимвольного интервала
|
||||||
|
uint8_t char_width = 5 * scale;
|
||||||
|
uint8_t char_height = 7 * scale;
|
||||||
|
uint8_t step_x = char_width + scale;
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
// Перенос строки при достижении правой границы экрана
|
||||||
|
if (x + char_width >= lcd->Width) {
|
||||||
|
x = 0;
|
||||||
|
y += char_height + scale; // Сдвиг вниз на высоту символа + межстрочный интервал
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y + char_height >= lcd->Height) break;
|
||||||
|
|
||||||
|
DS_ST7789V_DrawChar(lcd, x, y, *str, color, bg_color, scale);
|
||||||
|
|
||||||
|
x += step_x;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS_ST7789V_DrawInt(DS_ST7789V *lcd, uint16_t x, uint16_t y, int32_t num, uint16_t color, uint16_t bg_color, uint8_t scale) {
|
||||||
|
char buf[16]; // ИСПРАВЛЕНО: жестко выделили массив на 16 символов
|
||||||
|
int i = 14;
|
||||||
|
buf[15] = '\0'; // ИСПРАВЛЕНО: корректный знак конца строки
|
||||||
|
|
||||||
|
uint8_t is_negative = 0;
|
||||||
|
if (num < 0) {
|
||||||
|
is_negative = 1;
|
||||||
|
num = -num;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num == 0) {
|
||||||
|
buf[i--] = '0';
|
||||||
|
} else {
|
||||||
|
while (num > 0 && i > 0) {
|
||||||
|
buf[i--] = (num % 10) + '0';
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_negative) {
|
||||||
|
buf[i--] = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
DS_ST7789V_DrawString(lcd, x, y, &buf[i + 1], color, bg_color, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DS_ST7789V_DrawFloat(DS_ST7789V *lcd, uint16_t x, uint16_t y, float num, uint8_t decimals, uint16_t color, uint16_t bg_color, uint8_t scale) {
|
||||||
|
char buf[32]; // ИСПРАВЛЕНО: жестко выделили массив на 32 символа
|
||||||
|
int i = 30;
|
||||||
|
buf[31] = '\0'; // ИСПРАВЛЕНО: корректный знак конца строки
|
||||||
|
|
||||||
|
uint8_t is_negative = 0;
|
||||||
|
if (num < 0) {
|
||||||
|
is_negative = 1;
|
||||||
|
num = -num;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rounding = 0.5f;
|
||||||
|
for (uint8_t d = 0; d < decimals; d++) rounding /= 10.0f;
|
||||||
|
num += rounding;
|
||||||
|
|
||||||
|
int32_t int_part = (int32_t)num;
|
||||||
|
float frac_part = num - (float)int_part;
|
||||||
|
|
||||||
|
if (decimals > 0) {
|
||||||
|
for (uint8_t d = 0; d < decimals; d++) {
|
||||||
|
frac_part *= 10.0f;
|
||||||
|
int32_t digit = (int32_t)frac_part;
|
||||||
|
buf[i--] = digit + '0';
|
||||||
|
frac_part -= digit;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = i + 1;
|
||||||
|
int right = 30; // ИСПРАВЛЕНО: индекс конца массива изменен под размер 32
|
||||||
|
while (left < right) {
|
||||||
|
char temp = buf[left];
|
||||||
|
buf[left] = buf[right];
|
||||||
|
buf[right] = temp;
|
||||||
|
left++; right--;
|
||||||
|
}
|
||||||
|
i = 30 - decimals; // ИСПРАВЛЕНО
|
||||||
|
buf[i--] = '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int_part == 0) {
|
||||||
|
buf[i--] = '0';
|
||||||
|
} else {
|
||||||
|
while (int_part > 0 && i > 0) {
|
||||||
|
buf[i--] = (int_part % 10) + '0';
|
||||||
|
int_part /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_negative) {
|
||||||
|
buf[i--] = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
DS_ST7789V_DrawString(lcd, x, y, &buf[i + 1], color, bg_color, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS_ST7789V_DrawCharTransparent(DS_ST7789V *lcd, uint16_t x, uint16_t y, char ch, uint16_t color, uint8_t scale) {
|
||||||
|
if (ch < 0x20 || ch > 0x7E) return;
|
||||||
|
if (scale == 0) scale = 1;
|
||||||
|
|
||||||
|
uint16_t font_index = (ch - 0x20) * 5;
|
||||||
|
|
||||||
|
for (uint8_t col = 0; col < 5; col++) {
|
||||||
|
uint8_t line = DS_Font5x7[font_index + col];
|
||||||
|
for (uint8_t row = 0; row < 7; row++) {
|
||||||
|
// Если бит установлен — отрисовываем масштабированный пиксель цвета текста
|
||||||
|
if (line & (1 << row)) {
|
||||||
|
uint16_t px = x + (col * scale);
|
||||||
|
uint16_t py = y + (row * scale);
|
||||||
|
DS_ST7789V_FillRect(lcd, px, py, scale, scale, color);
|
||||||
|
}
|
||||||
|
// Если бит равен 0 — просто ничего не делаем, пропуская пиксель фона
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DS_ST7789V_DrawStringTransparent(DS_ST7789V *lcd, uint16_t x, uint16_t y, const char *str, uint16_t color, uint8_t scale) {
|
||||||
|
if (scale == 0) scale = 1;
|
||||||
|
|
||||||
|
uint8_t char_width = 5 * scale;
|
||||||
|
uint8_t char_height = 7 * scale;
|
||||||
|
uint8_t step_x = char_width + scale;
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
if (x + char_width >= lcd->Width) {
|
||||||
|
x = 0;
|
||||||
|
y += char_height + scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y + char_height >= lcd->Height) break;
|
||||||
|
|
||||||
|
DS_ST7789V_DrawCharTransparent(lcd, x, y, *str, color, scale);
|
||||||
|
|
||||||
|
x += step_x;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user