Top.Mail.Ru
Ответы
Аватар пользователя
Аватар пользователя
Аватар пользователя
Программирование
+1

Помогите найти ошибку в коде (stm32 подключение дисплея st7789 по spi)

Надеюсь, найдутся умельцы, которые шарят в вопросе))
пытаюсь подключить свой stm32h743vit6 к дисплею на базе мк st7789.
Распиновка дисплея следующая: CS(->PB4); DC(->PB5); RST(->PB6); SDA(->PA7); SCL(->PA5); VCC; GND.
Использую двуканальный режим spi, контакт MISO просто не подключаю, вроде как так можно делать.
Дисплей точно рабочий. Подключение проверил 10 раз.
Собственно, кусок кода:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
 void SPI_SendCommand(uint8_t cmd) { 
    HAL_GPIO_WritePin(GPIOB, TFT_CS_PIN, GPIO_PIN_RESET); // CS LOW 
    HAL_GPIO_WritePin(GPIOB, TFT_DC_PIN, GPIO_PIN_RESET); // Установите DC в 0 для команды 
    HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); // Отправьте команду 
    HAL_GPIO_WritePin(GPIOB, TFT_CS_PIN, GPIO_PIN_SET); // CS HIGH 
} 
 
void SPI_SendData(uint8_t *data, uint16_t size) { 
	HAL_GPIO_WritePin(GPIOB, TFT_CS_PIN, GPIO_PIN_RESET); // CS LOW 
    HAL_GPIO_WritePin(GPIOB, TFT_DC_PIN, GPIO_PIN_SET); // Установите DC в 1 для данных 
    HAL_SPI_Transmit(&hspi1, data, size, HAL_MAX_DELAY); // Отправьте данные 
    HAL_GPIO_WritePin(GPIOB, TFT_CS_PIN, GPIO_PIN_RESET); // CS HIGH 
} 
 
void ST7789_Init() { 
    HAL_GPIO_WritePin(GPIOB, TFT_RST_PIN, GPIO_PIN_RESET); // Сброс дисплея 
    HAL_Delay(100); 
    HAL_GPIO_WritePin(GPIOB, TFT_RST_PIN, GPIO_PIN_SET); 
    HAL_Delay(100); 
 
    SPI_SendCommand(0x01); // SWRESET 
    HAL_Delay(150); 
    SPI_SendCommand(0x11); // SLPOUT 
    HAL_Delay(500); 
 
    SPI_SendCommand(0x3A); // COLMOD 
    uint8_t color_mode = 0x05; // 16 битный цвет (RGB 565) 
    SPI_SendData(&color_mode, 1); 
 
    SPI_SendCommand(0x36); // MADCTL 
    uint8_t madctl = 0x00; // Настройка направления (обычно 0x00) 
    SPI_SendData(&madctl, 1); 
 
    SPI_SendCommand(0x29); // DISPON 
} 
 
void ST7789_FillScreen(uint16_t color) { 
    SPI_SendCommand(0x2A); // CASET 
    uint8_t caset[] = {0x00, 0x00, 0x00, 0xEF}; // Установите область по X 
    SPI_SendData(caset, sizeof(caset)); 
 
    SPI_SendCommand(0x2B); // RASET 
    uint8_t raset[] = {0x00, 0x00, 0x00, 0xEF}; // Установите область по Y 
    SPI_SendData(raset, sizeof(raset)); 
 
    SPI_SendCommand(0x2C); // RAMWR 
 
    uint16_t data[240 * 240]; // Массив для заполнения экрана 
    for (int i = 0; i < 240 * 240; i++) { 
        data[i] = color; // Заполнение массива цветом 
    } 
 
    SPI_SendData((uint8_t*)data, sizeof(data)); // Отправка данных на дисплей 
} 
/* USER CODE END 0 */ 
 
/** 
  * @brief  The application entry point. 
  * @retval int 
  */ 
int main(void) 
{ 
 
  /* USER CODE BEGIN 1 */ 
 
  /* USER CODE END 1 */ 
 
  /* MPU Configuration--------------------------------------------------------*/ 
  MPU_Config(); 
 
  /* MCU Configuration--------------------------------------------------------*/ 
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 
  HAL_Init(); 
 
  /* USER CODE BEGIN Init */ 
 
  /* USER CODE END Init */ 
 
  /* Configure the system clock */ 
  SystemClock_Config(); 
 
  /* USER CODE BEGIN SysInit */ 
 
  /* USER CODE END SysInit */ 
 
  /* Initialize all configured peripherals */ 
  MX_GPIO_Init(); 
  MX_SPI1_Init(); 
  /* USER CODE BEGIN 2 */ 
 

 
   ST7789_Init(); // инициализация дисплея 
   ST7789_FillScreen(0xFFFF); // Заполнение белым цветом (RGB565)
} 
По дате
По рейтингу
Аватар пользователя
Мудрец
6мес

Ваш код в целом выглядит правильным, однако есть несколько потенциальных моментов, которые могут вызывать проблемы:

1. Неправильное состояние CS в функции SPI_SendData

В функции SPI_SendData вы устанавливаете TFT_CS_PIN в низкий уровень до передачи данных, но затем сразу же снова ставите его в высокий уровень после передачи данных, что не соответствует корректному циклу работы с SPI. После завершения передачи данных CS должен оставаться высоким до следующей команды.

Нужно изменить строку:

HAL_GPIO_WritePin(GPIOB, TFT_CS_PIN, GPIO_PIN_RESET); // CS HIGH

на:

HAL_GPIO_WritePin(GPIOB, TFT_CS_PIN, GPIO_PIN_SET); // CS HIGH

Обновлённая версия функции будет выглядеть так:

void SPI_SendData(uint8_t *data, uint16_t size) {
HAL_GPIO_WritePin(GPIOB, TFT_CS_PIN, GPIO_PIN_RESET); // CS LOW
HAL_GPIO_WritePin(GPIOB, TFT_DC_PIN, GPIO_PIN_SET); // DC в 1 для данных
HAL_SPI_Transmit(&hspi1, data, size, HAL_MAX_DELAY); // Отправка данных
HAL_GPIO_WritePin(GPIOB, TFT_CS_PIN, GPIO_PIN_SET); // CS HIGH
}

2. Массив данных для экрана

В функции ST7789_FillScreen у вас есть массив data[240 * 240], который используется для заполнения экрана цветом. Он создаёт массив целых чисел, а вы используете SPI_SendData, который ожидает данные в байтах.

Попробуйте передавать данные по одному байту за раз, а не по 16 бит. Внесите изменения, чтобы отправить данные в формате RGB565, которое ожидает дисплей.

Измените код в ST7789_FillScreen:

void ST7789_FillScreen(uint16_t color) {
SPI_SendCommand(0x2A); // CASET
uint8_t caset[] = {0x00, 0x00, 0x00, 0xEF}; // Установите область по X
SPI_SendData(caset, sizeof(caset));

SPI_SendCommand(0x2B); // RASET
uint8_t raset[] = {0x00, 0x00, 0x00, 0xEF}; // Установите область по Y
SPI_SendData(raset, sizeof(raset));

SPI_SendCommand(0x2C); // RAMWR

uint8_t data[240 * 240 * 2]; // Массив для заполнения экрана (каждый пиксель 2 байта)
for (int i = 0; i < 240 * 240; i++) {
data[2 * i] = color >> 8; // Старший байт
data[2 * i + 1] = color & 0xFF; // Младший байт
}

SPI_SendData(data, sizeof(data)); // Отправка данных на дисплей
}

В этом изменении для каждого пикселя отправляется 2 байта: старший и младший байт цвета в формате RGB565.

3. Настройки SPI

Убедитесь, что настройки SPI в вашем микроконтроллере соответствуют требуемым параметрам для работы с дисплеем ST7789. В частности, убедитесь, что:

Используется режим SPI (full-duplex).

Настройки скорости SPI, формата данных, режима полярности и фазы (CPOL, CPHA) соответствуют требованиям дисплея.


Например, для ST7789 используйте настройки, такие как:

CPOL = 0, CPHA = 0

Скорость SPI: несколько Мбит/с (зависит от частоты вашего микроконтроллера).


4. Сброс дисплея

В некоторых случаях, возможно, потребуется немного увеличить задержку после сброса дисплея. Попробуйте увеличить время задержки в этой строке:

HAL_Delay(100); // Возможно, стоит увеличить время

5. Проверка проводки

Если проблема не устраняется, убедитесь, что вы правильно подключили дисплей и что провода не повреждены. Проверка с осциллографом или логическим анализатором поможет вам увидеть, передаются ли данные через SPI.

Если вы внесете эти изменения, скорее всего, дисплей начнёт работать корректно.