Урок 37
Часть 4
Дисплей TFT 240×320 8bit
В прошлой части данного урока мы закончили инициализацию дисплея и уже написали парочку простейших теста для оценки его работы, что показало, что дисплей не смотря на его крошечную цену вполне достойный.
Поэтому будем продолжать с ним работать и напишем в файле ili9341.c функцию для вывода точки определенного цвета на экран
//—————————————————————
void TFT9341_DrawPixel(int x, int y, uint16_t color)
{
if((x<0)||(y<0)||(x>=X_SIZE)||(y>=Y_SIZE)) return;
TFT9341_SetAddrWindow(x, y, x, y);
TFT9341_SendCommand(0x2C);
TFT9341_SendData(color >> 8);
TFT9341_SendData(color & 0xFF);
}
Добавим на нее также прототип в хедер ну и в честь этого конечно тест в main(), только сначала скопируем в main.c функцию задержки
/* USER CODE BEGIN 0 */
__STATIC_INLINE void DelayMicro(__IO uint32_t micros)
{
micros *=(SystemCoreClock / 1000000) / 5;
while (micros—);
}
//—————————————————————
void FileReadWrite(void)
Ну и собственно тест.
TFT9341_FillScreen(BLACK);
for(i=0;i<15000;i++)
{
TFT9341_DrawPixel(HAL_RNG_GetRandomNumber(&hrng)%240,HAL_RNG_GetRandomNumber(&hrng)%320,TFT9341_RandColor());
DelayMicro(100);
}
HAL_Delay(500);
TFT9341_FillScreen(BLACK);
Соберем и прошьем проект.
Вот как выглядит наш тест на экране дисплея
Напишем функцию вывода прямой линии на экран
void TFT9341_DrawLine(uint16_t color, uint16_t x1, uint16_t y1,
uint16_t x2, uint16_t y2)
{
int steep = abs(y2-y1)>abs(x2-x1);
if (steep)
{
swap(x1,y1);
swap(x2,y2);
}
if(x1>x2)
{
swap(x1,x2);
swap(y1,y2);
}
int dx,dy;
dx=x2-x1;
dy=abs(y2-y1);
int err=dx/2;
int ystep;
if(y1<y2) ystep = 1;
else ystep = -1;
for (;x1<=x2;x1++)
{
if (steep) TFT9341_DrawPixel(y1,x1,color);
else TFT9341_DrawPixel(x1,y1,color);
err-=dy;
if (err<0)
{
y1 += ystep;
err+=dx;
}
}
}
//—————————————————————
Напишем прототип и тест в main()
Добавим сначала еще одну переменную в main()
/* USER CODE BEGIN 1 */
uint16_t i,j;
/* USER CODE END 1 */
И собственно сам тест
TFT9341_FillScreen(BLACK);
for(j=0;j<20;j++)
{
for(i=0;i<240;i++)
{
TFT9341_DrawLine(TFT9341_RandColor(),i,0,i,319);
}
HAL_Delay(100);
}
HAL_Delay(500);
TFT9341_FillScreen(BLACK);
Вот так выглядит тест после сборки и прошивки
Напишем ещё один тест, для этого нам новых функций не потребуется
TFT9341_FillScreen(BLACK);
for(i=0;i<1000;i++)
{
TFT9341_DrawLine(TFT9341_RandColor(),HAL_RNG_GetRandomNumber(&hrng)%240,
HAL_RNG_GetRandomNumber(&hrng)%320,HAL_RNG_GetRandomNumber(&hrng)%240,
HAL_RNG_GetRandomNumber(&hrng)%320);
HAL_Delay(1);
}
HAL_Delay(1000);
TFT9341_FillScreen(BLACK);
Соберём код, прошьём контроллер и получим вот такой результат
Дальнейшие тесты и функции для них мы напишем в следующей части занятия.
Предыдущая часть Программирование МК STM32 Следующая часть
Техническая документация на контроллер дисплея
Отладочную плату можно приобрести здесь STM32F4-DISCOVERY
Переходник I2C to LCD можно приобрести здесьI2C to LCD1602 2004
Где приобрести именно такой дисплей TFT 240×320, написать затрудняюсь, так как может прийти не всегда именно такой дисплей, какой заявлен в продаже. Либо придет подключаемый по SPI, либо с другим контроллером. Поэтому все тонкости уточняйте у продавца.
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
В функции TFT9341_DrawLine(), где-то есть ошибка, не подскажете где можно посмотреть оригинал. Огромное спасибо за уроки.
Проекты с исходными кодами всегда находятся в аттаче к последней части урока.
ошибка была именно в вашей функции, но я её исправил. правда сейчас уже не помню как.
Если вспомните, напишите. Буду премного благодарен.
И спасибо за столь бурный интерес к ресурсу!
//——————————- правильная функция вывода отрезка
void TFT_drawLine(uint16_t color, uint16_t x0,uint16_t y0,uint16_t x1, uint16_t y1)
{
int x = x1-x0;
int y = y1-y0;
int dx = abs(x), sx = x0<x1 ? 1 : -1;
int dy = -abs(y), sy = y0= dy) { /* e_xy+e_x > 0 */
if (x0 == x1) break;
err += dy; x0 += sx;
}
if (e2 <= dx) { /* e_xy+e_y < 0 */
if (y0 == y1) break;
err += dx; y0 += sy;
}
}
}
//——————————-
//——————————- правильная функция вывода отрезка
void TFT_drawLine(uint16_t color, uint16_t x0,uint16_t y0,uint16_t x1, uint16_t y1)
{
int x = x1-x0;
int y = y1-y0;
int dx = abs(x), sx = x0<x1 ? 1 : -1;
int dy = -abs(y), sy = y0= dy) {
if (x0 == x1) break;
err += dy; x0 += sx;
}
if (e2 <= dx) {
if (y0 == y1) break;
err += dx; y0 += sy;
}
}
}
//——————————-
Не правильно делает вставку
По непонятным причинам функция DrawLine почему-то не позволяет нарисовать треугольник(полигон)
В сети нашел такую же функцию но исправленную
void ILI9341_DrawLine(uint16_t color, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
int deltaX = abs(x2-x1);
int deltaY = abs(y2-y1);
int signX = x1 < x2 ? 1 : -1;
int signY = y1 < y2 ? 1 : -1;
int error = deltaX — deltaY;
for(;;)
{
ILI9341_DrawPixel(x1,y1,color);
if(x1 == x2 && y1 == y2)
{
break;
}
int error2 = error * 2;
if(error2 > -deltaY)
{
error -= deltaY;
x1 += signX;
}
if(error2 < deltaX)
{
error += deltaX;
y1 += signY;
}
}
}