LTDC/DMA2D——液晶显示

LTDC/DMA2D——液晶显示

1.显示器介绍

常用的显示器有液晶LCD显示器、LED点阵显示器、OLED显示器、CRT显示器。
LED显示器是由LED点阵彩色显示器的点个像素点整合起来,显示整个面板图形,每一个像素点都是由一个LED灯实现RGB显示,所以一般来说,LED显示器体积比较大;
新一代的OLED单个的像素点是由发光二极管显示的,所以它的像素密度比较高;
显示器参数:
分辨率:行像素值×列像素值
色彩深度:每个像素点能表示多少种颜色,一般有位bit表示,单色显示屏只能表示亮、灭两种状态,所以为2bit,一般常见的是16bit、24bit
显示器尺寸:5寸、7寸
点距:两个相邻像素点之间的距离

2.液晶控制原理

(1)显示器由液晶显示面板、电容触摸面板、PCB底板组成。
(2)液晶面板的控制信号

信号名称说明
R[7:0]红色数据
G[7:0]绿色数据
B[7:0]蓝色数据
CLK像素同步时钟信号
HSYNC水平同步信号
VSYNC水平同步信号
DE数据使能信号
DISP液晶屏使能信号
BL液晶屏背光信号

(3)液晶数据传输时序图

(4)显存
在液晶显示中的每个像素点都是数据,实际应用中需要先将大量的数据缓存起来,然后一帧一帧的传输给液晶显示屏,这种存储显示数据的存储器就称为显存。一般最少要存储一帧数据。
例如分辨率为800×480的液晶屏,使用RGB888格式显示(24位),它存储一帧数据的大小为800*480×3=115200字节。

3.LTDC液晶控制器

(1)液晶显示屏支持2层数据的显示,前景层和背景层,在输出时LTDC控制器将两层数据叠加混合为一层数据进行输出。
(2)LTDC结构框图
主要包括信号线、图像处理单元、寄存器、时钟信号,具体设置可以根据需要进行配置

4.DMA2D图形加速器介绍

在使用LTDC控制器控制液晶面板时,LTDC控制器将显存里面缓存的数据搬运到液晶面板时,数据非常大,就想用DMA进行操作,可以提高速度,DMA2D可以快速绘制矩形、直线、分层数据混合、数据复制等,图形绘制的专用的DMA

5.LTDC初始化结构体

如何配置LTDC结构体

/**
  * @brief  初始化控制LCD的IO
  * @param  无
  * @retval 无
  */
static void LCD_GPIO_Config(void)
{		
	
  GPIO_InitTypeDef GPIO_InitStructure;
  
  /* 使能LCD相关的GPIO时钟 */

                         /*RGB信号线*/
  RCC_AHB1PeriphClockCmd(LCD_R0_GPIO_CLK | LCD_R1_GPIO_CLK | LCD_R2_GPIO_CLK | 
                         LCD_R3_GPIO_CLK | LCD_R4_GPIO_CLK | LCD_R5_GPIO_CLK |
                         LCD_R6_GPIO_CLK | LCD_R7_GPIO_CLK | LCD_G0_GPIO_CLK |
                         LCD_G1_GPIO_CLK | LCD_G2_GPIO_CLK | LCD_G3_GPIO_CLK | 
												 LCD_G4_GPIO_CLK | LCD_G5_GPIO_CLK | LCD_G6_GPIO_CLK |
												 LCD_G7_GPIO_CLK | LCD_B0_GPIO_CLK | LCD_B1_GPIO_CLK |
												 LCD_B2_GPIO_CLK | LCD_B3_GPIO_CLK | LCD_B4_GPIO_CLK |
												 LCD_B5_GPIO_CLK | LCD_B6_GPIO_CLK | LCD_B7_GPIO_CLK |
                         /*控制信号线*/
                         LCD_CLK_GPIO_CLK | LCD_HSYNC_GPIO_CLK | LCD_VSYNC_GPIO_CLK | 
                         LCD_DE_GPIO_CLK  | LCD_DISP_GPIO_CLK  | LCD_BL_GPIO_CLK,ENABLE);
                         
  
  /*-- GPIO 配置 --------------------------------------*/

  /* 通用 GPIO 配置 */
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;       //配置为复用功能
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽输出
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;   
  
  
  /*红色数据线GPIO配置*/
  GPIO_InitStructure.GPIO_Pin = LCD_R0_GPIO_PIN; 
  GPIO_Init(LCD_R0_GPIO_PORT, &GPIO_InitStructure);
  GPIO_PinAFConfig(LCD_R0_GPIO_PORT, LCD_R0_PINSOURCE , LCD_R0_AF);
/*中间的数据线省略*/

 //绿色数据线
  GPIO_InitStruct.GPIO_Pin = LTDC_G0_GPIO_PIN;
  GPIO_Init(LTDC_G0_GPIO_PORT, &GPIO_InitStruct);
  GPIO_PinAFConfig(LTDC_G0_GPIO_PORT, LTDC_G0_PINSOURCE, LTDC_G0_AF);
  /*中间的数据线省略*/
  
  //蓝色数据线
  GPIO_InitStruct.GPIO_Pin = LTDC_B0_GPIO_PIN;
  GPIO_Init(LTDC_B0_GPIO_PORT, &GPIO_InitStruct);
  GPIO_PinAFConfig(LTDC_B0_GPIO_PORT, LTDC_B0_PINSOURCE, LTDC_B0_AF);
   //控制信号线
  GPIO_InitStruct.GPIO_Pin = LTDC_CLK_GPIO_PIN;
  GPIO_Init(LTDC_CLK_GPIO_PORT, &GPIO_InitStruct);
  GPIO_PinAFConfig(LTDC_CLK_GPIO_PORT, LTDC_CLK_PINSOURCE, LTDC_CLK_AF);
  
  GPIO_InitStruct.GPIO_Pin = LTDC_HSYNC_GPIO_PIN;
  GPIO_Init(LTDC_HSYNC_GPIO_PORT, &GPIO_InitStruct);
  GPIO_PinAFConfig(LTDC_HSYNC_GPIO_PORT, LTDC_HSYNC_PINSOURCE, LTDC_HSYNC_AF);
  
  GPIO_InitStruct.GPIO_Pin = LTDC_VSYNC_GPIO_PIN;
  GPIO_Init(LTDC_VSYNC_GPIO_PORT, &GPIO_InitStruct);
  GPIO_PinAFConfig(LTDC_VSYNC_GPIO_PORT, LTDC_VSYNC_PINSOURCE, LTDC_VSYNC_AF);
  
  GPIO_InitStruct.GPIO_Pin = LTDC_DE_GPIO_PIN;
  GPIO_Init(LTDC_DE_GPIO_PORT, &GPIO_InitStruct);
  GPIO_PinAFConfig(LTDC_DE_GPIO_PORT, LTDC_DE_PINSOURCE, LTDC_DE_AF);

	  //背光BL及液晶使能信号DISP
  GPIO_InitStruct.GPIO_Pin = LTDC_DISP_GPIO_PIN;                             
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  
  GPIO_Init(LTDC_DISP_GPIO_PORT, &GPIO_InitStruct);
  GPIO_InitStruct.GPIO_Pin = LTDC_BL_GPIO_PIN; 
  GPIO_Init(LTDC_BL_GPIO_PORT, &GPIO_InitStruct);
  
  //拉高使能lcd
  GPIO_SetBits(LTDC_DISP_GPIO_PORT,LTDC_DISP_GPIO_PIN);
  GPIO_SetBits(LTDC_BL_GPIO_PORT,LTDC_BL_GPIO_PIN);	
}

注意其中的背光BL及液晶使能信号DISP/拉高使能lcd 也需要进行初始化配置

6.LTDC层级初始化结构体

可以配合固件库手册对层级结构体进行配置(stm324x9i_eval_lcd.c.)
在这里插入图片描述

 void LCD_Init(void)
 { 
   
   LTDC_InitTypeDef       LTDC_InitStruct;
   LTDC_Layer_TypeDef     LTDC_Layerx;
   
   /* Enable the LTDC Clock */
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_LTDC, ENABLE);
   
   /* Enable the DMA2D Clock */
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2D, ENABLE); 
   
   /* Configure the LCD Control pins */
   LCD_AF_GPIOConfig();  
   
   /* Configure the FMC Parallel interface : SDRAM is used as Frame Buffer for LCD */
   SDRAM_Init();
   
   /* Check if the LCD is AMPIRE480272 or AMPIRE640480 */
   LCD_CheckDevice();
   
   /* Polarity configuration */
   /* Initialize the horizontal synchronization polarity as active low */
   LTDC_InitStruct.LTDC_HSPolarity = LTDC_HSPolarity_AL;     
   /* Initialize the vertical synchronization polarity as active low */  
   LTDC_InitStruct.LTDC_VSPolarity = LTDC_VSPolarity_AL;     
   /* Initialize the data enable polarity as active low */
   LTDC_InitStruct.LTDC_DEPolarity = LTDC_DEPolarity_AL;     
   /* Initialize the pixel clock polarity as input pixel clock */ 
   LTDC_InitStruct.LTDC_PCPolarity = LTDC_PCPolarity_IPC;
   
   /* Configure R,G,B component values for LCD background color */                   
   LTDC_InitStruct.LTDC_BackgroundRedValue = 0;            
   LTDC_InitStruct.LTDC_BackgroundGreenValue = 0;          
   LTDC_InitStruct.LTDC_BackgroundBlueValue = 0;  
   
   /* LCD AMPIRE640480 is used */
   if(CurrentLcd == USE_LCD_AM640480)
   {  
     /* Initialise I2C for touch panel usage */
     LCD_I2C_Config();
     
     /* Initialize the LCD pixel width and pixel height */
     LCD_PIXEL_WIDTH  = 640;
     LCD_PIXEL_HEIGHT = 480;
     
     /* Configure PLLSAI prescalers for LCD */
     /* Enable Pixel Clock */
     /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
     /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAI_N = 192 Mhz */
     /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAI_R = 192/2 = 96 Mhz */
     /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 96/4 = 24 Mhz */
     RCC_PLLSAIConfig(192, 7, 2);
     RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div4);
     
     /* Enable PLLSAI Clock */
     RCC_PLLSAICmd(ENABLE);
     /* Wait for PLLSAI activation */
     while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY) == RESET)
     {
     }
     
     /* Timing configuration */  
     /* Configure horizontal synchronization width */     
     LTDC_InitStruct.LTDC_HorizontalSync = 29;
     /* Configure vertical synchronization height */
     LTDC_InitStruct.LTDC_VerticalSync = 2;
     /* Configure accumulated horizontal back porch */
     LTDC_InitStruct.LTDC_AccumulatedHBP = 143; 
     /* Configure accumulated vertical back porch */
     LTDC_InitStruct.LTDC_AccumulatedVBP = 34;  
     /* Configure accumulated active width */  
     LTDC_InitStruct.LTDC_AccumulatedActiveW = 783;
     /* Configure accumulated active height */
     LTDC_InitStruct.LTDC_AccumulatedActiveH = 514;
     /* Configure total width */
     LTDC_InitStruct.LTDC_TotalWidth = 799; 
     /* Configure total height */
     LTDC_InitStruct.LTDC_TotalHeigh = 524;
     
     LTDC_Init(&LTDC_InitStruct);
   }
   /* LCD AMPIRE480272 is used */
   else if(CurrentLcd == USE_LCD_AM480272)
   {
     /* Initialize the LCD pixel width and pixel height */
     LCD_PIXEL_WIDTH  = 480;
     LCD_PIXEL_HEIGHT = 272;
     
     /* Configure PLLSAI prescalers for LCD */
     /* Enable Pixel Clock */
     /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
     /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAI_N = 192 Mhz */
     /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAI_R = 192/3 = 64 Mhz */
     /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 64/8 = 8 Mhz */
     RCC_PLLSAIConfig(192, 7, 3);
     RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div8);
     
     /* Enable PLLSAI Clock */
     RCC_PLLSAICmd(ENABLE);
     /* Wait for PLLSAI activation */
     while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY) == RESET)
     {
     }
     
     /* Timing configuration */  
     /* Configure horizontal synchronization width */     
     LTDC_InitStruct.LTDC_HorizontalSync = 40;
     /* Configure vertical synchronization height */
     LTDC_InitStruct.LTDC_VerticalSync = 9;
     /* Configure accumulated horizontal back porch */
     LTDC_InitStruct.LTDC_AccumulatedHBP = 42; 
     /* Configure accumulated vertical back porch */
     LTDC_InitStruct.LTDC_AccumulatedVBP = 11;  
     /* Configure accumulated active width */  
     LTDC_InitStruct.LTDC_AccumulatedActiveW = 522;
     /* Configure accumulated active height */
     LTDC_InitStruct.LTDC_AccumulatedActiveH = 283;
     /* Configure total width */
     LTDC_InitStruct.LTDC_TotalWidth = 524; 
     /* Configure total height */
     LTDC_InitStruct.LTDC_TotalHeigh = 285;
     
     LTDC_Init(&LTDC_InitStruct); 
   }
 }

7.DMA2D初始化结构体

这里以使用DMA2D画直线为例,可以在固件库手册里面调用关于LCD_DrawLine()函数,同样固件库里面含有画圆、矩形的函数等等,可以根据需要调用。
在这里插入图片描述

/**
   * @brief  Displays a line.
   * @param Xpos: specifies the X position.
   * @param Ypos: specifies the Y position.
   * @param Length: line length.
   * @param Direction: line direction.
   *   This parameter can be one of the following values: Vertical or Horizontal.
   * @retval None
   */
 void LCD_DrawLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint8_t Direction)
 {
   DMA2D_InitTypeDef      DMA2D_InitStruct;
   
   uint32_t  Xaddress = 0;
   uint16_t Red_Value = 0, Green_Value = 0, Blue_Value = 0;
   
   Xaddress = CurrentFrameBuffer + 2*((LCD_PIXEL_WIDTH*Ypos) + Xpos);
  
   Red_Value = (0xF800 & CurrentTextColor) >> 11;
   Blue_Value = 0x001F & CurrentTextColor;
   Green_Value = (0x07E0 & CurrentTextColor) >> 5;
 
   /* Configure DMA2D */    
   DMA2D_DeInit();  
   DMA2D_InitStruct.DMA2D_Mode = DMA2D_R2M;       
   DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565;      
   DMA2D_InitStruct.DMA2D_OutputGreen = Green_Value;      
   DMA2D_InitStruct.DMA2D_OutputBlue = Blue_Value;     
   DMA2D_InitStruct.DMA2D_OutputRed = Red_Value;                
   DMA2D_InitStruct.DMA2D_OutputAlpha = 0x0F;                  
   DMA2D_InitStruct.DMA2D_OutputMemoryAdd = Xaddress;                  
   
   if(Direction == LCD_DIR_HORIZONTAL)
   {                                                      
     DMA2D_InitStruct.DMA2D_OutputOffset = 0;                
     DMA2D_InitStruct.DMA2D_NumberOfLine = 1;            
     DMA2D_InitStruct.DMA2D_PixelPerLine = Length; 
   }
   else
   {                                                            
     DMA2D_InitStruct.DMA2D_OutputOffset = LCD_PIXEL_WIDTH - 1;                
     DMA2D_InitStruct.DMA2D_NumberOfLine = Length;            
     DMA2D_InitStruct.DMA2D_PixelPerLine = 1;  
   }
   
   DMA2D_Init(&DMA2D_InitStruct);  
   /* Start Transfer */ 
   DMA2D_StartTransfer();  
   /* Wait for CTC Flag activation */
   while(DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET)
   {
   }
   
 }

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值