Урок 67
Часть 2
HAL. LTDC. BMP
В предыдущей части нашего урока мы
Продолжим писать нашу функцию вывода картинки на экран с именем TFT_DrawBitmap, находящуюся в файле ltdc.c.
Добавим ещё одну локальную переменную
uint32_t index = 0, ix=0, width = 0, height = 0, bit_pixel = 0;
uint32_t address;
Найдём адрес начала самих данных в файле
uint32_t address;
/* Get bitmap data address offset */
index = *(__IO uint16_t *) (pbmp + 10);
index |= (*(__IO uint16_t *) (pbmp + 12)) << 16;
Определим ширину и высоту рисунка
index |= (*(__IO uint16_t *) (pbmp + 12)) << 16;
/* Read bitmap width */
width = *(uint16_t *) (pbmp + 18);
width |= (*(uint16_t *) (pbmp + 20)) << 16;
/* Read bitmap height */
height = *(uint16_t *) (pbmp + 22);
height |= (*(uint16_t *) (pbmp + 24)) << 16;
Определим формат пикселя
height |= (*(uint16_t *) (pbmp + 24)) << 16;
/* Read bit/pixel */
bit_pixel = *(uint16_t *) (pbmp + 28);
Определим адрес начала данных будущего рисунка в памяти SDRAM
bit_pixel = *(uint16_t *) (pbmp + 28);
/* Set the address */
address = hltdc.LayerCfg[0].FBStartAdress + (((X_SIZE*Ypos) + Xpos)*4);
Передвинем указатель памяти на начало данных в файле, вернее не в самом файле, а в том месте SDRAM, куда мы скопировали файл
address = hltdc.LayerCfg[0].FBStartAdress + (((X_SIZE*Ypos) + Xpos)*(4));
/* Bypass the bitmap header */
pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
Сегодня мы работаем с форматом пикселя 24 бита на пиксель, поэтому в случае открытия файла другого формата мы вставим заглушки в виде окрашивания дисплея в красный и зелёный цвета
pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
if ((bit_pixel/8) == 4)
{
TFT_FillScreen(0xFFFF0000);
}
else if ((bit_pixel/8) == 2)
{
TFT_FillScreen(0xFF00FF00);
}
else
{
}
}
Затем начнём писать код тела условия в случае else.
Передвигаемся по оси y
else
{
/* Convert picture to ARGB8888 pixel format */
for(index=0; index < height; index++)
{
}
}
Теперь двигаемся по оси x
for(index=0; index < height; index++)
{
for(ix=0; ix < width; ix++)
{
}
}
Отправим данные о цвете точки по адресу, применив макрос конвертирования, который мы добавили выше
for(ix=0; ix < width; ix++)
{
*(uint32_t *) (address+(ix*4)) = convert24to32(*(uint32_t *)(pbmp+(ix*3)));
}
Выйдем из цикла продвижения по горизонтали и переместим наши указатели источника и приёмника
*(uint32_t *) (address+(ix*4)) = convert24to32(*(uint32_t *)(pbmp+(ix*3)));
}
address+= (X_SIZE*4);
pbmp -= width*(bit_pixel/8);
}
Теперь вообще выйдем из условия и сбросим на всякий случай флаг формата пикселя (лишним не будет)
}
bit_pixel = 0;
}
Вот и вся собственно функция.
Так как мы её уже вызвали в main.c, то попробуем собрать код и прошить контроллер.
Посмотрим результат
Отлично!
Осталось нам только в бесконечном цикле придумать какой-нибудь цикл, выводящий на экран дисплея поочерёдно все 10 изображений.
Добавим глобальный строчный массив в файле main.c
uint8_t* bmp1;
char str1[15];
Удалим вывод рисунка
Error_Handler();
}
OpenBMP((uint8_t *)bmp1,"image01.bmp");
TFT_DrawBitmap(0,0,(uint8_t *)bmp1);
И добавим несложный код вывода рисункков на экран в бесконечном цикле
/* USER CODE BEGIN 3 */
for(j=1;j<=10;j++)
{
//Копируем содержимое файла очередного рисунка в область памяти bmp1
sprintf(str1,"image%02d.bmp",j);
OpenBMP((uint8_t *)bmp1,str1);
//Выведем рисунок на экран
TFT_DrawBitmap(0,0,(uint8_t *)bmp1);
//Немного подождём до вывода на экран следующего рисунка
HAL_Delay(3000);
}
}
/* USER CODE END 3 */
Соберём код, прошьём контроллер и посмотрим результат
Ну вот и справилcиь мы с очередной задачей — вывести изображение в формате bmp с применением памяти SDRAM на экран дисплея посредством интерфейса LTDC без использования библиотеки BSP.
Предыдущая часть Программирование МК STM32 Следующий урок
Отладочную плату можно приобрести здесь 32F746G-DISCOVERY
Смотреть ВИДЕОУРОК (нажмите на картинку)
Добавить комментарий