STM Урок 70. HAL. LTDC. Вывод текста. Часть 2



 

Урок 70

 

Часть 2

 

HAL. LTDC. Вывод текста

 

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

 

Добавим цикл для вывода горизонтальных линий символа

 

offset = 8 *((width + 7)/8) - width ;

for(i = 0; i < height; i++)

{

}

 

В цикле вычислим указатель на линию в символе

 

for(i = 0; i < height; i++)

{

  pchar = ((uint8_t *)ch + (width + 7)/8 * i);

 

В переменную line добавим все пиксели линии из всех байтов в зависимости от ширины символа

 

pchar = ((uint8_t *)ch + (width + 7)/8 * i);

switch((width + 7)/8)

{

  case 1:

    line = pchar[0];

    break;

  case 2:

    line = (pchar[0]<< 8) | pchar[1];

    break;

  case 3:

  default:

    line = (pchar[0]<< 16) | (pchar[1]<< 8) | pchar[2];

    break;

}

 

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

 

  break;

}

for (j = 0; j < width; j++)

{

  if(line & (1 << (width- j + offset- 1)))

  {

    TFT_DrawPixel((x + j), y, lcdprop.TextColor);

  }

  else

  {

    TFT_DrawPixel((x + j), y, lcdprop.BackColor);

  }

}

 

Здесь, я думаю, всё понятно. Если встречается 0, то выводим пиксель с цветом фона, а если 1 — то с цветом символа.

 

 

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

 

    TFT_DrawPixel((x + j), y, lcdprop.BackColor);

  }

}

y++;

 

 Функция готова.

Напишем для неё, а также для всех написанных нами  прототип, затем перейдём в main() и там где мы закрашивали экран в чёрный цвет, поправим цвет на цвет из макроса — так красивее

 

HAL_LTDC_SetAddress(&hltdc,LCD_FRAME_BUFFER,0);

TFT_FillScreen(LCD_COLOR_BLACK);

 

Подправим также код в функции main(), где мы открываем файл BMP (уберем знак процента)

 

    //Копируем содержимое файла последнего рисунка в область памяти bmp1
    OpenBMP((uint8_t *)bmp1,"image01.bmp");

 

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

 

Тест вывода отдельных символов

/* USER CODE BEGIN 3 */

//вывод отдельных символов

TFT_FillScreen(LCD_COLOR_BLACK);

TFT_SetFont(&Font24);

TFT_SetTextColor(LCD_COLOR_YELLOW);

TFT_SetBackColor(LCD_COLOR_BLUE);

TFT_DrawChar(10, 10, (uint8_t)'S');

TFT_DrawChar(27, 10, (uint8_t)'t');

TFT_DrawChar(44, 10, (uint8_t)'m');

TFT_DrawChar(61, 10, (uint8_t)'3');

TFT_DrawChar(78, 10, (uint8_t)'2');

TFT_SetTextColor(LCD_COLOR_GREEN);

TFT_SetBackColor(LCD_COLOR_RED);

TFT_SetFont(&Font20);

TFT_DrawChar(10, 34, (uint8_t)'S');

TFT_DrawChar(24, 34, (uint8_t)'t');

TFT_DrawChar(38, 34, (uint8_t)'m');

TFT_DrawChar(52, 34, (uint8_t)'3');

TFT_DrawChar(66, 34, (uint8_t)'2');

TFT_SetTextColor(LCD_COLOR_BLUE);

TFT_SetBackColor(LCD_COLOR_YELLOW);

TFT_SetFont(&Font16);

TFT_DrawChar(10, 54, (uint8_t)'S');

TFT_DrawChar(21, 54, (uint8_t)'t');

TFT_DrawChar(32, 54, (uint8_t)'m');

TFT_DrawChar(43, 54, (uint8_t)'3');

TFT_DrawChar(54, 54, (uint8_t)'2');

TFT_SetFont(&Font12);

TFT_SetTextColor(LCD_COLOR_CYAN);

TFT_SetBackColor(LCD_COLOR_BLACK);

TFT_DrawChar(10, 70, (uint8_t)'S');

TFT_DrawChar(17, 70, (uint8_t)'t');

TFT_DrawChar(24, 70, (uint8_t)'m');

TFT_DrawChar(31, 70, (uint8_t)'3');

TFT_DrawChar(38, 70, (uint8_t)'2');

TFT_SetFont(&Font8);

TFT_SetTextColor(LCD_COLOR_RED);

TFT_SetBackColor(LCD_COLOR_GREEN);

TFT_DrawChar(10, 82, (uint8_t)'S');

TFT_DrawChar(15, 82, (uint8_t)'t');

TFT_DrawChar(20, 82, (uint8_t)'m');

TFT_DrawChar(25, 82, (uint8_t)'3');

TFT_DrawChar(30, 82, (uint8_t)'2');

HAL_Delay(5000);

//окраска всего экрана случайным цветом

 

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

 

image01

 

Только согласитесь, что выводить тексты отдельными символами не совсем удобно.

 

 

Поэтому вернёмся в нашу библиотеку — в файл ltdc.c — и добавим функцию для вывода текста строками, а также добавим в неё несколько локальных переменных для последующего использования в коде

 

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

void TFT_DisplayString(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode)

{

  uint16_t ref_column = 1, i = 0;

  uint32_t size = 0, xsize = 0;

  uint8_t *ptr = Text;

}

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

 

Определим размер строки, двигаясь по тексту до первой встечи с нулём

 

uint8_t *ptr = Text;

while (*ptr++) size ++ ;

 

Вычислим максимальное количество символов, которое сможет у нас уместиться в ширину, разделив ширину экрана в пикселях на ширину символа

 

while (*ptr++) size ++ ;

xsize = (X_SIZE/lcdprop.pFont->Width);

 

Вычислим горизонтальную координату вывода первого символа строки в зависимости от способа выравнивания текста по ширине

 

xsize = (X_SIZE/lcdprop.pFont->Width);

switch (Mode)

{

  case CENTER_MODE:

  {

    ref_column = Xpos + ((xsize - size) * lcdprop.pFont->Width) / 2;

    break;

  }

  case LEFT_MODE:

  {

    ref_column = Xpos;

    break;

  }

  case RIGHT_MODE:

  {

    ref_column = - Xpos + ((xsize - size) * lcdprop.pFont->Width);

    break;

  }

  default:

  {

    ref_column = Xpos;

    break;

  }

}

 

В случае ухода за левый край экрана сделаем поправку

 

    break;

  }

}

if ((ref_column < 1) || (ref_column >= 0x8000))

{

  ref_column = 1;

}

 

И теперь выведем символы на экран, используя при этом функцию, написанную выше

 

    ref_column = 1;

  }

  while ((*Text != 0) & (((X_SIZE - (i*lcdprop.pFont->Width)) & 0xFFFF) >= lcdprop.pFont->Width))

  {

    TFT_DrawChar(ref_column, Ypos, *Text);

    ref_column += lcdprop.pFont->Width;

    Text++;

    i++;

  }

}

 

Добавим для нашей только что написанной функции прототип и, используя её, напишем ещё один тест в бесконечный цикл в функции main()

 

TFT_DrawChar(30, 82, (uint8_t)'2');

//Вывод строк на экран

TFT_SetFont(&Font24);

TFT_SetTextColor(LCD_COLOR_CYAN);

TFT_SetBackColor(LCD_COLOR_BLACK);

TFT_DisplayString(14, 100, (uint8_t *)"STM32 Left 24", LEFT_MODE);

TFT_SetFont(&Font20);

TFT_SetTextColor(LCD_COLOR_RED);

TFT_DisplayString(14, 130, (uint8_t *)"STM32 Center 20", CENTER_MODE);

TFT_SetFont(&Font16);

TFT_SetTextColor(LCD_COLOR_MAGENTA);

TFT_DisplayString(14, 160, (uint8_t *)"STM32 Right 16", RIGHT_MODE);

HAL_Delay(5000);

 

Соберём код,запустим его на выполнение и посмотрим результат на живом дисплее

 

image02

 

Вот так выглядят наши строки. И, как мы видим, кода также намного меньше, чем при выводе посимвольно.

Итак, сегодня мы освоили ещё один вид вывода информации на экран дисплея, подключенному по интерфейсу LTDC — текстовый.

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

 

 

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

 

 

Исходный код

 

 

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

 

 

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

 

STM HAL. LTDC. Вывод текста

5 комментариев на “STM Урок 70. HAL. LTDC. Вывод текста. Часть 2
  1. Dmitriy:

    После миграции в CubeMX 5.0.1 и компиляции сгенерированного проекта в Atollic 9.2.0 выскакивает на пустом месте ошибка: undefined reference to 'SD_Path'. Как исправить, ума не приложу.

  2. Ан:

    А как русский шрифт добавить?

  3. Дмитрий:

    с цветами ошибки быть не может, при рандомной заливке зеленый и красный цвета есть, а при включении заливки конкретным цветом совпадает только синий, вместо зеленого желтый, вместо красного черный

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

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

*