【玩转嵌入式屏幕显示】(三)TFT 您所在的位置:网站首页 word表格横向网格线点划线 【玩转嵌入式屏幕显示】(三)TFT

【玩转嵌入式屏幕显示】(三)TFT

2023-08-31 04:21| 来源: 网络整理| 查看: 265

0. 引言

TFT-LCD屏幕的画直线、画斜线、画矩形、画圆等算法都是基于打点函数的,所以此程序可以移植到任何屏幕的基本驱动程序之上。

1. 打点函数 —— 底层函数(移植需修改)

打点函数其实就是屏幕显存(液晶控制器显存)中某一个点的颜色值。

针对SPI驱动的TFT-LCD屏幕:/** * @brief 带颜色画点函数 * @param x,y —— 画点坐标 * @return none */ void LCD_Draw_ColorPoint(uint16_t x, uint16_t y,uint16_t color) { LCD_Address_Set(x, y, x, y); LCD_Write_2Byte(color); } 2. Bresenham算法简介

Bresenham算法是计算机图形学领域使用最广泛的直线扫描转换方法,是计算机图形学中为了“显示器由像素构成”的这个特性而设计出来的算法,使得在求直线各点的过程中全部以整数来运算,因而大幅度了提升计算速度。

3. Bresenham直线算法 快速画水平线

水平线的像素点连续,所以非常好画,直接循环打点就行,算法实现如下:

if(y1 == y2) { /* 快速画水平线 */ LCD_Address_Set(x1, y1, x2, y2); for(i = 0; i > 8; lcd_buf[2 * i + 1] = color; } LCD_WR_RS(1); LCD_SPI_Send(lcd_buf, (x2 - x1) * 2); return; } 画斜线

【玩转嵌入式屏幕显示】(三)TFT-LCD屏幕打点 + 画线 + 画矩形 + 画圆Bresenham算法实现(基于打点函数,算法可移植到任何屏幕的驱动程序之上)_TFT-LCD 图中每个方格就是一个像素点,显然,每一个像素点只有显示颜色可以控制,不能控制显示像素点的一部分,所以红色的真实直线不可能表示出来。

在计算机中将真实的直线(红色)离散化,用图中黑色像素点近似显示,接下里问题转变为:

如何根据给出的直线确定要显示的像素点?

Bresenham提出了一种精确而有效的光栅线生成算法,该算法仅仅使用了增量整数计算,大大提高了画线效率,因此被广泛应用。

该算法的基本原理是:

计算 Δ x \Delta x Δx和 Δ y \Delta y Δy,取两者中的最大值设为 d i s t a n c e distance distance,然后依据 d i s t a n c e distance distance开始打点,每次循环都进行递增,对于另外一个坐标,则选择递增或者不递增。

算法实现如下:

/** * @brief 带颜色画线函数(直线、斜线) * @param x1,y1 起点坐标 * @param x2,y2 终点坐标 * @return none */ void LCD_Draw_ColorLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { uint16_t i = 0; int16_t delta_x = 0, delta_y = 0; int8_t incx = 0, incy = 0; uint16_t distance = 0; uint16_t t = 0; uint16_t x = 0, y = 0; uint16_t x_temp = 0, y_temp = 0; if(y1 == y2) { /* 快速画水平线 */ LCD_Address_Set(x1, y1, x2, y2); for(i = 0; i > 8; lcd_buf[2 * i + 1] = color; } LCD_WR_RS(1); LCD_SPI_Send(lcd_buf, (x2 - x1) * 2); return; } else { /* 画斜线(Bresenham算法) */ /* 计算两点之间在x和y方向的间距,得到画笔在x和y方向的步进值 */ delta_x = x2 - x1; delta_y = y2 - y1; if(delta_x > 0) { //斜线(从左到右) incx = 1; } else if(delta_x == 0) { //垂直斜线(竖线) incx = 0; } else { //斜线(从右到左) incx = -1; delta_x = -delta_x; } if(delta_y > 0) { //斜线(从左到右) incy = 1; } else if(delta_y == 0) { //水平斜线(水平线) incy = 0; } else { //斜线(从右到左) incy = -1; delta_y = -delta_y; } /* 计算画笔打点距离(取两个间距中的最大值) */ if(delta_x > delta_y) { distance = delta_x; } else { distance = delta_y; } /* 开始打点 */ x = x1; y = y1; //第一个点无效,所以t的次数加一 for(t = 0; t distance) { //x方向越界,减去距离值,为下一次检测做准备 x_temp -= distance; //在x方向递增打点 x += incx; } y_temp += delta_y; if(y_temp > distance) { //y方向越界,减去距离值,为下一次检测做准备 y_temp -= distance; //在y方向递增打点 y += incy; } } } } 4. 画矩形算法

画矩形算法比较简单,直接放上算法的代码实现:

/** * @breif 带颜色画矩形函数 * @param x1,y1 —— 矩形起始点 * @param x2,y2 —— 矩形终点 * @param color —— 颜色 * @retval none */ void LCD_Draw_ColorRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { LCD_Draw_ColorLine(x1,y1,x2,y1,color); LCD_Draw_ColorLine(x1,y1,x1,y2,color); LCD_Draw_ColorLine(x1,y2,x2,y2,color); LCD_Draw_ColorLine(x2,y1,x2,y2,color); } 5. 画圆算法

Bresenham画圆算法也称为中点画圆算法,与Bresenham 直线算法一样,其基本的方法是利用判别变量来判断选择最近的像素点,判别变量的数值仅仅用一些加、减和移位运算就可以计算出来。

该算法巧妙的利用了圆的八对称性,只计算出一个八分周上的点,其余的七个点利用对称性即可得出:【玩转嵌入式屏幕显示】(三)TFT-LCD屏幕打点 + 画线 + 画矩形 + 画圆Bresenham算法实现(基于打点函数,算法可移植到任何屏幕的驱动程序之上)_画矩形_02

那么,如何计算出一个八分周(一段圆弧)上的像素点坐标呢?

算法实现代码如下:

/** * @breif 带颜色画圆函数 * @param x1,x2 —— 圆心坐标 * @param r —— 半径 * @param color —— 颜色 * @retval none */ void LCD_Draw_ColorCircle(uint16_t x, uint16_t y, uint16_t r, uint16_t color) { /* Bresenham画圆算法 */ int16_t a = 0, b = r; int16_t d = 3 - (r


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有