STM Урок 67. HAL. LTDC. BMP. Часть 1

 

 

 

 

Урок 67

 

Часть 1

 

HAL. LTDC. BMP

 

 

Сегодня мы попробуем пойти дальше в сфере изучения программирования интерфейса LTDC и вывести из файла формата BMP картинку на экран. Я думаю, нам это удастся, так как мы этим уже занимались, правда с использованием библиотеки BSP, где был для этого готовый функционал. А теперь нам уже прийдётся написать что-то в этом плане самим.

Отладочную плату используем ту же самую — STM32F746G-DISCOМVERY.

Начнем с проекта. Проект мы сделаем из проекта предыдущего занятия LTDC_SDRAM и назовём его LTDC_BMP.

Откроем его в генераторе проектов Cube MX и включим там для начала поддержку SDIO, в пункте SDMMC1, так как открывать мы будем файлы именно с карты Micro SD

 

image00

 

Также включим FATFS

 

image01

 

В Configuration в FATFS увеличим максимальный размер сектора до 4096

 

image02

 

В Clock Configuration  переключим мультиплексор SDMMC Clock Mux на PLL48CLK

 

image04

 

Сгенерируем проект, откроем его, настроим программатор на авторезет, подключим к проекту файлы ltdc.c и MT48LC4M32B2.c и попробуем собрать проект.

Добавим глобальные переменные в файл main.c

 

/* Private variables ---------------------------------------------------------*/

#define LCD_FRAME_BUFFER SDRAM_DEVICE_ADDR

FATFS SDFatFs; /* File system object for SD card logical drive */

FIL MyFile; /* File object */

extern char SD_Path[4]; /* SD logical drive path */

uint8_t sect[4096];

uint32_t bytesread = 0;

uint8_t* bmp1;

 

Из проекта урока 58 возьмём полностью весь код функции OpenBMP

 

OpenBMP

/* USER CODE BEGIN 0 */

uint32_t OpenBMP(uint8_t *ptr, const char* fname)

{

  uint32_t ind = 0, sz = 0, i1 = 0, ind1 = 0;

  static uint32_t bmp_addr;

  if(f_open(&MyFile, fname, FA_READ) != FR_OK)

  {

    TFT_FillScreen(0xFF00FF00); //в случае неудачи окрасим экран в красный цвет

  }

  else

  {

    if (f_read (&MyFile, sect, 30, (UINT *)bytesread) != FR_OK)

    {

      Error_Handler();

    }

    else

    {

      bmp_addr = (uint32_t)sect;

      sz = *(uint16_t *) (bmp_addr + 2);

      sz |= (*(uint16_t *) (bmp_addr + 4)) << 16;

      /* Get bitmap data address offset */

      ind = *(uint16_t *) (bmp_addr + 10);

      ind |= (*(uint16_t *) (bmp_addr + 12)) << 16;

      f_close (&MyFile);

      f_open (&MyFile, fname, FA_READ);

      ind=0;

      do

      {

        if (sz < 4096)

        {

          i1 = sz;

        }

        else

        {

          i1 = 4096;

        }

        sz -= i1;

        f_lseek(&MyFile,ind1);

        f_read (&MyFile, sect, i1, (UINT *)&bytesread);

        memcpy((void*)(bmp1+ind1), (void*)sect, i1);

        ind1+=i1;

      }

      while (sz > 0);

      f_close (&MyFile);

    }

    ind1=0;

  }

  return 0;

}

/* USER CODE END 0 */

 

 

Установим также указатель на место в памяти SDRAM, как и в уроке 58

 

/* USER CODE BEGIN 1 */

uint16_t i,j;

bmp1 = (uint8_t *)0xC00FF000;

 

На флеш-карту я скопировал 10 рисунков в формате bmp размером 480×272 с форматом пикслея 24 бита на пиксель. Файлы я заранее подготовил из своих избранных фотографий, преобразовав их в данный формат и разрешение.

Из бесконечного цикла удалим весь код.

Экран вместо зелёного окрасим в чёрный цвет

 

HAL_LTDC_SetAddress(&hltdc,LCD_FRAME_BUFFER,0);

TFT_FillScreen(0xFF000000);

 

Примонтируем файловую систему

 

TFT_FillScreen(0xFF000000);

if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)

{

  TFT_FillScreen(0xFFFF0000); //в случае неудачи окрасим экран в красный цвет

  Error_Handler();

}

 

Откроем файл с рисунком

 

Error_Handler();

}

  OpenBMP((uint8_t *)bmp1,"image01.bmp");

 

Идём в файл ltdc.c и добавим туда функцию для отображения рисунка в формате BMP. Делать её будем по подобию той функции, которая присутствует в библиотеке BSP. Добавим в сразу в данную функцию несколько локальных переменных

 

//-------------------------------------------------

void TFT_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp)

{

  uint32_t index = 0, ix=0, width = 0, height = 0, bit_pixel = 0;

}

//-------------------------------------------------

 

Добавим на функцию прототип и сразу вызовем её в main.c

 

OpenBMP((uint8_t *)bmp1,"image01.bmp");

TFT_DrawBitmap(0,0,(uint8_t *)bmp1);

 

Добавим макрос конвертации формата пикселя в файл ltdc.h

 

#define swap(a,b) {int16_t t=a;a=b;b=t;}

#define convert24to32(x) (x|0xFF000000)

 

Вот такой вот простой оказался макрос, в котором мы просто устанавливаем полную непрозрачность в байте 3, который у нас прогрузится вообще из следующего пикселя, что не важно.

Добавим глобальные переменные размеров экрана в файле ltdc.c

 

extern LTDC_HandleTypeDef hltdc;

uint16_t X_SIZE = 480;

uint16_t Y_SIZE = 272;

 

В следующей части урока мы допишем функцию вывода рисунка на экран и испытаем наш код с помощью небольшого теста по последовательному выводу нескольких картинок на экран.

 

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

 

 

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

 

 

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

 

HAL. LTDC. BMP

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

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

*