STM Урок 208. LL. STM32F4. SPI. Дисплей TFT 240×320



Продолжаем программирование линейки контроллеров STM32F4 с использованием библиотеки LL.

Я решил немного перескочить некоторые части привычного алгоритма изучения библиотек и перейти сразу к шине SPI.

Данное решение принято было потому, что в плате STM32F429I-DISCOVERY, с которой мы работаем, установлен дисплей TFT разрешением 240×320 пикселей на контроллере ILI9341, который подключен к контроллеру как по интерфейсу LTDC, так и по шине SPI. Насчёт LTDC пока вопрос остаётся открытым, так как для него пока, видимо, библиотека LL ещё не написана, по крайней мере в последней на данный момент версии Cube MX мы при всём желании не можем задействовать на интерфейс LTDC данную библиотеку. Поэтому с дисплеем поработаем пока с использованием шины SPI. Дисплей нам постоянно будет требоваться в работе для мониторинга тех или иных состояний и значений, поэтому и было принято данное решение. Заодно и шину SPI рассмотрим.

Модуль SPI у контроллеров серии F4 устроен аналогично серии F1, практически без отличий, а вернее он вообще абсолютно такой же

 

 

Это даёт нам также возможность использовать материалы данного урока для подключения аналогичного дисплея к контроллерам серии F1 по шине SPI.

Что касается регистров, то там из изменений лишь наличие бита FRF (Frame format) в регистре CR2.

С дисплеем TFT разрешением 240×320 на контроллере ILI9341 мы неоднократно работали, в том числе и с использованием шины SPI, правда с использованием библиотеки HAL и с контроллером F1. Но то, что шина устроена точно так же, а также то, что с шиной SPI мы также с использованием библиотеки LL работали, применяя контроллер F1, то нам это значительно облегчит задачу.

Исходя из схемы к плате, подключен наш дисплей к шине SPI5, а ножки, в том числе и управляющие распределились следующим образом

 

PD12RESET
PC2CS
PD13DC
PF7 — SCK
PF9 — MOSI

 

Значит с таким учётом и будем настраивать наш проект в Cube MX, который мы сделаем из проекта прошлого занятия с именем LL_TIMER и присвоим ему новое имя LL_SPI_ILI9341.

Откроем наш проект в Cube MX и первым делом отключим таймер, он нам не потребуется

 

 

Включим SPI и настроим битрейт

 

 

Мы могли бы ещё уменьшить делитель, тем самым увеличив скорость обмена ещё вдвое, и всё бы работало, так как дисплей у нас впаянный, а не подключенный по проводам с разъёмами, но эффекта это никакого не даст, так как мы передаём в дисплей пакеты по одному или по два байта, больше времени уходит на обработку данных, мы не можем их заранее подготовить, положив в буфер и аппаратно оттуда без регистров АЛУ передать в контроллер дисплея. Это будет возможно, когда мы будем применять DMA. А пока предлагаю не мучить модуль SPI лишней неоправданной нагрузкой.

Включим ножку PC2 на выход

 

 

То же самое проделаем и с ножками PD12 и PD13

 

 

Скорость им настроим максимальную, такую же как и у ножек SPI

 

 

Также включим генератор случайных чисел

 

 

Настроим следующий делитель в Clock Configuration

 

 

Также задействуем библиотеку LL для SPI и RNG

 

 

Соберём проект, откроем его в Cube IDE и для начала в файле main.c удалим нашу функцию обработки событий от таймера

 

/* USER CODE BEGIN 4 */

void TIM6_Callback(void)

{

  if(LL_TIM_IsActiveFlag_UPDATE(TIM6))

  {

    LL_TIM_ClearFlag_UPDATE(TIM6);

    if(tim6_flag & 0x01) {LED2_OFF(); LED1_ON(); tim6_flag = 0;}

    else {LED1_OFF(); LED2_ON(); tim6_flag = 1;}

  }

}

 

Из проекта урока 179 с именем ILI9341_SPI добавим в соответствующие папки нашего проекта файлы spi_ili9341.h и spi_ili9341.c и затем переименуем их соответственно в ll_spi_ili9341.h и ll_spi_ili9341.c, а также файлы для работы со шрифтами fonts.h, font8.c, font12.c, font16.c, font20.c и font24.c.

Обновим дерево проекта и в файле ll_spi_ili9341.h вместо данной библиотеки

 

#include <cstdlib>

подключим две стандартные

#include <stdio.h>

#include <stdlib.h>

Также вместо вот этой библиотеки

#include "stm32f4xx_hal.h"

 

подключим несколько библиотек из комплекта LL

 

 

Также изменим немного макросы работы с ножками GPIO, так как, во-первых, библиотека другая и ножки тоже другие

 

 

 

А также переименуем защиту от повторного использования здесь

 

#ifndef __LL_SPI_ILI9341_H

#define __LL_SPI_ILI9341_H

 

и здесь

 

#endif /* __LL_SPI_ILI9341_H */

 

Перейдём теперь в файл ll_spi_ili9341.c и изменим также имя подключаемого файла

 

#include <ll_spi_ili9341.h>

 

Удалим подключение переменных для RNG

 

extern SPI_HandleTypeDef hspi1;

extern RNG_HandleTypeDef hrng;

 

В функции TFT9341_SendCommand удалим вот эту строку

 

HAL_SPI_Transmit (&hspi1, &cmd, 1, 5000);

 

Вместо неё добавим такие строки

 

 

Надеюсь, что как передаются байты в шину SPI при использовании библиотеки LL мы помним.

Аналогично, в функции TFT9341_SendData удалим вот эту строку

 

HAL_SPI_Transmit (&hspi1, &dt, 1, 5000);

 

А вместо неё добавим такие

 

 

В функции TFT9341_WriteData удалим вот эту строку

 

HAL_SPI_Transmit(&hspi1, buff, chunk_size, HAL_MAX_DELAY);

 

А добавим вот такие строки

 

 

Затем в тех местах, где встретится вызов функции задержки HAL_Delay, заменим её на LL_mDelay.

В функции TFT9341_FillRect удалим строку

 

HAL_SPI_Transmit(&hspi1, data, 2, HAL_MAX_DELAY);

 

и заменим её на такую

 

 

В функции TFT9341_RandColor удалим строку

 

return HAL_RNG_GetRandomNumber(&hrng)&0x0000FFFF;

 

и вместо неё вставим вот такие

 

 

 

Перейдём в файл main.c и подключим нашу библиотеку

 

 

Удалим объявление переменной для переключения светодиодов

 

uint8_t tim6_flag=0;

 

Подключим высоту и ширину экрана

 

 

Добавим также функцию задержки в микросекундах

 

 

В функции main() удалим настройку таймера

 

LL_TIM_EnableIT_UPDATE(TIM6);

LL_TIM_EnableCounter(TIM6);

 

Объявим две локальные переменные

 

 

Включим SPI5, вызовем функцию инициализации дисплея и окрасим его в чёрный цвет

 

 

Соберём код, прошьём контроллер и увидим, что дисплей наш окрасился в чёрный цвет

 

 

В бесконечном цикле добавим все наши тесты, немного подредактировав код в свете требований библиотеки LL

 

 

Соберём код, прошьём контроллер, и посмотрим, как работают тесты

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Все наши тесты исправно работают.

Таким образом, на данном уроке нам удалось поработать с дисплеем TFT, распаянном на плате STM32F429I-DISCOVERY и подключенному по шине SPI.

 

Всем спасибо за внимание!

 

 

Предыдущий урок Программирование МК STM32 Следующий урок

 

Исходный код

 

 

Отладочную плату можно приобрести здесь STM32F429I-DISCO

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM LL. STM32F4. SPI. Дисплей TFT 240?320

Один комментарий на “STM Урок 208. LL. STM32F4. SPI. Дисплей TFT 240×320
  1. Владимир:

    Здравствуйте!
    Спасибо за Ваши уроки — очень познавательно!
    Дисплеем как раз разжился и решил поэкспериментировать.
    Сделал как написано в readme — в CubeMX(6.5.0) создал проект для CubeIDE(1.7.0), добавил туда файлы, запустил CubeIDE, вылезли ошибки:
    font12.c:89: multiple definition of Font12_Table'
    font16.c:89: multiple definition of
    Font16_Table'
    font20.c:87: multiple definition of Font20_Table'
    font24.c:85: multiple definition of
    Font24_Table'
    font8.c:89: multiple definition of `Font8_Table'
    Помогите, пожалуйста разобраться с этими ошибками.
    Владимир.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*