本文基於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)函數才能使所有層的設置生效。