Первая итерация.
Базовая инициализация, и отрисовка прямоугольников
This commit is contained in:
156
Src/DS_ST7789V.c
Normal file
156
Src/DS_ST7789V.c
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "../inc/DS_ST7789V.h"
|
||||
|
||||
/* Вспомогательные статические макросы для локального управления линиями GPIO */
|
||||
#define CS_ACTIVE(lcd) \
|
||||
HAL_GPIO_WritePin(lcd->CS.Port, lcd->CS.Pin, GPIO_PIN_RESET)
|
||||
#define CS_IDLE(lcd) HAL_GPIO_WritePin(lcd->CS.Port, lcd->CS.Pin, GPIO_PIN_SET)
|
||||
#define DC_COMMAND(lcd) \
|
||||
HAL_GPIO_WritePin(lcd->DC.Port, lcd->DC.Pin, GPIO_PIN_RESET)
|
||||
#define DC_DATA(lcd) HAL_GPIO_WritePin(lcd->DC.Port, lcd->DC.Pin, GPIO_PIN_SET)
|
||||
#define RES_ACTIVE(lcd) \
|
||||
HAL_GPIO_WritePin(lcd->RES.Port, lcd->RES.Pin, GPIO_PIN_RESET)
|
||||
#define RES_IDLE(lcd) \
|
||||
HAL_GPIO_WritePin(lcd->RES.Port, lcd->RES.Pin, GPIO_PIN_SET)
|
||||
|
||||
void DS_ST7789V_WriteCommand(DS_ST7789V *lcd, uint8_t cmd) {
|
||||
DC_COMMAND(lcd);
|
||||
CS_ACTIVE(lcd);
|
||||
HAL_SPI_Transmit(lcd->hspi, &cmd, 1, HAL_MAX_DELAY);
|
||||
CS_IDLE(lcd);
|
||||
}
|
||||
|
||||
void DS_ST7789V_WriteData(DS_ST7789V *lcd, uint8_t *data, uint16_t size) {
|
||||
DC_DATA(lcd);
|
||||
CS_ACTIVE(lcd);
|
||||
HAL_SPI_Transmit(lcd->hspi, data, size, HAL_MAX_DELAY);
|
||||
CS_IDLE(lcd);
|
||||
}
|
||||
|
||||
static void DS_ST7789V_SetAddressWindow(DS_ST7789V *lcd, uint16_t x0,
|
||||
uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
uint8_t data[4];
|
||||
|
||||
/* Настройка столбцов (X) */
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_CASET);
|
||||
data[0] = (x0 >> 8) & 0xFF;
|
||||
data[1] = x0 & 0xFF;
|
||||
data[2] = (x1 >> 8) & 0xFF;
|
||||
data[3] = x1 & 0xFF;
|
||||
DS_ST7789V_WriteData(lcd, data, 4);
|
||||
|
||||
/* Настройка строк (Y) */
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_RASET);
|
||||
data[0] = (y0 >> 8) & 0xFF;
|
||||
data[1] = y0 & 0xFF;
|
||||
data[2] = (y1 >> 8) & 0xFF;
|
||||
data[3] = y1 & 0xFF;
|
||||
DS_ST7789V_WriteData(lcd, data, 4);
|
||||
|
||||
/* Готовность к записи в RAM */
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_RAMWR);
|
||||
}
|
||||
|
||||
void DS_ST7789V_Init(DS_ST7789V *lcd, SPI_HandleTypeDef *hspi,
|
||||
GPIO_TypeDef *cs_port, uint16_t cs_pin,
|
||||
GPIO_TypeDef *dc_port, uint16_t dc_pin,
|
||||
GPIO_TypeDef *res_port, uint16_t res_pin)
|
||||
{
|
||||
lcd->hspi = hspi;
|
||||
|
||||
/* Автоматическая привязка портов на основе сгенерированных CubeMX меток (User
|
||||
* Labels) */
|
||||
lcd->CS.Port = cs_port;
|
||||
lcd->CS.Pin = cs_pin;
|
||||
lcd->DC.Port = dc_port;
|
||||
lcd->DC.Pin = dc_pin;
|
||||
lcd->RES.Port = res_port;
|
||||
lcd->RES.Pin = res_pin;
|
||||
lcd->Width = DS_ST7789V_WIDTH;
|
||||
lcd->Height = DS_ST7789V_HEIGHT;
|
||||
|
||||
/* Аппаратный сброс матрицы */
|
||||
RES_ACTIVE(lcd);
|
||||
HAL_Delay(25);
|
||||
RES_IDLE(lcd);
|
||||
HAL_Delay(120);
|
||||
|
||||
/* Программный сброс контроллера */
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_SWRESET);
|
||||
HAL_Delay(150);
|
||||
|
||||
/* Выход из спящего режима */
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_SLPOUT);
|
||||
HAL_Delay(120);
|
||||
|
||||
/* Установка цветового режима: 16-бит/пиксель (RGB565) */
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_COLMOD);
|
||||
uint8_t color_mode = 0x55;
|
||||
DS_ST7789V_WriteData(lcd, &color_mode, 1);
|
||||
|
||||
/* Установка дефолтной ориентации */
|
||||
DS_ST7789V_SetOrientation(lcd, DS_ST7789V_ORIENTATION_PORTRAIT);
|
||||
|
||||
/* Инверсия цвета дисплея (требуется для большинства IPS матриц этой серии) */
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_INVON);
|
||||
|
||||
/* Включение дисплея */
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_DISPON);
|
||||
HAL_Delay(50);
|
||||
|
||||
/* Первоначальная очистка экрана черным цветом */
|
||||
DS_ST7789V_FillRect(lcd, 0, 0, lcd->Width, lcd->Height, 0x0000);
|
||||
}
|
||||
|
||||
void DS_ST7789V_SetOrientation(DS_ST7789V *lcd,
|
||||
DS_ST7789V_Orientation_t orientation) {
|
||||
lcd->Orientation = orientation;
|
||||
uint8_t madctl_val = 0;
|
||||
switch (orientation) {
|
||||
case DS_ST7789V_ORIENTATION_PORTRAIT:
|
||||
madctl_val = 0x00; // Развертка сверху-вниз, слева-направо
|
||||
lcd->Width = DS_ST7789V_WIDTH;
|
||||
lcd->Height = DS_ST7789V_HEIGHT;
|
||||
break;
|
||||
case DS_ST7789V_ORIENTATION_LANDSCAPE:
|
||||
madctl_val = 0x60; // Обмен строк и столбцов (поворот на 90°)
|
||||
lcd->Width = DS_ST7789V_HEIGHT;
|
||||
lcd->Height = DS_ST7789V_WIDTH;
|
||||
break;
|
||||
case DS_ST7789V_ORIENTATION_PORTRAIT_REV:
|
||||
madctl_val = 0xC0; // Отражение по осям X и Y
|
||||
lcd->Width = DS_ST7789V_WIDTH;
|
||||
lcd->Height = DS_ST7789V_HEIGHT;
|
||||
break;
|
||||
case DS_ST7789V_ORIENTATION_LANDSCAPE_REV:
|
||||
madctl_val = 0xA0; // Альтернативный альбомный режим
|
||||
lcd->Width = DS_ST7789V_HEIGHT;
|
||||
lcd->Height = DS_ST7789V_WIDTH;
|
||||
break;
|
||||
}
|
||||
DS_ST7789V_WriteCommand(lcd, ST7789V_CMD_MADCTL);
|
||||
DS_ST7789V_WriteData(lcd, &madctl_val, 1);
|
||||
}
|
||||
|
||||
void DS_ST7789V_FillRect(DS_ST7789V *lcd, uint16_t x, uint16_t y, uint16_t w,
|
||||
uint16_t h, uint16_t color) {
|
||||
if ((x >= lcd->Width) || (y >= lcd->Height))
|
||||
return;
|
||||
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];
|
||||
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 блоками для экономии ОЗУ */
|
||||
for (uint32_t i = 0; i < total_pixels; i++) {
|
||||
HAL_SPI_Transmit(lcd->hspi, color_bytes, 2, HAL_MAX_DELAY);
|
||||
}
|
||||
CS_IDLE(lcd);
|
||||
}
|
||||
Reference in New Issue
Block a user