使用STM32CubeMX進行STM32F429 LCD編程層配置

一.配置重載
所有層的寄存器均執行影子操作。一旦對某個寄存器執行寫操作,便不應在重載完成前再次進行修改。
因此,如果在尚未重載時對同一寄存器執行新的寫操作,則將覆蓋之前的配置。
該控制通過配置寄存器SRCR來完成。
在HAL_LTDC_ConfigLayer(stm32f4xx_hal_ltdc.c中)函數中有:
/* Set the Immediate Reload type */
hltdc->Instance->SRCR = LTDC_SRCR_IMR;
或使用宏:
__HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc);

二.層和層混合
最多可單獨使能、禁止和配置兩個層。層顯示順序固定,即自下而上。如果使能兩個層,則層2爲頂部顯示窗口。

層混合
混合操作始終有效,兩層可按照 LTDC_LxBFCR 寄存器中配置的混合係數進行混合。
混合順序固定,即由下至上。如果使能了兩層,首先第 1 層將與背景色混合,隨後第 2 層與第 1 層和背景的混合顏色結果再次混合。
請參見下圖。

所以層1(layer 0)爲背景層,層2(layer 1) 爲前景層。
#define LCD_BACKGROUND_LAYER     0x0000
#define LCD_FOREGROUND_LAYER     0x0001
當使用1024x768分辨率的液晶時,最好只使用一層,即上述的第1層,否則,當使用2層時,只能顯示靜態的畫面,動態刷新就會閃爍。
因爲每一層都佔用一個SDRAM緩衝區,當液晶分辨率過大時,所需要刷新的緩衝區(從SDRAM到LCD)的數據量就越大。當使用2層時,刷新的數據量翻倍。
LTDC會始終在兩層間執行混合操作,即便其中一層禁止也是如此(即使使用控制寄存器禁止了某層)。

三.層窗口
可爲每個層定位和調整大小,各個層必須位於有效顯示區域內。
窗口位置和大小通過左上和右下的 X/Y 位置以及包含同步、後沿大小和有效數據區域的內部時序發生器配置。請參見 LTDC_LxWHPCR 和 LTDC_WVPCR 寄存器。
可編程層位置和大小定義了一行中的第一個/最後一個可見像素和窗口中的第一個/最後一個可見行。它允許顯示完整的圖像幀,也允許只顯示圖像幀的一部分。
請參見圖 83。
· 層中的第一個和最後一個可見像素通過配置 LTDC_LxWHPCR 寄存器中的 WHSTPOS[11:0]和 WHSPPOS[11:0] 進行設置。
· 層中的第一個和最後一個可見行通過配置 LTDC_LxWVPCR 寄存器中的 WHSTPOS[11:0]和 WHSPPOS[11:0] 進行設置。


相關配置寄存器LTDC_LxWHPCR
LTDC Layerx Window Horizontal Position Configuration Register
LTDC 第 x 層窗口水平位置配置寄存器 (LTDC_LxWHPCR)(其中 x=1..2)
此寄存器定義第 1 層或第 2 層窗口的水平位置(第一個和最後一個像素)。
一行的第一個可見像素是在 LTDC_BPCR 寄存器中編程的 AHBP[10:0] bits + 1 的值。
一行的最後一個可見像素是在 LTDC_AWCR 寄存器中編程的 AAW[10:0] bits 的值。此範圍內的所有值均爲允許值。
如在上面的LCD同步時序配置中,將AHBP[10:0] bits設定爲6(HSW + HBP- 1:6 + 1 - 1),那麼
此處的LTDC_LxWHPCR寄存器一行的第一個可見像素的值就爲6 +1= 7。
其他同此。
再次引用圖82:

窗口要定義在上圖中的有效顯示區域內。
從上圖可以清楚的看出,一行的第一個有效顯示像素座標爲HSYNC(HSW) + HBP,下面的代碼描述了它們之間的關係:
/*代碼見STM32CubeMX代碼倉庫中STM32F429I-Discovery下的LCD示例代碼*/
/* 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=HBP+HSW;
LTDC_Layer_InitStruct.LTDC_HorizontalStop =HSW+HBP+LCD_PIXEL_WIDTH-1;
LTDC_Layer_InitStruct.LTDC_VerticalStart  =VBP+VSW;
LTDC_Layer_InitStruct.LTDC_VerticalStop   =VSW+VBP+LCD_PIXEL_HEIGHT-1;

STM32CubeMX中相關的配置:

生成的代碼如下:
pLayerCfg.WindowX0=7;
pLayerCfg.WindowX1=1030;
pLayerCfg.WindowY0=7;
pLayerCfg.WindowY1=774;   
...
if(HAL_LTDC_Init(&hltdc)!=HAL_OK)
{
    _Error_Handler(__FILE__,__LINE__);
}

四.默認顏色
注意它和全局配置中的背景色的區別。
背景色是上面圖8.4中的背景層的顏色,這裏的默認顏色是層窗口外的顏色---當層窗口的區域小於顯示窗口時,之外的區域的顏色。
每層可具有 ARGB 格式的默認顏色,該顏色在定義的層窗口外使用或在層禁止時使用。
默認顏色通過 LTDC_LxDCCR 寄存器配置。
始終在兩層間執行混合操作,即便其中一層禁止也是如此。要避免層禁止時顯示默認顏色,需將 LTDC_LxBFCR 寄存器中此層的混合係數設置爲其復位值。

這是針對層的,因爲只有層纔有窗口的概念。
STM32CubeMX生成的相應代碼如下:
//層配置
pLayerCfg.Backcolor.Blue=0;
pLayerCfg.Backcolor.Green=0;
pLayerCfg.Backcolor.Red=0;
if(HAL_LTDC_ConfigLayer(&hltdc,&pLayerCfg,0)!=HAL_OK)
{
    Error_Handler(__FILE__,__LINE__);
}

層禁止和默認顏色
如同時打開了2層,層0和層1,然後禁止層1:
 __HAL_LTDC_LAYER_DISABLE(&hltdc, 1);
__HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc);
層1禁止後,該層的顏色還是會參與到混合的,只是混合時使用的顏色是層默認顏色值(參見層默認顏色說明)。
1.禁止掉層1後,該層還是會參與顏色混合的。
2.禁止掉層1後,該層使用默認顏色來參與顏色混合。
3.要避免層禁止時顯示默認顏色,需將 LTDC_LxBFCR 寄存器中此層的混合係數設置爲其復位值。由於層1是前景層,
  只有 此時纔會顯示層0(除非把層1的alpha值設定爲0).

在LCD層初始化時,沒有初始化層1,此時也是隻使用層0。因爲此時層1相關寄存器的設定值爲其復位值。
見上面3所說,此時會禁止顯示默認顏色。

五. 顏色幀緩衝區長度和顏色幀緩衝區間距
顏色幀緩衝區長度Color Frame Buffer Length
Every layer has a total line length setting for the color frame buffer in bytes and a number of
lines in the frame buffer configurable in the LTDC_LxCFBLR and LTDC_LxCFBLNR
register respectively.
The line length and the number of lines settings are used to stop the prefetching of data to
the layer FIFO at the end of the frame buffer.
• If it is set to less bytes than required, a FIFO underrun interrupt is generated if it has
been previously enabled.
• If it is set to more bytes than actually required, the useless data read from the FIFO is
discarded. The useless data is not displayed.
每層均設置顏色幀緩衝區的總行長(單位爲字節)和行數,二者可分別通過 LTDC_LxCFBLR和 LTDC_LxCFBLNR 寄存器進行配置。
行長和行數的設置用於阻止將數據預取到幀緩衝區末尾的層 FIFO 中。
· 如果設置爲低於所需字節,則會產生 FIFO 下溢中斷(如果之前已使能)。
· 如果設置爲高於實際所需字節,則將丟棄從 FIFO 中讀取的無用數據。無用數據不會顯示。

顏色幀緩衝區間距Color Frame Buffer Pitch
Every layer has a configurable pitch for the color frame buffer, which is the distance between
the start of one line and the beginning of the next line in bytes. It is configured through the
LTDC_LxCFBLR register.
每層的顏色幀緩衝區均具有可配置間距,此間距是一行的開始與下一行開始的距離(以字節爲單位)。
它通過 LTDC_LxCFBLR 寄存器配置。

LTDC_LxCFBLR(LTDC Layerx Color Frame Buffer Length Register)  寄存器
LTDC 第 x 層顏色幀緩衝區長度寄存器

示例:
· 採用 RGB565(每像素 2 個字節)格式且寬度爲 256 像素的幀緩衝區(每行總字節數
爲 256x2=512)需要向此寄存器寫入值 0x02000203(其中,間距 = 行長)。
· 採用 RGB888(每像素 3 個字節)格式且寬度爲 320 像素的幀緩衝區(每行總字節數
爲 320x3=960)需要向此寄存器寫入值 0x03C003C3(其中,間距 = 行長)。

LTDC_LxCFBLNR(LTDC Layerx ColorFrame Buffer Line Number Register )寄存器
LTDC 第 x 層顏色幀緩衝區行數寄存器 (LTDC_LxCFBLNR)(其中 x=1..2)
此寄存器定義顏色幀緩衝區中的行數。
位 10:0 CFBLNBR[10:0]:幀緩衝區行數 (Frame Buffer Line Number)
這些位定義幀緩衝區中高電平有效寬度對應的行數。
注意: 行數和行長設置定義針對每層從每個幀中獲取的數據量。如果配置爲低於所需字節,則會產
生 FIFO 下溢中斷(如果使能)。
另一方面,起始地址和間距設置定義存儲器中每行的正確起始位置。

STM32CubeMX中相關的配置:

STM32CubeMX生成的相應代碼如下:
//層配置
pLayerCfg.ImageWidth=1024;
pLayerCfg.ImageHeight=768;
...
if(HAL_LTDC_ConfigLayer(&hltdc,&pLayerCfg,0)!=HAL_OK)
{
    _Error_Handler(__FILE__,__LINE__);
}

//HAL_LTDC_ConfigLayer-->LTDC_SetConfig 函數內代碼:
if(HAL_LTDC_ConfigLayer(&hltdc,&pLayerCfg,0)!=HAL_OK)
{
    Error_Handler(__FILE__,__LINE__);
}
/* Configure the color frame buffer pitch in byte */
LTDC_LAYER(hltdc,LayerIdx)->CFBLR &=~(LTDC_LxCFBLR_CFBLL|LTDC_LxCFBLR_CFBP);
LTDC_LAYER(hltdc,LayerIdx)->CFBLR =(((pLayerCfg->ImageWidth*tmp)<<16U)|(((pLayerCfg->WindowX1-pLayerCfg->WindowX0)*tmp) +3U));
/* Configure the frame buffer line number */
LTDC_LAYER(hltdc,LayerIdx)->CFBLNR &=~(LTDC_LxCFBLNR_CFBLNBR);
LTDC_LAYER(hltdc,LayerIdx)->CFBLNR =(pLayerCfg->ImageHeight);
/* Enable LTDC_Layer by setting LEN bit */ 
LTDC_LAYER(hltdc,LayerIdx)->CR|=(uint32_t)LTDC_LxCR_LEN;

六. 層混合參數Alpha
alpha其實是一個0-1之間的係數,以百分比表示透明度,0表示完全透明,1表示完全不透明。另外alpha混合基於alpha的取值有不同的算法。
STM32F29 LTDC中使用的通用混合公式爲:
BC = BF1 x C + BF2 x Cs
  • BC = 混合後的顏色
  • BF1 = 混合係數 1
  • C = 當前層顏色
  • BF2 = 混合係數 2
  • Cs = 底層混合後的顏色
上面的Cs是底層混合後的顏色,由於STM32F29 LTDC中的層混合是逐步進行的,即先是第0層和背景層混合,然後是第1層和上面混合後的顏色再次混合,所以,這是是底層混合後的顏色。
BF1和BF2通過寄存器LTDC_LxBFCR來配置,並結合LTDC_LxCACR寄存器完成混合顏色的計算輸出。

LTDC_LxCACR恆定 Alpha 配置寄存器
LTDC Layerx Constant Alpha Configuration Register
此寄存器定義在 alpha 混合中使用的恆定 alpha 值(由硬件實現 255 分頻)。
位 7:0 CONSTA[7:0]:恆定 Alpha (Constant Alpha)
這些位配置混合時使用的恆定 Alpha。恆定 Alpha 由硬件實現 255 分頻。
示例:如果編程的恆定 Alpha 爲 0xFF,則恆定 Alpha 值爲 255/255=1

LTDC 第 x 層混合係數配置寄存器 (LTDC_LxBFCR)(其中 x=1..2)
LTDC Layerx Blending Factors Configuration Register
復位值:0x0000 0607
位 10:8 BF1[2:0]:混合係數 1 (Blending Factor 1)
這些位選擇混合係數 F1,其值及其含義如下:
100:恆定 Alpha
110:像素 Alpha x 恆定 Alpha

位 2:0 BF2[2:0]:混合係數 2 (Blending Factor 2)
這些位選擇混合係數 F2,其值及其含義如下:
101:1-恆定 Alpha 
        即 1減去 Constant Alpha
111:1 -(像素 Alpha x 恆定 Alpha)
        即1 減去 (Pixel Alpha x Constant Alpha) 

上面的恆定Alpha,是在LTDC_LxCACR寄存器中配置的值,
像素Alpha,是像素值中包含的Alpha值,如如ARGB8888格式中,一個像素爲32bits,4字節,最高字節爲Alpha的值。上面所有的計算中的Alpha值,
均表示(配置中的整數值/255)。
如當BF1爲110時,混合係數F1則爲:
(像素中的Alpha整數值 / 255)  x (LTDC_LxCACR恆定 Alpha配置值 / 255)
當BF2爲111時,混合係數F2則爲:
1 - (像素中的Alpha整數值 / 255)  x (LTDC_LxCACR恆定 Alpha配置值 / 255)

示例:僅使能第 1 層,BF1 配置爲恆定 Alpha
BF2 配置爲 1-恆定 Alpha
恆定 Alpha:在 LxCACR 寄存器中編程的恆定 Alpha 爲 240 (0xF0)。因此,恆定 Alpha 值爲
240/255 = 0.94
C:當前層顏色爲 128
Cs:背景色爲 48
第 1 層與背景色混合。
BC = 恆定 Alpha x C + (1 - 恆定 Alpha) x Cs = 0.94 x 128 + (1- 0.94) x 48 = 123。

STM32CubeMX中相關的配置:


STM32CubeMX生成的相應代碼如下:
pLayerCfg.Alpha=255;
pLayerCfg.Alpha0=0;
pLayerCfg.BlendingFactor1=LTDC_BLENDING_FACTOR1_CA;
pLayerCfg.BlendingFactor2=LTDC_BLENDING_FACTOR2_CA;
//HAL_LTDC_ConfigLayer-->LTDC_SetConfig
/* Configure the default color values */
tmp=((uint32_t)(pLayerCfg->Backcolor.Green)<<8U);
tmp1=((uint32_t)(pLayerCfg->Backcolor.Red)<<16U);
tmp2=(pLayerCfg->Alpha0<<24U);
LTDC_LAYER(hltdc,LayerIdx)->DCCR&=~(LTDC_LxDCCR_DCBLUE|LTDC_LxDCCR_DCGREEN|LTDC_LxDCCR_DCRED|LTDC_LxDCCR_DCALPHA);
LTDC_LAYER(hltdc,LayerIdx)->DCCR=(pLayerCfg->Backcolor.Blue|tmp|tmp1|tmp2);
/* Specifies the constant alpha value */
LTDC_LAYER(hltdc,LayerIdx)->CACR&=~(LTDC_LxCACR_CONSTA);
LTDC_LAYER(hltdc,LayerIdx)->CACR=(pLayerCfg->Alpha);
/* Specifies the blending factors */
LTDC_LAYER(hltdc,LayerIdx)->BFCR&=~(LTDC_LxBFCR_BF2|LTDC_LxBFCR_BF1);
LTDC_LAYER(hltdc,LayerIdx)->BFCR=(pLayerCfg->BlendingFactor1|pLayerCfg->BlendingFactor2);

Default Alpha value
默認的Alpha value是針對層的默認顏色來說的,默認顏色在定義的層窗口外使用或在層禁止時使用。
詳見上面第四節默認顏色。
當在窗口外和層禁止時,使用該alpha參數值進行顏色混合,即默認顏色RGB和底層顏色的混合參數。
此時,也應遵循上面的通用混合公式BC = BF1 x C + BF2 x Cs,只是此時BF1、BF2中的參數
恆定 Alpha由此Default Alpha value來取代(STM32F429文檔對此沒有說明)。
在上面第四節默認顏的描述中,有:
要避免層禁止時顯示默認顏色,需將 LTDC_LxBFCR 寄存器中此層的混合係數設置爲其復位值。
而LTDC_LxBFCR的復位值爲0x0000 0607(見上),即此時BF1爲110,BF2爲111,
混合係數F1爲:
BF1(像素中的Alpha整數值 / 255)  x (LTDC_LxCACR恆定 Alpha配置值 / 255)
混合係數F2爲:
1 - (像素中的Alpha整數值 / 255)  x (LTDC_LxCACR恆定 Alpha配置值 / 255)
像素中的Alpha整數值此時應爲0,則F1和F2均爲0.
那麼混合公式BC = BF1 x C + BF2 x Cs
BC = 0.

測試
//液晶全局的背景色爲已經配置爲0,即黑色
//下面是第0層的配置,且只使用了此一層。
pLayerCfg.WindowX0=7;
pLayerCfg.WindowX1=1030;
pLayerCfg.WindowY0=7;
pLayerCfg.WindowY1=774-100; //層窗口,小於有效顯示區域
pLayerCfg.PixelFormat=LTDC_PIXEL_FORMAT_RGB565;
pLayerCfg.Alpha=255;
pLayerCfg.Alpha0=255; //默認顏色中的alpha值,修改此值,層窗口外區域顏色的變化(透明度的變化)
pLayerCfg.BlendingFactor1=LTDC_BLENDING_FACTOR1_PAxCA; //注意此時必須設定爲像素參與F1計算,而此時的像素alpha值就是層默認顏色中的相應值
pLayerCfg.BlendingFactor2=LTDC_BLENDING_FACTOR2_PAxCA;  //注意此時必須設定爲像素參與F1計算,而此時的像素alpha值就是層默認顏色中的相應值
pLayerCfg.FBStartAdress=0xD0000000;
pLayerCfg.ImageWidth=1024;
pLayerCfg.ImageHeight=768-100; //層窗口,小於有效顯示區域
pLayerCfg.Backcolor.Blue=0;
pLayerCfg.Backcolor.Green=0xff;
pLayerCfg.Backcolor.Red=0;

代碼完整的示例下載地址:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章