程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> STM32F429之LTDC驅動圖解

STM32F429之LTDC驅動圖解

編輯:關於C++

本文基於ST官方demo板STM32F429 Discovery硬件平台,以看圖說話的形式給大家講解LTDC的主要參數配置。關於本文提到的代碼部分均摘自本人另一片文章《STM32F429之LTDC代碼模板》,LCD硬件為240x320,驅動IC為ili9341。本文目的意在讓大家通過幾張圖就能掌握STM32F429 LTDC控制器的配置要領,而從干澀的文字中解脫出來,方便記憶。當然本文只是講解了LTDC一些常用的設置,關於更多細節的操作還是得參照ST的官方datasheet。


一、關於LTDC外設的時鐘配置,只需要記住下面這張圖就可以了(圖片來源於STM32CubeMX RCC時鐘樹):

\

該圖所對應的代碼如下:

<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHByZSBjbGFzcz0="brush:java;"> /* Configure PLLSAI prescalers for LCD */ /* 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) { }


二、關於LCD的信號時序配置參數,只需要記住下面這張圖就可以了:

\

注意:這部分需要根據LCD Datasheet要求嚴格配置。

改圖所對應的代碼如下:

  /* 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;
  
  /* Timing configuration */
  /* Configure horizontal synchronization width */     
  LTDC_InitStruct.LTDC_HorizontalSync = 9;
  /* Configure vertical synchronization height */
  LTDC_InitStruct.LTDC_VerticalSync = 1;
  /* Configure accumulated horizontal back porch */
  LTDC_InitStruct.LTDC_AccumulatedHBP = 29; 
  /* Configure accumulated vertical back porch */
  LTDC_InitStruct.LTDC_AccumulatedVBP = 3;  
  /* Configure accumulated active width */  
  LTDC_InitStruct.LTDC_AccumulatedActiveW = 269;
  /* Configure accumulated active height */
  LTDC_InitStruct.LTDC_AccumulatedActiveH = 323;
  /* Configure total width */
  LTDC_InitStruct.LTDC_TotalWidth = 279; 
  /* Configure total height */
  LTDC_InitStruct.LTDC_TotalHeigh = 327;

三、LTDC的層——Layer

關於層的概念有以下幾點:

1. STM32F429共有3個層,分別為Background、Layer1、Layer2,任何時候LCD顯示的圖像都是由層疊加後的最終結果;

2. Background層任何時候都有效,而Layer1、Layer2可以通過軟件配置使能或禁止;

3. 這3個層的空間順序,從下往上依次為Background、Layer1、Layer2,所以疊加的順序如下圖:

\

每個Layer支持窗口(Window)操作,所謂Window,就是指該層的圖像只有在Window區域內有效,而Window區域外則用該層的DefaultColor填充。如下圖:

\


關於Layer Window顯示位置及大小的配置,記住下面這張圖就可以了:

\

該圖所對應的代碼如下:

  /* Windowing configuration */ 
  /* In this case all the active display area is used to display a picture then:
  Horizontal start = horizontal synchronization + Horizontal back porch = 30 
  Horizontal stop = Horizontal start + window width -1 = 30 + 240 -1
  Vertical start   = vertical synchronization + vertical back porch     = 4
  Vertical stop   = Vertical start + window height -1  = 4 + 320 -1      */ 
  LTDC_Layer_InitStruct.LTDC_HorizontalStart = 30;
  LTDC_Layer_InitStruct.LTDC_HorizontalStop = (240 + 30 - 1); 
  LTDC_Layer_InitStruct.LTDC_VerticalStart = 4;
  LTDC_Layer_InitStruct.LTDC_VerticalStop = 320 + 4 -1; 


每個Layer關聯了一個顯示緩沖區FrameBuffer,由於Background只能使用單色填充,所以它沒有FrameBuffer。關於FrameBuffer有幾個參數:Pixel Format、Buffer Address、Line Length、Number of lines、Buffer Pitch,這幾個參數都是針對於Layer的Window而言的,它們的含義如下:

Pixel Format:不多說,RGB565、ARGB8888、ARGB1555等等;

Buffer Address:顯示緩沖區的起始地址;

Line Length:window所對應的緩沖區寬度+3,以字節為單位;

Number of Lines:window所對應的緩沖區高度,以字節為單位;

Buffer Pitch:從這一行起始到下一行起始所經過的字節數,說白了就是換行時的一個行指針增量(也可以理解為整幅圖像的寬度,以字節為單位);


假設Layer1的FrameBuffer如下圖(RGB565):

\

設置window要顯示的圖像為下圖粉色部分:

\

結合之前設置的Window的位置,最終顯示的圖像如下圖(不考慮Layer2及透明色):

\

由此可以看到:

Start Address、Buffer Pitch決定了window在顯存中每行的起始位置;

Line Length、Line Number決定了window在顯存中的大小。

該部分所對應的代碼如下:

  /* Input Address configuration */    
  LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (u32)FrameBuffer;
  
  /* the length of one line of pixels in bytes + 3 then :
  Line Lenth = Active high width x number of bytes per pixel + 3 
  Active high width         = 240 
  number of bytes per pixel = 2    (pixel_format : RGB565) 
  */
  LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((240 * 2) + 3);
  
  /*  the pitch is the increment from the start of one line of pixels to the 
  start of the next line in bytes, then :
  Pitch = Active high width x number of bytes per pixel     
  */
  LTDC_Layer_InitStruct.LTDC_CFBPitch = (240 * 2);  
  
  /* configure the number of lines */
  LTDC_Layer_InitStruct.LTDC_CFBLineNumber = 320;


需要注意的是,為了保證圖像能正確顯示,請務必確認顯存中圖像的大小與window顯示的大小一致,即Line Length、Line Number要與(HStop-HStart)、(VStop-VStart)相一致,否則顯示將不正確。

最後不要忘了設置完所有Layer的寄存器後,光調用LTDC_LayerCmd()還不夠,還需要調用LTDC_ReloadConfig(ENABLE)函數才能使所有層的設置生效。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved