AVR Урок 34. Дисплей TFT 240×320 8bit. Часть 6



 

Урок 34

Часть 6

 

Дисплей TFT 240×320 8bit

 

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

Теперь давайте зайдём в файл ili9341.c и напишем вывод на экран дисплея линии с координатами начала и окончания. Так как эта функиция оказалась непростой, то сначала мы её просто создадим, а писать будем постепенно

 

//—————————————————————

void TFT9341_DrawLine(unsigned int color,unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)

{

}

//—————————————————————

 

Как обычно сначала во входных параметрах у нас цвет, а затем координаты начала и окончания линиии.

Применим вот такую конструкцию

 

void TFT9341_DrawLine(unsigned int color,unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)

{

  int steep = abs(y2 y1) > abs(x2 x1);

 

Здесь переменная будет равна единице в случае выполнения условия, а в случае невыполнения будет нулём. В условии у нас неравенство. Мы сравниваем — что у нас больше — разность между вертикальными координатами или между горизонтальными.

И затем уже в зависимости от результата войдём в условие

 

int steep = abs(y2 y1) > abs(x2 x1);

if (steep) {

  swap(x1, y1);

  swap(x2, y2);

}

 

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

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

 

  swap(x2, y2);

}

if (x1 > x2) {

  swap(x1, x2);

  swap(y1, y2);

}

 

Добавим 2 переменных

 

  swap(y1, y2);

}

int dx, dy;

 

Занесём в них разность координат

 

int dx, dy;

dx = x2 x1;

dy = abs(y2 y1);

 

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

 

 

сохраним в переменную половину разницы между вертикальными координатами и создадим ещё одну переменную

 

dy = abs(y2 y1);

int err = dx / 2;

int ystep;

 

Затем, в зависимости от того, какая вертикальная координата меньше, занесём в эту переменную значение

 

int ystep;

if (y1 < y2) {

  ystep = 1;

} else {

  ystep = -1;

}

 

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

 

    ystep = -1;

  }

  for (; x1<=x2; x1++) {

  }

}

 

Теперь займёмся телом данного цикла.

А в цикле будет условие, в котором мы нарисуем точку линии в зависимости от значения переменной steep

 

for (; x1<=x2; x1++) {

if (steep) {

  TFT9341_DrawPixel(y1, x1, color);

} else {

  TFT9341_DrawPixel(x1, y1, color);

}

 

Далее занесём в переменную разницу вертикальных координат с противоположным знаком

 

TFT9341_DrawPixel(x1, y1, color);

}

  err -= dy;

 

Ну и в конце цикла условие, в котором мы наращиваем значение y1 или убавляем его в зависимости от значения переменной ystep

 

    err -= dy;

    if (err < 0) {

      y1 += ystep;

      err += dx;

    }

  }

}

 

 

Вот такая вот интересная функция. Ну, а теперь, конечно, тест в main(), но перед этим мы не забываем про прототип в заголовочном файле. В тесте мы выведем вертикальные линии случайного цвета

 

TFT9341_FillScreen(BLACK);

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

{

  TFT9341_DrawLine(TFT9341_RandColor(),i,0,i,319);

}

_delay_ms(500);

TFT9341_FillScreen(BLACK);

 

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

 

image13

 

Далее напишем тест вывода прямых линий со случайными координатами и случайным цветом

 

TFT9341_FillScreen(BLACK);

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

{

  TFT9341_DrawLine(TFT9341_RandColor(),rand()%240,rand()%320,rand()%240,rand()%320);

}

_delay_ms(500);

TFT9341_FillScreen(BLACK);

 

Давайте проверим данный тест

 

image14

 

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

 

//—————————————————————

void TFT9341_DrawRect(unsigned int color,unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)

{

  TFT9341_DrawLine(color,x1,y1,x2,y1);

  TFT9341_DrawLine(color,x2,y1,x2,y2);

  TFT9341_DrawLine(color,x1,y1,x1,y2);

  TFT9341_DrawLine(color,x1,y2,x2,y2);

}

//—————————————————————

 

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

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

 

TFT9341_FillScreen(BLACK);

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

{

  TFT9341_DrawRect(TFT9341_RandColor(),i,i,239-i,319-i);

}

_delay_ms(500);

TFT9341_FillScreen(BLACK);

 

Проверим тест на практике

 

image15

 

Теперь напишем функцию отрисовки окружности с определённым радиусом

 

//—————————————————————

void TFT9341_DrawCircle(int x0, int y0, int r, unsigned int color)

{

  int f = 1 r;

  int ddF_x = 1;

  int ddF_y = -2 * r;

  int x = 0;

  int y = r;

  TFT9341_DrawPixel(x0 , y0+r, color);

  TFT9341_DrawPixel(x0 , y0r, color);

  TFT9341_DrawPixel(x0+r, y0 , color);

  TFT9341_DrawPixel(x0r, y0 , color);

  while (x<y) {

    if (f >= 0) {

      y—;

     ddF_y += 2;

     f += ddF_y;

    }

    x++;

    ddF_x += 2;

    f += ddF_x;

    TFT9341_DrawPixel(x0 + x, y0 + y, color);

    TFT9341_DrawPixel(x0 x, y0 + y, color);

    TFT9341_DrawPixel(x0 + x, y0 y, color);

    TFT9341_DrawPixel(x0 x, y0 y, color);

    TFT9341_DrawPixel(x0 + y, y0 + x, color);

    TFT9341_DrawPixel(x0 y, y0 + x, color);

    TFT9341_DrawPixel(x0 + y, y0 x, color);

    TFT9341_DrawPixel(x0 y, y0 x, color);

  }

}

//—————————————————————

 

Данная функция была взята из какого-то примера и переработана под наш дисплей.

Во входных параметрах координаты центра, радиус в пикселях и цвет.

Напишем для неё прототип и напишем тест в main(), в котором мы будем выводить в случайное место окружности радиусом в 20 пикселей

 

TFT9341_FillScreen(BLACK);

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

{

  TFT9341_DrawCircle(rand()%200+20,rand()%280+20,20,TFT9341_RandColor());

}

_delay_ms(500);

TFT9341_FillScreen(BLACK);

 

Запас 20 пикселей в координатах сделан для того, чтобы окружности уместились полностью в видимой областью и не попали в область вне экрана.

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

 

image16

 

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

 

 

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

 

 

Техническая документация на контроллер дисплея ILI9341

 

Программатор, символьный дисплей LCD 20×4 и переходник для него можно приобрести здесь:

Программатор USBASP USBISP с адаптером USBASP USBISP 3.3 с адаптером

Дисплей LCD 20×4

Переходник PCF8574 IIC

 

 

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

AVR Дисплей TFT 240×320 8bit

 

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

AVR Дисплей TFT 240×320 8bit

2 комментария на “AVR Урок 34. Дисплей TFT 240×320 8bit. Часть 6
  1. Денис:

    А в протеусе не выводятся линии и символы ? Заливка идет, все работает, но нет символов вообще. Я пробовал убирать заливку, сразу выводить текст, тоже ничего. Координаты тоже изменял на разные. В самом крае дисплея что-то все время виднеется и все, в зависимости от координат, то выше то ниже. Это несоответствие дисплея в протеусе ?

  2. Владимир:

    Отличный урок!
    Вот только у данного дисплея
    есть картоприёмник для карты
    Micro SD,как-бы её сюда прикрутить,
    для регистрации каких-нибудь данных,
    и считывания на дисплей.

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

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

*