1520 lines
44 KiB
C
1520 lines
44 KiB
C
/**
|
||
******************************************************************************
|
||
* @file bsp_lcd.c
|
||
* @author fire
|
||
* @version V1.0
|
||
* @date 2016-xx-xx
|
||
* @brief LCD应用函数接口,支持ARGB888/RGB888/RGB565/ARGB4444/ARGB1555 (不含中文显示)
|
||
******************************************************************************
|
||
* @attention
|
||
*
|
||
* 实验平台:野火 STM32 H750 开发板
|
||
* 论坛 :http://www.firebbs.cn
|
||
* 淘宝 :http://firestm32.taobao.com
|
||
*
|
||
******************************************************************************
|
||
*/
|
||
|
||
/* Includes ------------------------------------------------------------------*/
|
||
#include "./lcd/bsp_lcd.h"
|
||
#include "./fonts//font24.c"
|
||
#include "./fonts//font20.c"
|
||
#include "./fonts//font16.c"
|
||
#include "./fonts//font12.c"
|
||
#include "./fonts//font8.c"
|
||
|
||
|
||
#define POLY_X(Z) ((int32_t)((Points + Z)->X))
|
||
#define POLY_Y(Z) ((int32_t)((Points + Z)->Y))
|
||
|
||
#define ABS(X) ((X) > 0 ? (X) : -(X))
|
||
|
||
static LTDC_HandleTypeDef Ltdc_Handler;
|
||
static DMA2D_HandleTypeDef Dma2d_Handler;
|
||
|
||
/* Default LCD configuration with LCD Layer 1 */
|
||
static uint32_t ActiveLayer = 0;
|
||
static LCD_DrawPropTypeDef DrawProp[MAX_LAYER_NUMBER];
|
||
/**
|
||
* @brief Initializes the LCD.
|
||
* @param None
|
||
* @retval None
|
||
*/
|
||
|
||
|
||
/* 不同液晶屏的参数 */
|
||
const LCD_PARAM_TypeDef lcd_param[LCD_TYPE_NUM]={
|
||
|
||
/* 5寸屏参数 */
|
||
{
|
||
/*根据液晶数据手册的参数配置*/
|
||
.hbp = 46, //HSYNC后的无效像素
|
||
.vbp = 23, //VSYNC后的无效行数
|
||
|
||
.hsw = 1, //HSYNC宽度
|
||
.vsw = 3, //VSYNC宽度
|
||
|
||
.hfp = 40, //HSYNC前的无效像素
|
||
.vfp = 13, //VSYNC前的无效行数
|
||
|
||
.comment_clock_2byte = 33, //rgb565/argb4444等双字节像素时推荐使用的液晶时钟频率
|
||
.comment_clock_4byte = 21, //Argb8888等四字节像素时推荐使用的液晶时钟频率
|
||
|
||
|
||
.lcd_pixel_width = ((uint16_t)800),//液晶分辨率,宽
|
||
.lcd_pixel_height = ((uint16_t)480),//液晶分辨率,高
|
||
|
||
.m_palette_btn_width = 90,//触摸画板按键的宽度
|
||
.m_palette_btn_height = 50,//触摸画板按键的高度
|
||
},
|
||
|
||
/* 7寸屏参数(与5寸一样) */
|
||
{
|
||
/*根据液晶数据手册的参数配置*/
|
||
.hbp = 46, //HSYNC后的无效像素
|
||
.vbp = 23, //VSYNC后的无效行数
|
||
|
||
.hsw = 1, //HSYNC宽度
|
||
.vsw = 1, //VSYNC宽度
|
||
|
||
.hfp = 22, //HSYNC前的无效像素
|
||
.vfp = 22, //VSYNC前的无效行数
|
||
|
||
.comment_clock_2byte = 33, //rgb565/argb4444等双字节像素时推荐使用的液晶时钟频率
|
||
.comment_clock_4byte = 21, //Argb8888等四字节像素时推荐使用的液晶时钟频率
|
||
|
||
|
||
.lcd_pixel_width = ((uint16_t)800),//液晶分辨率,宽
|
||
.lcd_pixel_height = ((uint16_t)480),//液晶分辨率,高
|
||
|
||
.m_palette_btn_width = 90,//触摸画板按键的宽度
|
||
.m_palette_btn_height = 50,//触摸画板按键的高度
|
||
|
||
},
|
||
|
||
/* 4.3寸屏参数 */
|
||
{
|
||
/*根据液晶数据手册的参数配置*/
|
||
.hbp = 8, //HSYNC后的无效像素
|
||
.vbp = 2, //VSYNC后的无效行数
|
||
|
||
.hsw = 41, //HSYNC宽度
|
||
.vsw = 10, //VSYNC宽度
|
||
|
||
.hfp = 4, //HSYNC前的无效像素
|
||
.vfp = 4, //VSYNC前的无效行数
|
||
|
||
.comment_clock_2byte = 15, //rgb565/argb4444等双字节像素时推荐使用的液晶时钟频率
|
||
.comment_clock_4byte = 15, //Argb8888等四字节像素时推荐使用的液晶时钟频率
|
||
|
||
.lcd_pixel_width = 480,//液晶分辨率,宽
|
||
.lcd_pixel_height = 272,//液晶分辨率,高
|
||
|
||
.m_palette_btn_width = 50,//触摸画板按键的宽度
|
||
.m_palette_btn_height = 30,//触摸画板按键的高度
|
||
}
|
||
};
|
||
|
||
|
||
LCD_TypeDef cur_lcd = INCH_5;
|
||
|
||
|
||
static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c);
|
||
static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
|
||
static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex);
|
||
static void LL_ConvertLineToARGB8888(void * pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode);
|
||
/**
|
||
* @brief 初始化控制LCD的IO
|
||
* @param 无
|
||
* @retval 无
|
||
*/
|
||
static void LCD_GPIO_Config(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStruct;
|
||
|
||
/* 使能LCD使用到的引脚时钟 */
|
||
//红色数据线
|
||
LTDC_R0_GPIO_CLK_ENABLE();LTDC_R1_GPIO_CLK_ENABLE();LTDC_R2_GPIO_CLK_ENABLE();\
|
||
LTDC_R3_GPIO_CLK_ENABLE();LTDC_R4_GPIO_CLK_ENABLE();LTDC_R5_GPIO_CLK_ENABLE();\
|
||
LTDC_R6_GPIO_CLK_ENABLE();LTDC_R7_GPIO_CLK_ENABLE();LTDC_G0_GPIO_CLK_ENABLE();\
|
||
LTDC_G1_GPIO_CLK_ENABLE();LTDC_G2_GPIO_CLK_ENABLE();LTDC_G3_GPIO_CLK_ENABLE();\
|
||
LTDC_G3_GPIO_CLK_ENABLE();LTDC_G5_GPIO_CLK_ENABLE();LTDC_G6_GPIO_CLK_ENABLE();\
|
||
LTDC_G7_GPIO_CLK_ENABLE();LTDC_B0_GPIO_CLK_ENABLE();LTDC_B1_GPIO_CLK_ENABLE();\
|
||
LTDC_B2_GPIO_CLK_ENABLE();LTDC_B3_GPIO_CLK_ENABLE();LTDC_B4_GPIO_CLK_ENABLE();\
|
||
LTDC_B5_GPIO_CLK_ENABLE();LTDC_B6_GPIO_CLK_ENABLE();LTDC_B7_GPIO_CLK_ENABLE();\
|
||
LTDC_CLK_GPIO_CLK_ENABLE();LTDC_HSYNC_GPIO_CLK_ENABLE();LTDC_VSYNC_GPIO_CLK_ENABLE();\
|
||
LTDC_DE_GPIO_CLK_ENABLE();LTDC_BL_GPIO_CLK_ENABLE();
|
||
/* GPIO配置 */
|
||
|
||
/* 红色数据线 */
|
||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||
|
||
GPIO_InitStruct.Pin = LTDC_R0_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_R0_AF;
|
||
HAL_GPIO_Init(LTDC_R0_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_R1_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_R1_AF;
|
||
HAL_GPIO_Init(LTDC_R1_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_R2_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_R2_AF;
|
||
HAL_GPIO_Init(LTDC_R2_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_R3_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_R3_AF;
|
||
HAL_GPIO_Init(LTDC_R3_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_R4_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_R4_AF;
|
||
HAL_GPIO_Init(LTDC_R4_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_R5_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_R5_AF;
|
||
HAL_GPIO_Init(LTDC_R5_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_R6_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_R6_AF;
|
||
HAL_GPIO_Init(LTDC_R6_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_R7_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_R7_AF;
|
||
HAL_GPIO_Init(LTDC_R7_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
//绿色数据线
|
||
GPIO_InitStruct.Pin = LTDC_G0_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_G0_AF;
|
||
HAL_GPIO_Init(LTDC_G0_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_G1_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_G1_AF;
|
||
HAL_GPIO_Init(LTDC_G1_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_G2_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_G2_AF;
|
||
HAL_GPIO_Init(LTDC_G2_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_G3_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_G3_AF;
|
||
HAL_GPIO_Init(LTDC_G3_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_G4_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_G4_AF;
|
||
HAL_GPIO_Init(LTDC_G4_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_G5_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_G5_AF;
|
||
HAL_GPIO_Init(LTDC_G5_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_G6_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_G6_AF;
|
||
HAL_GPIO_Init(LTDC_G6_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_G7_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_G7_AF;
|
||
HAL_GPIO_Init(LTDC_G7_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
//蓝色数据线
|
||
GPIO_InitStruct.Pin = LTDC_B0_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_B0_AF;
|
||
HAL_GPIO_Init(LTDC_B0_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_B1_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_B1_AF;
|
||
HAL_GPIO_Init(LTDC_B1_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_B2_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_B2_AF;
|
||
HAL_GPIO_Init(LTDC_B2_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_B3_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_B3_AF;
|
||
HAL_GPIO_Init(LTDC_B3_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_B4_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_B4_AF;
|
||
HAL_GPIO_Init(LTDC_B4_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_B5_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_B5_AF;
|
||
HAL_GPIO_Init(LTDC_B5_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_B6_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_B6_AF;
|
||
HAL_GPIO_Init(LTDC_B6_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_B7_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_B7_AF;
|
||
HAL_GPIO_Init(LTDC_B7_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
//控制信号线
|
||
GPIO_InitStruct.Pin = LTDC_CLK_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_CLK_AF;
|
||
HAL_GPIO_Init(LTDC_CLK_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_HSYNC_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_HSYNC_AF;
|
||
HAL_GPIO_Init(LTDC_HSYNC_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_VSYNC_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_VSYNC_AF;
|
||
HAL_GPIO_Init(LTDC_VSYNC_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = LTDC_DE_GPIO_PIN;
|
||
GPIO_InitStruct.Alternate = LTDC_DE_AF;
|
||
HAL_GPIO_Init(LTDC_DE_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
//背光BL
|
||
GPIO_InitStruct.Pin = LTDC_BL_GPIO_PIN;
|
||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||
|
||
HAL_GPIO_Init(LTDC_BL_GPIO_PORT, &GPIO_InitStruct);
|
||
|
||
}
|
||
/**
|
||
* @brief 时钟配置
|
||
* @retval 无
|
||
*/
|
||
void LCD_ClockConfig(void)
|
||
{
|
||
static RCC_PeriphCLKInitTypeDef periph_clk_init_struct;
|
||
|
||
/* 液晶屏时钟配置 */
|
||
/* 5寸屏的典型PCLK为27 MHz,因此PLL3R配置为提供此时钟 */
|
||
/* AMPIRE640480 LCD clock configuration */
|
||
/* PLL3_VCO Input = HSE_VALUE/PLL3M = 1 Mhz */
|
||
/* PLL3_VCO Output = PLL3_VCO Input * PLL3N = 270 Mhz */
|
||
/* PLLLCDCLK = PLL3_VCO Output/PLL3R = 270/10 = 27Mhz */
|
||
/* LTDC clock frequency = PLLLCDCLK = 27 Mhz */
|
||
periph_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
||
periph_clk_init_struct.PLL3.PLL3M = 25;
|
||
periph_clk_init_struct.PLL3.PLL3N = 270;
|
||
periph_clk_init_struct.PLL3.PLL3P = 2;
|
||
periph_clk_init_struct.PLL3.PLL3Q = 2;
|
||
periph_clk_init_struct.PLL3.PLL3R = 10;
|
||
HAL_RCCEx_PeriphCLKConfig(&periph_clk_init_struct);
|
||
}
|
||
void LCD_Init(void)
|
||
{
|
||
/* 使能LTDC时钟 */
|
||
__HAL_RCC_LTDC_CLK_ENABLE();
|
||
/* 使能DMA2D时钟 */
|
||
__HAL_RCC_DMA2D_CLK_ENABLE();
|
||
/* 液晶屏时钟配置 */
|
||
LCD_ClockConfig();
|
||
/* 初始化LCD引脚 */
|
||
LCD_GPIO_Config();
|
||
/* 初始化SDRAM 用作LCD 显存*/
|
||
SDRAM_Init();
|
||
/* 配置LTDC参数 */
|
||
Ltdc_Handler.Instance = LTDC;
|
||
/* 配置行同步信号宽度(HSW-1) */
|
||
Ltdc_Handler.Init.HorizontalSync =HSW-1;
|
||
/* 配置垂直同步信号宽度(VSW-1) */
|
||
Ltdc_Handler.Init.VerticalSync = VSW-1;
|
||
/* 配置(HSW+HBP-1) */
|
||
Ltdc_Handler.Init.AccumulatedHBP = HSW+HBP-1;
|
||
/* 配置(VSW+VBP-1) */
|
||
Ltdc_Handler.Init.AccumulatedVBP = VSW+VBP-1;
|
||
/* 配置(HSW+HBP+有效像素宽度-1) */
|
||
Ltdc_Handler.Init.AccumulatedActiveW = HSW+HBP+LCD_PIXEL_WIDTH-1;
|
||
/* 配置(VSW+VBP+有效像素高度-1) */
|
||
Ltdc_Handler.Init.AccumulatedActiveH = VSW+VBP+LCD_PIXEL_HEIGHT-1;
|
||
/* 配置总宽度(HSW+HBP+有效像素宽度+HFP-1) */
|
||
Ltdc_Handler.Init.TotalWidth =HSW+ HBP+LCD_PIXEL_WIDTH + HFP-1;
|
||
/* 配置总高度(VSW+VBP+有效像素高度+VFP-1) */
|
||
Ltdc_Handler.Init.TotalHeigh =VSW+ VBP+LCD_PIXEL_HEIGHT + VFP-1;
|
||
|
||
/* 初始化LCD的像素宽度和高度 */
|
||
Ltdc_Handler.LayerCfg->ImageWidth = LCD_PIXEL_WIDTH;
|
||
Ltdc_Handler.LayerCfg->ImageHeight = LCD_PIXEL_HEIGHT;
|
||
/* 设置LCD背景层的颜色,默认黑色 */
|
||
Ltdc_Handler.Init.Backcolor.Red = 0;
|
||
Ltdc_Handler.Init.Backcolor.Green = 0;
|
||
Ltdc_Handler.Init.Backcolor.Blue = 0;
|
||
/* 极性配置 */
|
||
/* 初始化行同步极性,低电平有效 */
|
||
Ltdc_Handler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
|
||
/* 初始化场同步极性,低电平有效 */
|
||
Ltdc_Handler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
|
||
/* 初始化数据有效极性,低电平有效 */
|
||
Ltdc_Handler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
|
||
/* 初始化行像素时钟极性,同输入时钟 */
|
||
Ltdc_Handler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
|
||
HAL_LTDC_Init(&Ltdc_Handler);
|
||
/* 初始化字体 */
|
||
LCD_SetFont(&LCD_DEFAULT_FONT);
|
||
}
|
||
|
||
/**
|
||
* @brief 获取LCD当前有效层X轴的大小
|
||
* @retval X轴的大小
|
||
*/
|
||
uint32_t LCD_GetXSize(void)
|
||
{
|
||
return Ltdc_Handler.LayerCfg[ActiveLayer].ImageWidth;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取LCD当前有效层Y轴的大小
|
||
* @retval Y轴的大小
|
||
*/
|
||
uint32_t LCD_GetYSize(void)
|
||
{
|
||
return Ltdc_Handler.LayerCfg[ActiveLayer].ImageHeight;
|
||
}
|
||
|
||
/**
|
||
* @brief 设置LCD当前有效层Y轴的大小
|
||
* @param imageWidthPixels:图像宽度像素个数
|
||
* @retval 无
|
||
*/
|
||
void LCD_SetXSize(uint32_t imageWidthPixels)
|
||
{
|
||
Ltdc_Handler.LayerCfg[ActiveLayer].ImageWidth = imageWidthPixels;
|
||
}
|
||
|
||
/**
|
||
* @brief 设置LCD当前有效层Y轴的大小
|
||
* @param imageHeightPixels:图像高度像素个数
|
||
* @retval None
|
||
*/
|
||
void LCD_SetYSize(uint32_t imageHeightPixels)
|
||
{
|
||
Ltdc_Handler.LayerCfg[ActiveLayer].ImageHeight = imageHeightPixels;
|
||
}
|
||
|
||
/**
|
||
* @brief 初始化LCD层
|
||
* @param LayerIndex: 前景层(层1)或者背景层(层0)
|
||
* @param FB_Address: 每一层显存的首地址
|
||
* @param PixelFormat: 层的像素格式
|
||
* @retval 无
|
||
*/
|
||
void LCD_LayerInit(uint16_t LayerIndex, uint32_t FB_Address,uint32_t PixelFormat)
|
||
{
|
||
LTDC_LayerCfgTypeDef layer_cfg;
|
||
|
||
/* 层初始化 */
|
||
layer_cfg.WindowX0 = 0; //窗口起始位置X坐标
|
||
layer_cfg.WindowX1 = LCD_GetXSize(); //窗口结束位置X坐标
|
||
layer_cfg.WindowY0 = 0; //窗口起始位置Y坐标
|
||
layer_cfg.WindowY1 = LCD_GetYSize(); //窗口结束位置Y坐标
|
||
layer_cfg.PixelFormat = PixelFormat; //像素格式
|
||
layer_cfg.FBStartAdress = FB_Address; //层显存首地址
|
||
layer_cfg.Alpha = 255; //用于混合的透明度常量,范围(0—255)0为完全透明
|
||
layer_cfg.Alpha0 = 0; //默认透明度常量,范围(0—255)0为完全透明
|
||
layer_cfg.Backcolor.Blue = 0; //层背景颜色蓝色分量
|
||
layer_cfg.Backcolor.Green = 0; //层背景颜色绿色分量
|
||
layer_cfg.Backcolor.Red = 0; //层背景颜色红色分量
|
||
layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;//层混合系数1
|
||
layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;//层混合系数2
|
||
layer_cfg.ImageWidth = LCD_GetXSize();//设置图像宽度
|
||
layer_cfg.ImageHeight = LCD_GetYSize();//设置图像高度
|
||
|
||
HAL_LTDC_ConfigLayer(&Ltdc_Handler, &layer_cfg, LayerIndex); //设置选中的层参数
|
||
|
||
DrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;//设置层的字体颜色
|
||
DrawProp[LayerIndex].pFont = &LCD_DEFAULT_FONT;//设置层的字体类型
|
||
DrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK; //设置层的字体背景颜色
|
||
|
||
__HAL_LTDC_RELOAD_CONFIG(&Ltdc_Handler);//重载层的配置参数
|
||
}
|
||
/**
|
||
* @brief 选择LCD层
|
||
* @param LayerIndex: 前景层(层1)或者背景层(层0)
|
||
* @retval 无
|
||
*/
|
||
void LCD_SelectLayer(uint32_t LayerIndex)
|
||
{
|
||
ActiveLayer = LayerIndex;
|
||
}
|
||
|
||
/**
|
||
* @brief 设置LCD层的可视化
|
||
* @param LayerIndex: 前景层(层1)或者背景层(层0)
|
||
* @param State: 禁能或者使能
|
||
* @retval 无
|
||
*/
|
||
void LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState State)
|
||
{
|
||
if(State == ENABLE)
|
||
{
|
||
__HAL_LTDC_LAYER_ENABLE(&Ltdc_Handler, LayerIndex);
|
||
}
|
||
else
|
||
{
|
||
__HAL_LTDC_LAYER_DISABLE(&Ltdc_Handler, LayerIndex);
|
||
}
|
||
__HAL_LTDC_RELOAD_CONFIG(&Ltdc_Handler);
|
||
}
|
||
|
||
/**
|
||
* @brief 设置LCD的透明度常量
|
||
* @param LayerIndex: 前景层(层1)或者背景层(层0)
|
||
* @param Transparency: 透明度,范围(0—255)0为完全透明
|
||
* @retval 无
|
||
*/
|
||
void LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency)
|
||
{
|
||
HAL_LTDC_SetAlpha(&Ltdc_Handler, Transparency, LayerIndex);
|
||
}
|
||
|
||
/**
|
||
* @brief 设置LCD缓冲帧的首地址
|
||
* @param LayerIndex: 前景层(层1)或者背景层(层0)
|
||
* @param Address: LCD缓冲帧的首地址
|
||
* @retval 无
|
||
*/
|
||
void LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address)
|
||
{
|
||
HAL_LTDC_SetAddress(&Ltdc_Handler, Address, LayerIndex);
|
||
}
|
||
|
||
/**
|
||
* @brief 设置显示窗口
|
||
* @param LayerIndex: 前景层(层1)或者背景层(层0)
|
||
* @param Xpos: LCD X轴起始位置
|
||
* @param Ypos: LCD Y轴起始位置
|
||
* @param Width: LCD 窗口大小
|
||
* @param Height: LCD 窗口大小
|
||
* @retval None
|
||
*/
|
||
void LCD_SetLayerWindow(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
|
||
{
|
||
/* 重新设置窗口大小 */
|
||
HAL_LTDC_SetWindowSize(&Ltdc_Handler, Width, Height, LayerIndex);
|
||
|
||
/* 重新设置窗口的起始位置 */
|
||
HAL_LTDC_SetWindowPosition(&Ltdc_Handler, Xpos, Ypos, LayerIndex);
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief 设置LCD当前层文字颜色
|
||
* @param Color: 文字颜色
|
||
* @retval 无
|
||
*/
|
||
void LCD_SetTextColor(uint32_t Color)
|
||
{
|
||
DrawProp[ActiveLayer].TextColor = Color;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取LCD当前层文字颜色
|
||
* @retval 文字颜色
|
||
*/
|
||
uint32_t LCD_GetTextColor(void)
|
||
{
|
||
return DrawProp[ActiveLayer].TextColor;
|
||
}
|
||
|
||
/**
|
||
* @brief 设置LCD当前层的文字背景颜色
|
||
* @param Color: 文字背景颜色
|
||
* @retval 无
|
||
*/
|
||
void LCD_SetBackColor(uint32_t Color)
|
||
{
|
||
DrawProp[ActiveLayer].BackColor = Color;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取LCD当前层的文字背景颜色
|
||
* @retval 文字背景颜色
|
||
*/
|
||
uint32_t LCD_GetBackColor(void)
|
||
{
|
||
return DrawProp[ActiveLayer].BackColor;
|
||
}
|
||
|
||
/**
|
||
* @brief 设置LCD文字的颜色和背景的颜色
|
||
* @param TextColor: 指定文字颜色
|
||
* @param BackColor: 指定背景颜色
|
||
* @retval 无
|
||
*/
|
||
void LCD_SetColors(uint32_t TextColor, uint32_t BackColor)
|
||
{
|
||
LCD_SetTextColor (TextColor);
|
||
LCD_SetBackColor (BackColor);
|
||
}
|
||
/**
|
||
* @brief 设置LCD当前层显示的字体
|
||
* @param fonts: 字体类型
|
||
* @retval None
|
||
*/
|
||
void LCD_SetFont(sFONT *fonts)
|
||
{
|
||
DrawProp[ActiveLayer].pFont = fonts;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取LCD当前层显示的字体
|
||
* @retval 字体类型
|
||
*/
|
||
sFONT *LCD_GetFont(void)
|
||
{
|
||
return DrawProp[ActiveLayer].pFont;
|
||
}
|
||
|
||
/**
|
||
* @brief 读LCD的像素值
|
||
* @param Xpos: X 轴坐标位置
|
||
* @param Ypos: Y 轴坐标位置
|
||
* @retval RGB像素值
|
||
*/
|
||
uint32_t LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos)
|
||
{
|
||
uint32_t ret = 0;
|
||
|
||
if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
|
||
{
|
||
/* 从SDRAM显存中读取颜色数据 */
|
||
ret = *(__IO uint32_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*LCD_GetXSize() + Xpos)));
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
|
||
{
|
||
/* 从SDRAM显存中读取颜色数据 */
|
||
ret = (*(__IO uint8_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (3*(Ypos*LCD_GetXSize() + Xpos))+2) & 0x00FFFFFF);
|
||
ret |= (*(__IO uint8_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (3*(Ypos*LCD_GetXSize() + Xpos))+1) & 0x00FFFFFF);
|
||
ret |= (*(__IO uint8_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (3*(Ypos*LCD_GetXSize() + Xpos))) & 0x00FFFFFF);
|
||
}
|
||
else if((Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_AL88))
|
||
{
|
||
/* 从SDRAM显存中读取颜色数据 */
|
||
ret = *(__IO uint16_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*LCD_GetXSize() + Xpos)));
|
||
}
|
||
else
|
||
{
|
||
/* 从SDRAM显存中读取颜色数据 */
|
||
ret = *(__IO uint8_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*LCD_GetXSize() + Xpos)));
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* @brief LCD当前层清屏
|
||
* @param Color: 背景颜色
|
||
* @retval None
|
||
*/
|
||
void LCD_Clear(uint32_t Color)
|
||
{
|
||
/* 清屏 */
|
||
LL_FillBuffer(ActiveLayer, (uint32_t *)(Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress), LCD_GetXSize(), LCD_GetYSize(), 0, Color);
|
||
}
|
||
|
||
/**
|
||
* @brief 清除一行
|
||
* @param Line: 行
|
||
* @retval None
|
||
*/
|
||
void LCD_ClearLine(uint32_t Line)
|
||
{
|
||
uint32_t color_backup = DrawProp[ActiveLayer].TextColor;
|
||
DrawProp[ActiveLayer].TextColor = DrawProp[ActiveLayer].BackColor;
|
||
|
||
/* 画一个跟背景色一致的矩形完成清除 */
|
||
LCD_FillRect(0, (Line * DrawProp[ActiveLayer].pFont->Height), LCD_GetXSize(), DrawProp[ActiveLayer].pFont->Height);
|
||
|
||
DrawProp[ActiveLayer].TextColor = color_backup;
|
||
LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
|
||
HAL_Delay(1);
|
||
}
|
||
|
||
/**
|
||
* @brief 显示一个字符
|
||
* @param Xpos: X轴起始坐标
|
||
* @param Ypos: Y轴起始坐标
|
||
* @param Ascii: 字符 ascii 码,范围( 0x20 —0x7E )
|
||
* @retval 无
|
||
*/
|
||
void LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii)
|
||
{
|
||
DrawChar(Xpos, Ypos, &DrawProp[ActiveLayer].pFont->table[(Ascii-' ') *\
|
||
DrawProp[ActiveLayer].pFont->Height * ((DrawProp[ActiveLayer].pFont->Width + 7) / 8)]);
|
||
}
|
||
|
||
/**
|
||
* @brief 显示字符串
|
||
* @param Xpos: X轴起始坐标
|
||
* @param Ypos: Y轴起始坐标
|
||
* @param Text: 字符串指针
|
||
* @param Mode: 显示对齐方式,可以是CENTER_MODE、RIGHT_MODE、LEFT_MODE
|
||
* @retval None
|
||
*/
|
||
void LCD_DisplayStringAt(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;
|
||
|
||
/* 获取字符串大小 */
|
||
while (*ptr++) size ++ ;
|
||
|
||
/* 每一行可以显示字符的数量 */
|
||
xsize = (LCD_GetXSize()/DrawProp[ActiveLayer].pFont->Width);
|
||
|
||
switch (Mode)
|
||
{
|
||
case CENTER_MODE:
|
||
{
|
||
ref_column = Xpos + ((xsize - size)* DrawProp[ActiveLayer].pFont->Width) / 2;
|
||
break;
|
||
}
|
||
case LEFT_MODE:
|
||
{
|
||
ref_column = Xpos;
|
||
break;
|
||
}
|
||
case RIGHT_MODE:
|
||
{
|
||
ref_column = - Xpos + ((xsize - size)*DrawProp[ActiveLayer].pFont->Width);
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
ref_column = Xpos;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*检查起始行是否在显示范围内 */
|
||
if ((ref_column < 1) || (ref_column >= 0x8000))
|
||
{
|
||
ref_column = 1;
|
||
}
|
||
|
||
/* 使用字符显示函数显示每一个字符*/
|
||
while ((*Text != 0) & (((LCD_GetXSize() - (i*DrawProp[ActiveLayer].pFont->Width)) & 0xFFFF)\
|
||
>= DrawProp[ActiveLayer].pFont->Width))
|
||
{
|
||
/* 显示一个字符 */
|
||
LCD_DisplayChar(ref_column, Ypos, *Text);
|
||
/* 根据字体大小计算下一个偏移位置 */
|
||
ref_column += DrawProp[ActiveLayer].pFont->Width;
|
||
/* 指针指向下一个字符 */
|
||
Text++;
|
||
i++;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 在指定行显示字符串(最多60个)
|
||
* @param Line: 显示的行
|
||
* @param ptr: 字符串指针
|
||
* @retval 无
|
||
*/
|
||
void LCD_DisplayStringLine(uint16_t Line, uint8_t *ptr)
|
||
{
|
||
LCD_DisplayStringAt(0, LINE(Line), ptr, LEFT_MODE);
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制水平线
|
||
* @param Xpos: X轴起始坐标
|
||
* @param Ypos: Y轴起始坐标
|
||
* @param Length: 线的长度
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
|
||
{
|
||
uint32_t Xaddress = 0;
|
||
|
||
if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
|
||
{
|
||
Xaddress = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 4*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
|
||
{
|
||
Xaddress = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 3*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else if((Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_AL88))
|
||
{
|
||
Xaddress = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else
|
||
{
|
||
Xaddress = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
/* 填充数据 */
|
||
LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, Length, 1, 0, DrawProp[ActiveLayer].TextColor);
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制垂直线
|
||
* @param Xpos: X轴起始坐标
|
||
* @param Ypos: Y轴起始坐标
|
||
* @param Length: 线的长度
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
|
||
{
|
||
uint32_t Xaddress = 0;
|
||
|
||
if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
|
||
{
|
||
Xaddress = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 4*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
|
||
{
|
||
Xaddress = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 3*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else if((Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_AL88))
|
||
{
|
||
Xaddress = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else
|
||
{
|
||
Xaddress = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
|
||
/* 填充数据 */
|
||
LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, 1, Length, (LCD_GetXSize() - 1), DrawProp[ActiveLayer].TextColor);
|
||
}
|
||
|
||
/**
|
||
* @brief 指定两点画一条线
|
||
* @param x1: 第一点X轴坐标
|
||
* @param y1: 第一点Y轴坐标
|
||
* @param x2: 第二点X轴坐标
|
||
* @param y2: 第二点Y轴坐标
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
||
{
|
||
int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
|
||
yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0,
|
||
curpixel = 0;
|
||
|
||
deltax = ABS(x2 - x1); /* 求x轴的绝对值 */
|
||
deltay = ABS(y2 - y1); /* 求y轴的绝对值 */
|
||
x = x1; /* 第一个像素的x坐标起始值 */
|
||
y = y1; /* 第一个像素的y坐标起始值 */
|
||
|
||
if (x2 >= x1) /* x坐标值为递增 */
|
||
{
|
||
xinc1 = 1;
|
||
xinc2 = 1;
|
||
}
|
||
else /* x坐标值为递减 */
|
||
{
|
||
xinc1 = -1;
|
||
xinc2 = -1;
|
||
}
|
||
|
||
if (y2 >= y1) /* y坐标值为递增 */
|
||
{
|
||
yinc1 = 1;
|
||
yinc2 = 1;
|
||
}
|
||
else /* y坐标值为递减 */
|
||
{
|
||
yinc1 = -1;
|
||
yinc2 = -1;
|
||
}
|
||
|
||
if (deltax >= deltay) /* 每个 y 坐标值至少有一个x坐标值*/
|
||
{
|
||
xinc1 = 0; /* 当分子大于或等于分母时不要改变 x */
|
||
yinc2 = 0; /* 不要为每次迭代更改 y */
|
||
den = deltax;
|
||
num = deltax / 2;
|
||
num_add = deltay;
|
||
num_pixels = deltax; /* x比y多的值 */
|
||
}
|
||
else /* 每个 x 坐标值至少有一个y坐标值 */
|
||
{
|
||
xinc2 = 0; /* 不要为每次迭代更改 x */
|
||
yinc1 = 0; /* 当分子大于或等于分母时不要改变 y */
|
||
den = deltay;
|
||
num = deltay / 2;
|
||
num_add = deltax;
|
||
num_pixels = deltay; /* y比x多的值 */
|
||
}
|
||
|
||
for (curpixel = 0; curpixel <= num_pixels; curpixel++)
|
||
{
|
||
LCD_DrawPixel(x, y, DrawProp[ActiveLayer].TextColor); /* 绘制当前像素点 */
|
||
num += num_add; /* 在分数的基础上增加分子 */
|
||
if (num >= den) /* 检查分子大于或等于分母 */
|
||
{
|
||
num -= den; /* 计算新的分子值 */
|
||
x += xinc1; /* x值递增 */
|
||
y += yinc1; /* y值递增 */
|
||
}
|
||
x += xinc2; /* y值递增 */
|
||
y += yinc2; /* y值递增 */
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制一个矩形
|
||
* @param Xpos: X轴坐标
|
||
* @param Ypos: Y轴坐标
|
||
* @param Width: 矩形宽度
|
||
* @param Height: 矩形高度
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
|
||
{
|
||
/* 绘制水平线 */
|
||
LCD_DrawHLine(Xpos, Ypos, Width);
|
||
LCD_DrawHLine(Xpos, (Ypos+ Height), Width);
|
||
|
||
/* 绘制垂直线 */
|
||
LCD_DrawVLine(Xpos, Ypos, Height);
|
||
LCD_DrawVLine((Xpos + Width), Ypos, Height);
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制一个圆形
|
||
* @param Xpos: X轴坐标
|
||
* @param Ypos: Y轴坐标
|
||
* @param Radius: 圆的半径
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
|
||
{
|
||
int32_t decision; /* 决策变量 */
|
||
uint32_t current_x; /* 当前x坐标值 */
|
||
uint32_t current_y; /* 当前y坐标值 */
|
||
|
||
decision = 3 - (Radius << 1);
|
||
current_x = 0;
|
||
current_y = Radius;
|
||
|
||
while (current_x <= current_y)
|
||
{
|
||
LCD_DrawPixel((Xpos + current_x), (Ypos - current_y), DrawProp[ActiveLayer].TextColor);
|
||
|
||
LCD_DrawPixel((Xpos - current_x), (Ypos - current_y), DrawProp[ActiveLayer].TextColor);
|
||
|
||
LCD_DrawPixel((Xpos + current_y), (Ypos - current_x), DrawProp[ActiveLayer].TextColor);
|
||
|
||
LCD_DrawPixel((Xpos - current_y), (Ypos - current_x), DrawProp[ActiveLayer].TextColor);
|
||
|
||
LCD_DrawPixel((Xpos + current_x), (Ypos + current_y), DrawProp[ActiveLayer].TextColor);
|
||
|
||
LCD_DrawPixel((Xpos - current_x), (Ypos + current_y), DrawProp[ActiveLayer].TextColor);
|
||
|
||
LCD_DrawPixel((Xpos + current_y), (Ypos + current_x), DrawProp[ActiveLayer].TextColor);
|
||
|
||
LCD_DrawPixel((Xpos - current_y), (Ypos + current_x), DrawProp[ActiveLayer].TextColor);
|
||
|
||
if (decision < 0)
|
||
{
|
||
decision += (current_x << 2) + 6;
|
||
}
|
||
else
|
||
{
|
||
decision += ((current_x - current_y) << 2) + 10;
|
||
current_y--;
|
||
}
|
||
current_x++;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制一条折线
|
||
* @param Points: 指向点数组的指针
|
||
* @param PointCount: 点数
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawPolygon(pPoint Points, uint16_t PointCount)
|
||
{
|
||
int16_t x = 0, y = 0;
|
||
|
||
if(PointCount < 2)
|
||
{
|
||
return;
|
||
}
|
||
|
||
LCD_DrawLine(Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
|
||
|
||
while(--PointCount)
|
||
{
|
||
x = Points->X;
|
||
y = Points->Y;
|
||
Points++;
|
||
LCD_DrawLine(x, y, Points->X, Points->Y);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制一个椭圆
|
||
* @param Xpos: X轴坐标
|
||
* @param Ypos: Y轴坐标
|
||
* @param XRadius: 椭圆X轴半径
|
||
* @param YRadius: 椭圆Y轴半径
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius)
|
||
{
|
||
int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
|
||
float k = 0, rad1 = 0, rad2 = 0;
|
||
|
||
rad1 = XRadius;
|
||
rad2 = YRadius;
|
||
|
||
k = (float)(rad2/rad1);
|
||
|
||
do {
|
||
LCD_DrawPixel((Xpos-(uint16_t)(x/k)), (Ypos+y), DrawProp[ActiveLayer].TextColor);
|
||
LCD_DrawPixel((Xpos+(uint16_t)(x/k)), (Ypos+y), DrawProp[ActiveLayer].TextColor);
|
||
LCD_DrawPixel((Xpos+(uint16_t)(x/k)), (Ypos-y), DrawProp[ActiveLayer].TextColor);
|
||
LCD_DrawPixel((Xpos-(uint16_t)(x/k)), (Ypos-y), DrawProp[ActiveLayer].TextColor);
|
||
|
||
e2 = err;
|
||
if (e2 <= x) {
|
||
err += ++x*2+1;
|
||
if (-y == x && e2 <= y) e2 = 0;
|
||
}
|
||
if (e2 > y) err += ++y*2+1;
|
||
}
|
||
while (y <= 0);
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制一个点
|
||
* @param Xpos: X轴坐标
|
||
* @param Ypos: Y轴坐标
|
||
* @param RGB_Code: 像素颜色值
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code)
|
||
{
|
||
|
||
if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
|
||
{
|
||
*(__IO uint32_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*LCD_GetXSize() + Xpos))) = RGB_Code;
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
|
||
{
|
||
*(__IO uint8_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (3*(Ypos*LCD_GetXSize() + Xpos))+2) = 0xFF&(RGB_Code>>16);
|
||
*(__IO uint8_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (3*(Ypos*LCD_GetXSize() + Xpos))+1) = 0xFF&(RGB_Code>>8);
|
||
*(__IO uint8_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (3*(Ypos*LCD_GetXSize() + Xpos))) = 0xFF&RGB_Code;
|
||
}
|
||
else if((Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_AL88))
|
||
{
|
||
*(__IO uint16_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*LCD_GetXSize() + Xpos))) = (uint16_t)RGB_Code;
|
||
}
|
||
else
|
||
{
|
||
*(__IO uint16_t*) (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*LCD_GetXSize() + Xpos))) = (uint16_t)RGB_Code;
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制一幅从内部flash加载的ARGB888(32 bits per pixel)格式的图片
|
||
* @param Xpos: Bmp在液晶上X 轴坐标
|
||
* @param Ypos: Bmp在液晶上Y 轴坐标
|
||
* @param pbmp: 指针指向存在内部flash的Bmp图片的首地址
|
||
* @retval 无
|
||
*/
|
||
void LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp)
|
||
{
|
||
uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
|
||
uint32_t address;
|
||
uint32_t input_color_mode = 0;
|
||
|
||
/* 获取位图数据的基地址 */
|
||
index = *(__IO uint16_t *) (pbmp + 10);
|
||
index |= (*(__IO uint16_t *) (pbmp + 12)) << 16;
|
||
|
||
/* 获取位图宽度 */
|
||
width = *(uint16_t *) (pbmp + 18);
|
||
width |= (*(uint16_t *) (pbmp + 20)) << 16;
|
||
|
||
/* 获取位图高度 */
|
||
height = *(uint16_t *) (pbmp + 22);
|
||
height |= (*(uint16_t *) (pbmp + 24)) << 16;
|
||
|
||
/* 获取像素个数 */
|
||
bit_pixel = *(uint16_t *) (pbmp + 28);
|
||
|
||
/* 设定地址 */
|
||
address = Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress + (((LCD_GetXSize()*Ypos) + Xpos)*(4));
|
||
|
||
/*判断层输入像素格式 */
|
||
if ((bit_pixel/8) == 4)
|
||
{
|
||
input_color_mode = DMA2D_INPUT_ARGB8888;
|
||
}
|
||
else if ((bit_pixel/8) == 2)
|
||
{
|
||
input_color_mode = DMA2D_INPUT_RGB565;
|
||
}
|
||
else
|
||
{
|
||
input_color_mode = DMA2D_INPUT_RGB888;
|
||
}
|
||
|
||
/* 绕过位图的帧头 */
|
||
pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
|
||
|
||
/* 将图片转换为 ARGB8888 像素格式 */
|
||
for(index=0; index < height; index++)
|
||
{
|
||
/* 像素格式转换 */
|
||
LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)address, width,input_color_mode);
|
||
|
||
/* 递增源和目标缓冲区 */
|
||
address+= (LCD_GetXSize()*4);
|
||
pbmp -= width*(bit_pixel/8);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 填充一个实心矩形
|
||
* @param Xpos: X坐标值
|
||
* @param Ypos: Y坐标值
|
||
* @param Width: 矩形宽度
|
||
* @param Height: 矩形高度
|
||
* @retval 无
|
||
*/
|
||
void LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
|
||
{
|
||
uint32_t x_address = 0;
|
||
|
||
/* 设置文字颜色 */
|
||
LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
|
||
|
||
/* 设置矩形开始地址 */
|
||
if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
|
||
{
|
||
x_address = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 4*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
|
||
{
|
||
x_address = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 3*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else if((Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
|
||
(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_AL88))
|
||
{
|
||
x_address = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
else
|
||
{
|
||
x_address = (Ltdc_Handler.LayerCfg[ActiveLayer].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
|
||
}
|
||
/* 填充矩形 */
|
||
LL_FillBuffer(ActiveLayer, (uint32_t *)x_address, Width, Height, (LCD_GetXSize() - Width), DrawProp[ActiveLayer].TextColor);
|
||
}
|
||
|
||
/**
|
||
* @brief 填充一个实心圆
|
||
* @param Xpos: X坐标值
|
||
* @param Ypos: Y坐标值
|
||
* @param Radius: 圆的半径
|
||
* @retval 无
|
||
*/
|
||
void LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
|
||
{
|
||
int32_t decision; /* 决策变量 */
|
||
uint32_t current_x; /* 当前x坐标值 */
|
||
uint32_t current_y; /* 当前y坐标值 */
|
||
|
||
decision = 3 - (Radius << 1);
|
||
|
||
current_x = 0;
|
||
current_y = Radius;
|
||
|
||
LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
|
||
|
||
while (current_x <= current_y)
|
||
{
|
||
if(current_y > 0)
|
||
{
|
||
LCD_DrawHLine(Xpos - current_y, Ypos + current_x, 2*current_y);
|
||
LCD_DrawHLine(Xpos - current_y, Ypos - current_x, 2*current_y);
|
||
}
|
||
|
||
if(current_x > 0)
|
||
{
|
||
LCD_DrawHLine(Xpos - current_x, Ypos - current_y, 2*current_x);
|
||
LCD_DrawHLine(Xpos - current_x, Ypos + current_y, 2*current_x);
|
||
}
|
||
if (decision < 0)
|
||
{
|
||
decision += (current_x << 2) + 6;
|
||
}
|
||
else
|
||
{
|
||
decision += ((current_x - current_y) << 2) + 10;
|
||
current_y--;
|
||
}
|
||
current_x++;
|
||
}
|
||
|
||
LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
|
||
LCD_DrawCircle(Xpos, Ypos, Radius);
|
||
}
|
||
|
||
/**
|
||
* @brief 绘制多边形
|
||
* @param Points: 指向点数组的指针
|
||
* @param PointCount: 点数
|
||
* @retval 无
|
||
*/
|
||
void LCD_FillPolygon(pPoint Points, uint16_t PointCount)
|
||
{
|
||
int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0;
|
||
uint16_t image_left = 0, image_right = 0, image_top = 0, image_bottom = 0;
|
||
|
||
image_left = image_right = Points->X;
|
||
image_top= image_bottom = Points->Y;
|
||
|
||
for(counter = 1; counter < PointCount; counter++)
|
||
{
|
||
pixelX = POLY_X(counter);
|
||
if(pixelX < image_left)
|
||
{
|
||
image_left = pixelX;
|
||
}
|
||
if(pixelX > image_right)
|
||
{
|
||
image_right = pixelX;
|
||
}
|
||
|
||
pixelY = POLY_Y(counter);
|
||
if(pixelY < image_top)
|
||
{
|
||
image_top = pixelY;
|
||
}
|
||
if(pixelY > image_bottom)
|
||
{
|
||
image_bottom = pixelY;
|
||
}
|
||
}
|
||
|
||
if(PointCount < 2)
|
||
{
|
||
return;
|
||
}
|
||
|
||
X_center = (image_left + image_right)/2;
|
||
Y_center = (image_bottom + image_top)/2;
|
||
|
||
X_first = Points->X;
|
||
Y_first = Points->Y;
|
||
|
||
while(--PointCount)
|
||
{
|
||
X = Points->X;
|
||
Y = Points->Y;
|
||
Points++;
|
||
X2 = Points->X;
|
||
Y2 = Points->Y;
|
||
|
||
FillTriangle(X, X2, X_center, Y, Y2, Y_center);
|
||
FillTriangle(X, X_center, X2, Y, Y_center, Y2);
|
||
FillTriangle(X_center, X2, X, Y_center, Y2, Y);
|
||
}
|
||
|
||
FillTriangle(X_first, X2, X_center, Y_first, Y2, Y_center);
|
||
FillTriangle(X_first, X_center, X2, Y_first, Y_center, Y2);
|
||
FillTriangle(X_center, X2, X_first, Y_center, Y2, Y_first);
|
||
}
|
||
|
||
/**
|
||
* @brief 填充一个实心椭圆
|
||
* @param Xpos: X轴坐标
|
||
* @param Ypos: Y轴坐标
|
||
* @param XRadius: 椭圆X轴半径
|
||
* @param YRadius: 椭圆Y轴半径
|
||
* @retval 无
|
||
*/
|
||
void LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius)
|
||
{
|
||
int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
|
||
float k = 0, rad1 = 0, rad2 = 0;
|
||
|
||
rad1 = XRadius;
|
||
rad2 = YRadius;
|
||
|
||
k = (float)(rad2/rad1);
|
||
|
||
do
|
||
{
|
||
LCD_DrawHLine((Xpos-(uint16_t)(x/k)), (Ypos+y), (2*(uint16_t)(x/k) + 1));
|
||
LCD_DrawHLine((Xpos-(uint16_t)(x/k)), (Ypos-y), (2*(uint16_t)(x/k) + 1));
|
||
|
||
e2 = err;
|
||
if (e2 <= x)
|
||
{
|
||
err += ++x*2+1;
|
||
if (-y == x && e2 <= y) e2 = 0;
|
||
}
|
||
if (e2 > y) err += ++y*2+1;
|
||
}
|
||
while (y <= 0);
|
||
}
|
||
|
||
/**
|
||
* @brief 使能显示
|
||
* @retval 无
|
||
*/
|
||
void LCD_DisplayOn(void)
|
||
{
|
||
/* 开显示 */
|
||
__HAL_LTDC_ENABLE(&Ltdc_Handler);
|
||
HAL_GPIO_WritePin(LTDC_BL_GPIO_PORT, LTDC_BL_GPIO_PIN, GPIO_PIN_SET); /* 开背光*/
|
||
}
|
||
|
||
/**
|
||
* @brief 禁能显示
|
||
* @retval 无
|
||
*/
|
||
void LCD_DisplayOff(void)
|
||
{
|
||
/* 关显示 */
|
||
__HAL_LTDC_DISABLE(&Ltdc_Handler);
|
||
HAL_GPIO_WritePin(LTDC_BL_GPIO_PORT, LTDC_BL_GPIO_PIN, GPIO_PIN_RESET);/*关背光*/
|
||
}
|
||
|
||
|
||
/*******************************************************************************
|
||
局部函数
|
||
*******************************************************************************/
|
||
|
||
/**
|
||
* @brief 显示一个字符
|
||
* @param Xpos: 显示字符的行位置
|
||
* @param Ypos: 列起始位置
|
||
* @param c: 指向字体数据的指针
|
||
* @retval 无
|
||
*/
|
||
static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c)
|
||
{
|
||
uint32_t i = 0, j = 0;
|
||
uint16_t height, width;
|
||
uint8_t offset;
|
||
uint8_t *pchar;
|
||
uint32_t line;
|
||
|
||
height = DrawProp[ActiveLayer].pFont->Height;//获取正在使用字体高度
|
||
width = DrawProp[ActiveLayer].pFont->Width; //获取正在使用字体宽度
|
||
|
||
offset = 8 *((width + 7)/8) - width ;//计算字符的每一行像素的偏移值,实际存储大小-字体宽度
|
||
|
||
for(i = 0; i < height; i++)//遍历字体高度绘点
|
||
{
|
||
pchar = ((uint8_t *)c + (width + 7)/8 * i);//计算字符的每一行像素的偏移地址
|
||
|
||
switch(((width + 7)/8))//根据字体宽度来提取不同字体的实际像素值
|
||
{
|
||
|
||
case 1:
|
||
line = pchar[0]; //提取字体宽度小于8的字符的像素值
|
||
break;
|
||
|
||
case 2:
|
||
line = (pchar[0]<< 8) | pchar[1]; //提取字体宽度大于8小于16的字符的像素值
|
||
break;
|
||
|
||
case 3:
|
||
default:
|
||
line = (pchar[0]<< 16) | (pchar[1]<< 8) | pchar[2]; //提取字体宽度大于16小于24的字符的像素值
|
||
break;
|
||
}
|
||
|
||
for (j = 0; j < width; j++)//遍历字体宽度绘点
|
||
{
|
||
if(line & (1 << (width- j + offset- 1))) //根据每一行的像素值及偏移位置按照当前字体颜色进行绘点
|
||
{
|
||
LCD_DrawPixel((Xpos + j), Ypos, DrawProp[ActiveLayer].TextColor);
|
||
}
|
||
else//如果这一行没有字体像素则按照背景颜色绘点
|
||
{
|
||
LCD_DrawPixel((Xpos + j), Ypos, DrawProp[ActiveLayer].BackColor);
|
||
}
|
||
}
|
||
Ypos++;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 填充三角形(基于三点)
|
||
* @param x1: 第一点的X坐标值
|
||
* @param y1: 第一点的Y坐标值
|
||
* @param x2: 第二点的X坐标值
|
||
* @param y2: 第二点的Y坐标值
|
||
* @param x3: 第三点的X坐标值
|
||
* @param y3: 第三点的Y坐标值
|
||
* @retval 无
|
||
*/
|
||
static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3)
|
||
{
|
||
int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
|
||
yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0,
|
||
curpixel = 0;
|
||
|
||
deltax = ABS(x2 - x1); /* 求x轴的绝对值 */
|
||
deltay = ABS(y2 - y1); /* 求y轴的绝对值 */
|
||
x = x1; /* 第一个像素的x坐标起始值 */
|
||
y = y1; /* 第一个像素的y坐标起始值 */
|
||
|
||
if (x2 >= x1) /* x坐标值为递增*/
|
||
{
|
||
xinc1 = 1;
|
||
xinc2 = 1;
|
||
}
|
||
else /* x坐标值为递减 */
|
||
{
|
||
xinc1 = -1;
|
||
xinc2 = -1;
|
||
}
|
||
|
||
if (y2 >= y1) /* y坐标值为递增*/
|
||
{
|
||
yinc1 = 1;
|
||
yinc2 = 1;
|
||
}
|
||
else /* y坐标值为递减 */
|
||
{
|
||
yinc1 = -1;
|
||
yinc2 = -1;
|
||
}
|
||
|
||
if (deltax >= deltay) /* 每个 y 坐标值至少有一个x坐标值*/
|
||
{
|
||
xinc1 = 0; /* 当分子大于或等于分母时不要改变 x */
|
||
yinc2 = 0; /* 不要为每次迭代更改 y */
|
||
den = deltax;
|
||
num = deltax / 2;
|
||
num_add = deltay;
|
||
num_pixels = deltax; /* x比y多的值 */
|
||
}
|
||
else /* 每个 x 坐标值至少有一个y坐标值 */
|
||
{
|
||
xinc2 = 0; /* 不要为每次迭代更改 x */
|
||
yinc1 = 0; /* 当分子大于或等于分母时不要改变 y */
|
||
den = deltay;
|
||
num = deltay / 2;
|
||
num_add = deltax;
|
||
num_pixels = deltay; /* y比x多的值 */
|
||
}
|
||
|
||
for (curpixel = 0; curpixel <= num_pixels; curpixel++)
|
||
{
|
||
LCD_DrawLine(x, y, x3, y3);
|
||
|
||
num += num_add; /* 在分数的基础上增加分子 */
|
||
if (num >= den) /* 判断分子是否大于或等于分母 */
|
||
{
|
||
num -= den; /* 计算新的分子值 */
|
||
x += xinc1; /* x值递增 */
|
||
y += yinc1; /* y值递增 */
|
||
}
|
||
x += xinc2; /* x值递增 */
|
||
y += yinc2; /* y值递增 */
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 填充一个缓冲区
|
||
* @param LayerIndex: 当前层
|
||
* @param pDst: 指向目标缓冲区指针
|
||
* @param xSize: 缓冲区宽度
|
||
* @param ySize: 缓冲区高度
|
||
* @param OffLine: 偏移量
|
||
* @param ColorIndex: 当前颜色
|
||
* @retval None
|
||
*/
|
||
static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex)
|
||
{
|
||
|
||
Dma2d_Handler.Init.Mode = DMA2D_R2M;
|
||
if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565)
|
||
{
|
||
Dma2d_Handler.Init.ColorMode = DMA2D_OUTPUT_RGB565;
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
|
||
{
|
||
Dma2d_Handler.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
|
||
{
|
||
Dma2d_Handler.Init.ColorMode = DMA2D_OUTPUT_RGB888;
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB1555)
|
||
{
|
||
Dma2d_Handler.Init.ColorMode = DMA2D_OUTPUT_ARGB1555;
|
||
}
|
||
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444)
|
||
{
|
||
Dma2d_Handler.Init.ColorMode = DMA2D_OUTPUT_ARGB4444;
|
||
}
|
||
Dma2d_Handler.Init.OutputOffset = OffLine;
|
||
|
||
Dma2d_Handler.Instance = DMA2D;
|
||
|
||
/* DMA2D 初始化 */
|
||
if(HAL_DMA2D_Init(&Dma2d_Handler) == HAL_OK)
|
||
{
|
||
if(HAL_DMA2D_ConfigLayer(&Dma2d_Handler, LayerIndex) == HAL_OK)
|
||
{
|
||
if (HAL_DMA2D_Start(&Dma2d_Handler, ColorIndex, (uint32_t)pDst, xSize, ySize) == HAL_OK)
|
||
{
|
||
/* DMA轮询传输 */
|
||
HAL_DMA2D_PollForTransfer(&Dma2d_Handler, 10);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 转换一行为ARGB8888像素格式
|
||
* @param pSrc: 指向源缓冲区的指针
|
||
* @param pDst: 输出颜色
|
||
* @param xSize: 缓冲区宽度
|
||
* @param ColorMode: 输入颜色模式
|
||
* @retval 无
|
||
*/
|
||
static void LL_ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode)
|
||
{
|
||
/* 配置DMA2D模式,颜色模式和输出偏移 */
|
||
Dma2d_Handler.Init.Mode = DMA2D_M2M_PFC;
|
||
Dma2d_Handler.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
|
||
Dma2d_Handler.Init.OutputOffset = 0;
|
||
|
||
/* Foreground Configuration */
|
||
Dma2d_Handler.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
|
||
Dma2d_Handler.LayerCfg[1].InputAlpha = 0xFF;
|
||
Dma2d_Handler.LayerCfg[1].InputColorMode = ColorMode;
|
||
Dma2d_Handler.LayerCfg[1].InputOffset = 0;
|
||
|
||
Dma2d_Handler.Instance = DMA2D;
|
||
|
||
/* DMA2D 初始化 */
|
||
if(HAL_DMA2D_Init(&Dma2d_Handler) == HAL_OK)
|
||
{
|
||
if(HAL_DMA2D_ConfigLayer(&Dma2d_Handler, 1) == HAL_OK)
|
||
{
|
||
if (HAL_DMA2D_Start(&Dma2d_Handler, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == HAL_OK)
|
||
{
|
||
/* DMA轮询传输*/
|
||
HAL_DMA2D_PollForTransfer(&Dma2d_Handler, 10);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|