TFT-LCD显示直线、矩形、圆形
之前显示ASCII字符、中文和图片都是使用的取模软件,这次直接用代码驱动显示直线、矩形和圆形
在前面显示图片的工程上继续加函数
获取像素点
/**
* @name LCD_GetPointPiexl
* @brief 获取像素点
* @param usX:X轴坐标
* usY:Y轴坐标
* @retval None
*/
static uint16_t LCD_GetPointPiexl(uint16_t usX,uint16_t usY)
{
uint16_t usR,usG,usB;
uint16_t usColor; //颜色数据,RGB565格式
//判断坐标是否有效
if((usX < LCD_WIGHT)&&(usY < LCD_HIGHT))
{
//设置窗口,大小为1x1
LCD_SetWindows(usX,usY,1,1);
//写入读GRAM命令0x2E
LCD_WRITE_CMD(LCD_CMD_REGRAM);
//开始读数据
usR = LCD_READ_DATA(); //读Dummy数据,舍弃
usR = LCD_READ_DATA(); //读RED数据
usG = LCD_READ_DATA(); //读GREEN数据
usB = LCD_READ_DATA(); //读BLUE数据
usColor = (((usR>>11)<<11)|((usG>>10)<<5)|(usB>>11)); //组合成16位的RGB565数据格式
printf("The Piexl color is 0x%.4x\r\n",usColor);
}
//返回颜色数据
return usColor;
}
usR、usG、usB变量为16位,但首先读取出的RED数据占5位,且在高字节,GREEN数据占6位,同样在高字节,BLUE数据占5位,在高字节,所以组合时要通过移位,将RED数据放在usColor的高5位,GREEN数据占中间的6位,剩下的5位放BLUE数据,这样就组合成了RGB565的数据格式
设置像素点颜色
/**
* @name LCD_SetPointPiexl
* @brief 设置像素点颜色
* @param usX:X轴坐标
* usY:Y轴坐标
* usColor:显示的颜色
* @retval None
*/
static void LCD_SetPointPiexl(uint16_t usX,uint16_t usY,LCD_Color_t usColor)
{
//判断坐标是否有效
if((usX < LCD_WIGHT)&&(usY < LCD_HIGHT))
{
//设置窗口,大小为1x1
LCD_SetWindows(usX,usY,1,1);
//写入颜色数据
LCD_WRITE_DATA(usColor);
}
}
画直线
画直线使用到了算法,不研究算法的话直接复制使用
/**
* @name LCD_DrawLine
* @brief LCD使用算法画直线
* @param usX_Start:X轴起始坐标
* usY_Start:Y轴起始坐标
* usX_End:X轴终点坐标
* usY_End:Y轴终点坐标
* usColor:显示的颜色
* @retval None
*/
static void LCD_DrawLine(uint16_t usX_Start,uint16_t usY_Start,uint16_t usX_End,uint16_t usY_End,LCD_Color_t usColor)
{
uint16_t i;
uint16_t j; //动态查看画线效果变量
uint16_t usX_Current,usY_Current;
int16_t sError_X=0,sError_Y=0,sDelta_X,sDelta_Y,sDistance;
int16_t sIncrease_X, sIncrease_Y;
//设置坐标增量
sDelta_X = usX_End - usX_Start;
sDelta_Y = usY_End - usY_Start;
usX_Current = usX_Start;
usY_Current = usY_Start;
//算法,直接拿来用
if(sDelta_X > 0)
{
/* 设置单步方向 */
sIncrease_X=1;
}
else if(sDelta_X == 0)
{
/* 垂直线 */
sIncrease_X = 0;
}
else
{
sIncrease_X = -1;
sDelta_X = -sDelta_X;
}
if(sDelta_Y > 0)
{
sIncrease_Y = 1;
}
else if(sDelta_Y==0)
{
/* 水平线 */
sIncrease_Y = 0;
}
else
{
sIncrease_Y = -1;
sDelta_Y = -sDelta_Y;
}
if(sDelta_X > sDelta_Y)
{
/* 选取基本增量坐标轴 */
sDistance = sDelta_X;
}
else
{
sDistance = sDelta_Y;
}
//画线输出
for(i=0;i<=sDistance+1;i++)
{
//画点
TFT_LCD.LCD_SetPointPiexl(usX_Current,usY_Current,usColor);
sError_X += sDelta_X;
sError_Y += sDelta_Y;
if(sError_X > sDistance)
{
sError_X -= sDistance;
usX_Current += sIncrease_X;
}
if(sError_Y > sDistance)
{
sError_Y -= sDistance;
usY_Current += sIncrease_Y;
}
//动态看画线效果,可删除
for(j=0;j<20000;j++);
}
}
画矩形
如果是填充矩形,则调用填充颜色函数按照矩形的宽和高填充颜色就行,如果是不填充矩形,则画四条直线
/**
* @name LCD_DrawRectangle
* @brief LCD画矩形
* @param usX_Start:X轴起始坐标
* usY_Start:Y轴起始坐标
* usWidth:矩形的宽度
* usHeight:矩形的高度
* usColor:显示的颜色
* ucFilled:选择是否填充矩形 参数:Filled:填充,unFilled:不填充
* @retval None
*/
static void LCD_DrawRectangle(uint16_t usX_Start,
uint16_t usY_Start,
uint16_t usWidth,
uint16_t usHeight,
LCD_Color_t usColor,
Filled_t ucFilled)
{
//如果是填充矩形
if(ucFilled == Filled)
{
TFT_LCD.LCD_FillColor(usX_Start,usY_Start,usWidth,usHeight,usColor);
}
//不填充矩形
else
{
//画四条线
TFT_LCD.LCD_DrawLine(usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start, usColor);
TFT_LCD.LCD_DrawLine(usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1, usColor);
TFT_LCD.LCD_DrawLine(usX_Start + usWidth - 1, usY_Start + usHeight - 1, usX_Start, usY_Start + usHeight - 1, usColor);
TFT_LCD.LCD_DrawLine(usX_Start, usY_Start + usHeight - 1, usX_Start, usY_Start, usColor);
}
}
画圆
使用 Bresenham 算法画圆
/**
* @name LCD_DrawCircle
* @brief 在LCD屏幕上使用 Bresenham 算法画圆
* @param usX_Center:圆心X坐标
* usY_Center:圆心Y坐标
* usRadius:圆的半径(单位像素)
* usColor:圆的颜色
* ucFilled:选择是否填充圆形 参数:Filled:填充,unFilled:不填充
* @retval None
*/
static void LCD_DrawCircle(uint16_t usX_Center,uint16_t usY_Center,uint16_t usRadius,LCD_Color_t usColor,Filled_t ucFilled)
{
int16_t sCurrentX, sCurrentY;
int16_t sError;
sCurrentX = 0;
sCurrentY = usRadius;
sError = 3- (usRadius<<1); //判断下个点位置的标志
while(sCurrentX <= sCurrentY)
{
int16_t sCountY;
if(ucFilled)
{
for(sCountY=sCurrentX;sCountY<=sCurrentY;sCountY++)
{
TFT_LCD.LCD_SetPointPiexl(usX_Center + sCurrentX, usY_Center + sCountY, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center - sCurrentX, usY_Center + sCountY, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center - sCountY, usY_Center + sCurrentX, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center - sCountY, usY_Center - sCurrentX, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center - sCurrentX, usY_Center - sCountY, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center + sCurrentX, usY_Center - sCountY, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center + sCountY, usY_Center - sCurrentX, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center + sCountY, usY_Center + sCurrentX, usColor);
}
}
else
{
TFT_LCD.LCD_SetPointPiexl(usX_Center + sCurrentX, usY_Center + sCurrentY, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center - sCurrentX, usY_Center + sCurrentY, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center - sCurrentY, usY_Center + sCurrentX, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center - sCurrentY, usY_Center - sCurrentX, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center - sCurrentX, usY_Center - sCurrentY, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center + sCurrentX, usY_Center - sCurrentY, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center + sCurrentY, usY_Center - sCurrentX, usColor);
TFT_LCD.LCD_SetPointPiexl(usX_Center + sCurrentY, usY_Center + sCurrentX, usColor);
}
sCurrentX++;
if(sError < 0)
{
sError += (4*sCurrentX + 6);
}
else
{
sError += (10 + 4*(sCurrentX - sCurrentY));
sCurrentY--;
}
}
}
主函数调用
/*
* @name Run
* @brief 系统运行
* @param None
* @retval None
*/
static void Run()
{
//画直线
TFT_LCD.LCD_DrawLine(50,20,200,20,Color_RED);
TFT_LCD.LCD_DrawLine(50,30,200,30,Color_GREEN);
TFT_LCD.LCD_DrawLine(50,40,200,40,Color_BLUE);
TFT_LCD.LCD_DrawLine(50,50,200,50,Color_BLACK);
TFT_LCD.LCD_DrawLine(50,60,200,60,Color_YELLOW);
//中间直线
TFT_LCD.LCD_DrawLine(120,90,120,290,Color_BLUE);
//画填充矩形
TFT_LCD.LCD_DrawRectangle(40,90,60,80,Color_BLACK,Filled);
//画不填充矩形
TFT_LCD.LCD_DrawRectangle(140,90,60,80,Color_BLACK,unFilled);
//画不填充圆形
TFT_LCD.LCD_DrawCircle(70,250,40,Color_RED,unFilled);
//画填充圆形
TFT_LCD.LCD_DrawCircle(170,250,40,Color_RED,Filled);
//动态画矩形和圆形
// uint8_t i;
// for(i=10;i<=80;i+=20)
// {
// TFT_LCD.LCD_DrawRectangle(50+i,50,20,20,Color_BLUE,Filled); //动态画矩形
// TFT_LCD.LCD_DrawCircle(120,220,i,Color_RED,unFilled); //动态画圆形
// HAL_Delay(1000);
// }
// for(i=80;i>=10;i-=20)
// {
// TFT_LCD.LCD_DrawRectangle(50+i,50,20,20,Color_GRAY,Filled); //动态画矩形
// TFT_LCD.LCD_DrawCircle(120,220,i,Color_GRAY,unFilled); //动态画圆形
// HAL_Delay(1000);
// }
}