【LTDC】LTDC 相關寄存器
引言
此篇文章僅作筆記分享,內容來源為:
這篇文章就是為了了解 LTDC 其中的寄存器,以至于移植什么的更加清晰明了。
注意事項
- RGBLCD 其實也是 TFTLCD,只是接口不同。
- 控制 B7、G7、R7 引腳可以分辨 LCD 的模塊 ID,例如:100 為 4.3 寸,800 * 480 分辨率 LCD。
- LTDC 是 STM32H7 的 TFTLCD 控制器。
- LTDC 控制器主要包含:信號線、圖像處理單元、 AHB接口、配置和狀態寄存器以及時鐘部分,其框圖如圖。
- LTDC 有 24 位并行像素輸出,每個像素8位數據(RGB888),但是為了節省 IO,提高速度,一般只用 RGB565,只需要16個 IO 口。
即:LCD_R[7:3]、LCD_G[7:2]、LCD_B[7:3]。 - 一個像素需要2個字節的內存,一般的 16 位 RGB565 模式,800 * 480 的屏幕,則需要 800 * 480 * 2 = 768 KB,故要使用到外部SDRAM,
而 SDRAM 是掛載在 AHB 總線上的,LTDC 的AHB 總線的功能就是將顯存數據從 SDRAM 存儲器傳輸到 FIFO 中。 - 對于 LTDC 控制器來說,屏幕的顯示區域被稱作為有效顯示范圍,即分辨率。其中一些無效顯示范圍包括以下部分:

寄存器
全局控制寄存器 LTDC_GCR (極性控制)

- LTDCEN TFT LCD: 控制器使能位,也就是 LTDC 的開關,該位需要設置為 1。
- PCPOL: 像素時鐘極性。控制像素時鐘的極性,根據 LCD 面板的特性來設置,我們所用的 LCD 一般設置為 0 即可,表示低電平有效。
- DEPOL: 數據使能極性。控制 DE 信號的極性,根據 LCD 面板的特性來設置,我們所用的 LCD 一般設置為 0 即可,表示低電平有效。
- VSPOL: 垂直同步極性。控制 VSYNC 信號的極性,根據 LCD 面板的特性來設置,我們所用的 LCD 一般設置為 0 即可,表示低電平有效。
- HSPOL: 水平同步極性。控制 HSYNC 信號的極性,根據 LCD 面板的特性來設置,我們所用的 LCD 一般設置為 0 即可,表示低電平有效。
同步大小配置寄存器 LTDC_SSCR

- VSH: 表示垂直同步高度(以水平掃描行為單位),表示垂直同步脈寬減 1 ,即 VSW-1。
- HSW: 表示水平同步寬度(以像素時鐘為單位),表示 水平同步脈寬減 1,即 HSW-1。
后沿配置寄存器 LTDC_BPCR

- AVBP: 加垂直后沿(以水平掃描行為單位),表示: VSW+VBP-1。
- AHBP:累加水平后沿(以像素時鐘為單位),表示 HSW+HBP-1,下同。
有效寬度配置寄存器 LTDC_AWCR

-
AAH: 累加有效高度(以水平掃描行為單位),表示: VSW+VBP+有效高度 -1。
-
AAW: 累加有效寬度(以像素時鐘為單位),表示: HSW+HBP+有效寬度 -1。
這里所說的有效高度和有效寬度,是指LCD 面板的寬度和高度(構成分辨率,下同)
總寬度配置寄存器 LTDC_TWCR

- TOTALH: 總高度(以水平掃描行為單位),表示: VSW+VBP+有效高度 +VFP-1。
- TOTALW: 總寬度(以像素時鐘為單位),表示: HSW+HBP+有效寬度 +HFP-1。
背景色配置寄存器 LTDC_BCC

該寄存器定義背景層的顏色(RGB888),通過低 24 位配置,我們一般設置為全 0 即可。
層顏色幀緩沖區地址寄存器 LTDC_LxCFBAR(x=1/2)

該寄存器用來定義一層顯存的起始地址。STM32H743的 LTDC支持 2個層,所以總共兩個寄存器,分別設置層 1和層 2的顯存起始地址。
層像素格式配置寄存器 LTDC_LxPFCR(x=1/2)

該寄存器只有最低 3位有效,用于設置層顏色的像素格式:
000: ARGB8888
001: RGB888
010: RGB565
011: ARGB1555
100: ARGB4444
101: L8(8位 Luminance)
110: AL44(4位 Alpha 4位 Luminance)
111: AL88 (8位 Alpha 8位 Luminance)
我們一般使用 RGB565 格式,即該寄存器設置為: 010 即可。
層恒定 Alpha配置寄存器 LTDC_LxCACR(x=1/2)

該寄存器低 8 位(CONSTA)有效,這些位配置混合時使用的恒定 Alpha。恒定 Alpha 由硬件實現 255分頻。關于這個恒定 Alpha 的使用,我們將在介紹 LTDC_LxBFCR 寄存器的時候進行講解。
層默認顏色配置寄存器 LTDC_LxDCCR(x=1/2)

該寄存器定義采用 ARGB8888 格式的層的默認顏色。默認顏色在定義的層窗口外使用或在層禁止時使用。一般情況下,用不到,所以該寄存器一般設置為 0即可。
層混合系數配置寄存器 LTDC_LxBFCR(x=1/2)

該寄存器用于定義混合系數:BF1 和 BF2。
BF1 = 100: 使用恒定 Alpha混合系數(由 LTDC_LxCACR寄存器設置恒定 Alpha 值)
BF1 = 110: 使用像素 Alpha * 恒定 Alpha。像素 Alpha即 ARGB格式像素的 A值( Alpha值),僅限ARGB顏色格式時使用。
顏色格式時使用。在 RGB565格式下,我們設置 BF1 = 100 即可。
BF2 同 BF1類似。
BF2 = 101: 使用恒定 Alpha混合系數。
BF2 = 111: 使用像素 Alpha*恒定 Alpha。
在 RGB565格式下,我們設置 BF2 = 101 即可。
公式
通用的混合公式為:BC = BF1 * C + BF2 * Cs
BC: 混合后的顏色
BF1: 混合系數 1
C: 當前層顏色,即我們寫入層顯存的顏色值
BF2: 混合系數 2
Cs: 底層混合后的顏色,對于層 1 來說, Cs=背景層的顏色,對于層 2 來說, Cs=背景層和層 1 混合后的顏色。
舉例
假設 Alpha 的值由 LTDC_LxCACR 寄存器設置,恒定 ALpha = LTDC_LxCACR 設置值 / 255。假設 LTDC_LxCACR 設置值= 240;C = 128;Cs = 48;那么計算得 恒定 Alpha = LTDC_LxCACR 設置值 / 255 = 0.94。通過以上混合公式:BC = BF1 * C + BF2 * Cs 計算得,BC = 122。
注意
- BF1 和 BF2 的恒定 Alpha 值互補,他們之和為 1。
- 且 BF1 使用的是恒定 Alpha 值, BF2 使用的是互補值。
- 一般情況下,我們設置 LTDC_LxCACR 的值為 255,這樣,在使用恒定 Alpha 值的時候,BF1 = 1、BF2 = 0,這樣就可以得到 BC=C,即混合后的顏色,就是顯存里面的顏色(不進行混色)。
層窗口水平位置配置寄存器 LTDC_LxWHPCR(x=1/2)

該寄存器定義第 1 層或第 2 層窗口的水平位置(第一個和最后一個像素),其中:
- WHSTPOS:窗口水平起始位置,定義層窗口的一行的第一個可見像素。
- WHSPPOS:窗口水平停止位置,定義層窗口的一行的最后一個可見像素。
層窗口垂直位置配置寄存器 LTDC_LxWVPCR(x=1/2)

該寄存器定義第 1 層或第 2 層窗口的垂直位置(第一行或最后一行),其中:
- WVSTPOS:窗口垂直起始位置,定義層窗口的第一個可見行,見圖 27.1.2.15。
- WVSPPOS:窗口垂直停止位置,定義層窗口的最后一個可見行,見圖 27.1.2.15。
LTDC 的層支持窗口設置功能,通過 LTDC_LxWHPCR 和 LTDC_LxWVPCR 這上面兩個寄存器設置,可以調整顯示區域的大小,如圖:

層顏色幀緩沖區長度寄存器 LTDC_LxCFBLR(x=1/2)

該寄存器定義顏色幀緩沖區的行長和行間距。其中:
- CFBLL:這些位定義一行像素的長度(以字節為單位) +3。行長的計算方法為:有效寬度 每像素的字節數 +3。比如, LCD 面板的分辨率為 800480 有效寬度為 800,采用 RGB565 格式,那么 CFBLL 需要設置為: 8002+3=1603。
- CFBP:這些位定義從像素某行的起始處到下一行的起始處的增量(以字節為單位)。這個設置,其實同樣是一行像素的長度,對于 800480的 LCD 面板, RGB565 格式,設置 CFBP 為: 8002=1600 即可。
層顏色幀緩沖區行數寄存器 LTDC_LxCFBLNR(x=1/2)

該寄存器定義顏色幀緩沖區中的行數。
CFBLNBR: 用于定義幀緩沖區行數,比如, LCD 面板的分辨率為 800*480,那么幀緩沖區的行數為 480 行,則設置 CFBLNBR=480 即可。
時鐘域
LTDC 有三個時鐘域: AXI 時鐘域( ltdc_aclk) 、 APB3 時鐘域( ltdc_plck)和像素時鐘域( ltdc_ker_ck)。
AXI 時鐘域( ltdc_aclk):用于驅動接口讀取寄存器的數據到FIFO中。
APB3 時鐘域( ltdc_plck):配置寄存器。
像素時鐘域( ltdc_ker_ck):生成LCD接口信號( LCD_HSYNC、 LCD_VSYNC和 LCD_CLK等),這些時鐘信號需根據 LCD面板的要求進行配置。
LCD_CLK配置過程
LCD_CLK的時鐘 源來自 ltdc_ker_ck 而 ltdc_ker_ck 則來自 PLL3的 R分頻。下圖則是配置過程:

由圖可知,ltdc_ker_ck 的來源 為 clk_in 一般 為外部晶振(假定外部晶振作為系統時鐘源),經過 DIVM3分頻器分頻, 輸入鎖相環進行倍頻( DIVN3)和分頻 DIVR3),輸出 pll3_r_ck 然后通過 PKSU和 PKEU得到 ltdc_ker_ck,最終輸出到 LTDC,產生 LCD_CK,驅動液晶面板。
配置 LTDC
點擊查看代碼
/* LTDC 配置 */
#define LTDC_PIXFORMAT LTDC_PIXEL_FORMAT_RGB565
/**
* @brief LTDC初始化函數
* @param 無
* @retval 無
*/
void ltdc_init(void)
{
uint16_t lcdid = 0;
lcdid = ltdc_panelid_read(); /* 讀取LCD面板ID */
if (lcdid == 0X4342)
{
lcdltdc.pwidth = 480; /* 面板寬度,單位:像素 */
lcdltdc.pheight = 272; /* 面板高度,單位:像素 */
lcdltdc.hsw = 1; /* 水平同步寬度 */
lcdltdc.vsw = 1; /* 垂直同步寬度 */
lcdltdc.hbp = 40; /* 水平后廊 */
lcdltdc.vbp = 8; /* 垂直后廊 */
lcdltdc.hfp = 5; /* 水平前廊 */
lcdltdc.vfp = 8; /* 垂直前廊 */
ltdc_clk_set(300, 25, 33); /* 設置像素時鐘 9Mhz */
/* 其他參數待定. */
}
else if (lcdid == 0X7084)
{
lcdltdc.pwidth = 800; /* 面板寬度,單位:像素 */
lcdltdc.pheight = 480; /* 面板高度,單位:像素 */
lcdltdc.hsw = 1; /* 水平同步寬度 */
lcdltdc.vsw = 1; /* 垂直同步寬度 */
lcdltdc.hbp = 46; /* 水平后廊 */
lcdltdc.vbp = 23; /* 垂直后廊 */
lcdltdc.hfp = 210; /* 水平前廊 */
lcdltdc.vfp = 22; /* 垂直前廊 */
ltdc_clk_set(300, 25, 9); /* 設置像素時鐘 33M(如果開雙顯,需要降低DCLK到:18.75Mhz 300/4/4,才會比較好) */
}
else if (lcdid == 0X7016)
{
lcdltdc.pwidth = 1024; /* 面板寬度,單位:像素 */
lcdltdc.pheight = 600; /* 面板高度,單位:像素 */
lcdltdc.hsw = 20; /* 水平同步寬度 */
lcdltdc.vsw = 3; /* 垂直同步寬度 */
lcdltdc.hbp = 140; /* 水平后廊 */
lcdltdc.vbp = 20; /* 垂直后廊 */
lcdltdc.hfp = 160; /* 水平前廊 */
lcdltdc.vfp = 12; /* 垂直前廊 */
ltdc_clk_set(300, 25, 6); /* 設置像素時鐘 40Mhz 6 */
/* 其他參數待定.*/
}
else if (lcdid == 0X7018)
{
lcdltdc.pwidth = 1280; /* 面板寬度,單位:像素 */
lcdltdc.pheight = 800; /* 面板高度,單位:像素 */
/* 其他參數待定.*/
}
else if (lcdid == 0X4384)
{
lcdltdc.pwidth = 800; /* 面板寬度,單位:像素 */
lcdltdc.pheight = 480; /* 面板高度,單位:像素 */
lcdltdc.hbp = 88; /* 水平后廊 */
lcdltdc.hfp = 40; /* 水平前廊 */
lcdltdc.hsw = 48; /* 水平同步寬度 */
lcdltdc.vbp = 32; /* 垂直后廊 */
lcdltdc.vfp = 13; /* 垂直前廊 */
lcdltdc.vsw = 3; /* 垂直同步寬度 */
ltdc_clk_set(300, 25, 9); /* 設置像素時鐘 33M */
/* 其他參數待定. */
}
else if (lcdid == 0X1018)
{
lcdltdc.pwidth = 1280; /* 面板寬度,單位:像素 */
lcdltdc.pheight = 800; /* 面板高度,單位:像素 */
lcdltdc.hbp = 140; /* 水平后廊 */
lcdltdc.hfp = 10; /* 水平前廊 */
lcdltdc.hsw = 10; /* 水平同步寬度 */
lcdltdc.vbp = 10; /* 垂直后廊 */
lcdltdc.vfp = 10; /* 垂直前廊 */
lcdltdc.vsw = 3; /* 垂直同步寬度 */
ltdc_clk_set(300, 25, 6); /* 設置像素時鐘 45Mhz */
}
lcddev.width = lcdltdc.pwidth;
lcddev.height = lcdltdc.pheight;
#if LTDC_PIXFORMAT == LTDC_PIXFORMAT_ARGB8888 || LTDC_PIXFORMAT == LTDC_PIXFORMAT_RGB888
g_ltdc_framebuf[0] = (uint32_t*) <dc_lcd_framebuf;
lcdltdc.pixsize = 4; /* 每個像素占4個字節 */
#else
lcdltdc.pixsize = 2; /* 每個像素占2個字節 */
g_ltdc_framebuf[0] = (uint32_t*)<dc_lcd_framebuf;
// g_ltdc_framebuf[1] = (uint32_t*)<dc_lcd_framebuf1;
#endif
/* LTDC配置 */
g_ltdc_handle.Instance = LTDC;
g_ltdc_handle.Init.HSPolarity = LTDC_HSPOLARITY_AL; /* 水平同步極性 */
g_ltdc_handle.Init.VSPolarity = LTDC_VSPOLARITY_AL; /* 垂直同步極性 */
g_ltdc_handle.Init.DEPolarity = LTDC_DEPOLARITY_AL; /* 數據使能極性 */
g_ltdc_handle.State = HAL_LTDC_STATE_RESET;
if (lcdid == 0X1018)
{
g_ltdc_handle.Init.PCPolarity = LTDC_PCPOLARITY_IIPC; /* 像素時鐘極性 */
}
else
{
g_ltdc_handle.Init.PCPolarity = LTDC_PCPOLARITY_IPC; /* 像素時鐘極性 */
}
g_ltdc_handle.Init.HorizontalSync = lcdltdc.hsw - 1; /* 水平同步寬度 */
g_ltdc_handle.Init.VerticalSync = lcdltdc.vsw - 1; /* 垂直同步寬度 */
g_ltdc_handle.Init.AccumulatedHBP = lcdltdc.hsw + lcdltdc.hbp - 1; /* 水平同步后沿寬度 */
g_ltdc_handle.Init.AccumulatedVBP = lcdltdc.vsw + lcdltdc.vbp - 1; /* 垂直同步后沿高度 */
g_ltdc_handle.Init.AccumulatedActiveW = lcdltdc.hsw + lcdltdc.hbp + lcdltdc.pwidth - 1; /* 有效寬度 */
g_ltdc_handle.Init.AccumulatedActiveH = lcdltdc.vsw + lcdltdc.vbp + lcdltdc.pheight - 1; /* 有效高度 */
g_ltdc_handle.Init.TotalWidth = lcdltdc.hsw + lcdltdc.hbp + lcdltdc.pwidth + lcdltdc.hfp - 1; /* 總寬度 */
g_ltdc_handle.Init.TotalHeigh = lcdltdc.vsw + lcdltdc.vbp + lcdltdc.pheight + lcdltdc.vfp - 1; /* 總高度 */
g_ltdc_handle.Init.Backcolor.Red = 0; /* 屏幕背景層紅色部分 */
g_ltdc_handle.Init.Backcolor.Green = 0; /* 屏幕背景層綠色部分 */
g_ltdc_handle.Init.Backcolor.Blue = 0; /* 屏幕背景色藍色部分 */
HAL_LTDC_Init(&g_ltdc_handle);
/* 層配置:LTDC(LCD-TFT顯示控制器)支持多層顯示,通過配置不同層實現圖像疊加等效果 */
/*
* 配置LTDC第0層的參數
* 參數說明:
* 第一個參數:0 - 層索引,指定配置第0層(LTDC通常支持多層,此處配置第1層)
* 第二個參數:(uint32_t)g_ltdc_framebuf[0] - 該層的幀緩沖區地址,g_ltdc_framebuf[0]為存儲第0層圖像數據的數組
* 第三個參數:LTDC_PIXFORMAT - 像素格式(如RGB565、ARGB8888等,由宏定義具體指定)
* 第四個參數:255 - 圖層透明度(0-255,255表示完全不透明,0表示完全透明)
* 第五個參數:0 - 混合因子(通常用于圖層疊加計算,0表示不使用特殊混合規則)
* 第六個參數:6 - 水平同步后沿(HSYNC之后的無效像素數,根據LCD時序特性配置)
* 第七個參數:7 - 垂直同步后沿(VSYNC之后的無效行數,根據LCD時序特性配置)
* 第八個參數:0X000000 - 背景色(當圖層無有效數據時顯示的顏色,此處為黑色)
*/
ltdc_layer_parameter_config(0, (uint32_t)g_ltdc_framebuf[0], LTDC_PIXFORMAT, 255, 0, 6, 7, 0X000000); /* 層參數配置 */
/*
* 配置LTDC第0層的顯示窗口
* 參數說明:
* 第一個參數:0 - 層索引,指定配置第0層
* 第二個參數:0 - 窗口左上角X坐標(以LCD面板坐標系為原點,橫向起始位置)
* 第三個參數:0 - 窗口左上角Y坐標(以LCD面板坐標系為原點,縱向起始位置)
* 第四個參數:lcdltdc.pwidth - 窗口寬度(等于LCD面板的實際寬度,確保全屏顯示)
* 第五個參數:lcdltdc.pheight - 窗口高度(等于LCD面板的實際高度,確保全屏顯示)
* 注意:窗口坐標以LCD面板原生坐標系為基準,直接影響圖像在屏幕上的顯示位置,非特殊需求請勿修改
*/
ltdc_layer_window_config(0, 0, 0, lcdltdc.pwidth, lcdltdc.pheight); /* 層窗口配置,以LCD面板坐標系為基準,不要隨便修改! */
/*
* 以下為第1層的配置示例(當前被注釋禁用)
* 第1層可用于疊加在第0層上方顯示額外內容(如UI控件、狀態信息等)
*/
// /*
// * 配置LTDC第1層的參數
// * 與第0層相比,主要差異在于透明度設為127(半透明),幀緩沖區使用g_ltdc_framebuf[1]
// */
// ltdc_layer_parameter_config(1,(uint32_t)g_ltdc_framebuf[1],LTDC_PIXFORMAT,127,0,6,7,0X000000); /* 層參數配置 */
//
// /*
// * 配置LTDC第1層的顯示窗口
// * 窗口大小與第0層一致,默認全屏疊加(可根據需求修改為局部區域顯示)
// */
// ltdc_layer_window_config(1,0,0,lcdltdc.pwidth,lcdltdc.pheight); /* 層窗口配置,以LCD面板坐標系為基準,不要隨便修改! */
// ltdc_display_dir(0); /* 默認豎屏 */
ltdc_select_layer(0); /* 選擇第1層 */
LTDC_BL(1); /* 點亮背光 */
ltdc_clear(0XFFFFFFFF); /* 清屏 */
}
/**
* @brief LTDC層基本參數設置
* @note 此函數,必須在ltdc_layer_window_config之前設置.
* @param layerx : 0,第一層; 1,第二層;
* @param bufaddr : 層顏色幀緩存起始地址
* @param pixformat : 顏色格式. 0,ARGB8888; 1,RGB888; 2,RGB565; 3,ARGB1555; 4,ARGB4444; 5,L8; 6;AL44; 7;AL88
* @param alpha : 層顏色Alpha值, 0,全透明;255,不透明
* @param alpha0 : 默認顏色Alpha值, 0,全透明;255,不透明
* @param bfac1 : 混合系數1, 4(100),恒定的Alpha; 6(101),像素Alpha*恒定Alpha
* @param bfac2 : 混合系數2, 5(101),恒定的Alpha; 7(111),像素Alpha*恒定Alpha
* @param bkcolor : 層默認顏色,32位,低24位有效,RGB888格式
* @retval 無
*/
void ltdc_layer_parameter_config(uint8_t layerx, uint32_t bufaddr, uint8_t pixformat, uint8_t alpha, uint8_t alpha0, uint8_t bfac1, uint8_t bfac2, uint32_t bkcolor)
{
LTDC_LayerCfgTypeDef playercfg;
playercfg.WindowX0 = 0; /* 窗口起始X坐標 */
playercfg.WindowY0 = 0; /* 窗口起始Y坐標 */
playercfg.WindowX1 = lcdltdc.pwidth; /* 窗口終止X坐標 */
playercfg.WindowY1 = lcdltdc.pheight; /* 窗口終止Y坐標 */
playercfg.PixelFormat = pixformat; /* 像素格式 */
playercfg.Alpha = alpha; /* Alpha值設置,0~255,255為完全不透明 */
playercfg.Alpha0 = alpha0; /* 默認Alpha值 */
playercfg.BlendingFactor1 = (uint32_t)bfac1 << 8; /* 設置層混合系數 */
playercfg.BlendingFactor2 = (uint32_t)bfac2; /* 設置層混合系數 */
playercfg.FBStartAdress = bufaddr; /* 設置層顏色幀緩存起始地址 */
playercfg.ImageWidth = lcdltdc.pwidth; /* 設置顏色幀緩沖區的寬度 */
playercfg.ImageHeight = lcdltdc.pheight; /* 設置顏色幀緩沖區的高度 */
playercfg.Backcolor.Red = (uint8_t)(bkcolor & 0X00FF0000) >> 16; /* 背景顏色紅色部分 */
playercfg.Backcolor.Green = (uint8_t)(bkcolor & 0X0000FF00) >> 8; /* 背景顏色綠色部分 */
playercfg.Backcolor.Blue = (uint8_t)bkcolor & 0X000000FF; /* 背景顏色藍色部分 */
HAL_LTDC_ConfigLayer(&g_ltdc_handle, &playercfg, layerx); /* 設置所選中的層 */
}
/**
* @brief LTDC層窗口設置, 窗口以LCD面板坐標系為基準
* @note 此函數必須在ltdc_layer_parameter_config之后再設置.另外,當設置的窗口值不等于面板的尺
* 寸時,GRAM的操作(讀/寫點函數),也要根據窗口的寬高來進行修改,否則顯示不正常(本例程就未做修改).
* @param layerx : 0,第一層; 1,第二層;
* @param sx, sy : 起始坐標
* @param width,height: 寬度和高度
* @retval 無
*/
void ltdc_layer_window_config(uint8_t layerx, uint16_t sx, uint16_t sy, uint16_t width, uint16_t height)
{
HAL_LTDC_SetWindowPosition(&g_ltdc_handle, sx, sy, layerx); /* 設置窗口的位置 */
HAL_LTDC_SetWindowSize(&g_ltdc_handle, width, height, layerx); /* 設置窗口大小 */
}
/**
* @brief LTDC底層IO初始化和時鐘使能
* @note 此函數會被HAL_LTDC_Init()調用
* @param hltdc:LTDC句柄
* @retval 無
*/
void HAL_LTDC_MspInit(LTDC_HandleTypeDef *hltdc)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_LTDC_CLK_ENABLE(); /* 使能LTDC時鐘 */
__HAL_RCC_DMA2D_CLK_ENABLE(); /* 使能DMA2D時鐘 */
/* 以下是LTDC信號控制引腳 BL/DE/VSYNC/HSYNC/CLK等的配置 */
LTDC_BL_GPIO_CLK_ENABLE(); /* LTDC_BL腳時鐘使能 */
LTDC_DE_GPIO_CLK_ENABLE(); /* LTDC_DE腳時鐘使能 */
LTDC_VSYNC_GPIO_CLK_ENABLE(); /* LTDC_VSYNC腳時鐘使能 */
LTDC_HSYNC_GPIO_CLK_ENABLE(); /* LTDC_HSYNC腳時鐘使能 */
LTDC_CLK_GPIO_CLK_ENABLE(); /* LTDC_CLK腳時鐘使能 */
__HAL_RCC_GPIOH_CLK_ENABLE(); /* GPIOH時鐘使能 */
/* 初始化PB5,背光引腳 */
gpio_init_struct.Pin = LTDC_BL_GPIO_PIN; /* LTDC_BL引腳模式設置 */
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽輸出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_HIGH; /* 高速 */
HAL_GPIO_Init(LTDC_BL_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_DE_GPIO_PIN; /* LTDC_DE引腳模式設置 */
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 復用 */
gpio_init_struct.Pull = GPIO_NOPULL;
gpio_init_struct.Speed = GPIO_SPEED_HIGH;
gpio_init_struct.Alternate = GPIO_AF14_LTDC; /* 復用為LTDC */
HAL_GPIO_Init(LTDC_DE_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_VSYNC_GPIO_PIN; /* LTDC_VSYNC引腳模式設置 */
HAL_GPIO_Init(LTDC_VSYNC_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_HSYNC_GPIO_PIN; /* LTDC_HSYNC引腳模式設置 */
HAL_GPIO_Init(LTDC_HSYNC_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_CLK_GPIO_PIN; /* LTDC_CLK引腳模式設置 */
HAL_GPIO_Init(LTDC_CLK_GPIO_PORT, &gpio_init_struct);
/* 初始化PG6,11 */
gpio_init_struct.Pin = GPIO_PIN_6 | GPIO_PIN_11;
HAL_GPIO_Init(GPIOG, &gpio_init_struct);
/* 初始化PH9,10,11,12,13,14,15 */
gpio_init_struct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | \
GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOH, &gpio_init_struct);
/* 初始化PI0,1,2,4,5,6,7 */
gpio_init_struct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_5| \
GPIO_PIN_6 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOI, &gpio_init_struct);
}
通過以上幾個步驟,我們就完成了 LTDC 的配置,可以控制 RGBLCD 顯示了。
博客導航
本文來自博客園,作者:膝蓋中箭衛兵,轉載請注明原文鏈接:http://www.rzrgm.cn/Skyrim-sssuuu/p/19163545

浙公網安備 33010602011771號
https://orcid.org/0000-0001-5102-772X