基於STM32F429的RGB屏使用
使用ST的HAL庫進行開發,RGB螢幕是480*272的4.3寸LCD,由於驅動RGB螢幕需要較多的記憶體,
所以使用了外部SDRAM,記憶體是32M位元組,關於SDRAM的驅動本文不進行討論。
RGB螢幕常用的畫素格式有:ARGB8888、RGB888、RGB565、ARGB1555、ARGB4444等格式,本文討論RGB565格式的使用。
RGBLCD的訊號線如下表:
上表共有24根顏色訊號線,RGB565格式只用了其中的16根顏色訊號線,分別是:R[3:7],G[2:7],B[3:7],共16位,
這樣在表示顏色的時候就可以用16位長度的資料進行表示了,增加了資料的傳輸速度。
RGBLCD介面的原理圖如下:
除了16位資料線之外,還有用到如下幾個訊號線:
LCD_BL:背光;
LCD_DE:資料使能訊號;
LCD_VSYNC:垂直同步訊號;
LCD_HSYNC:水平同步訊號;
LCD_CLK:時鐘訊號;
STM32F429有自帶的RGBLCD外設介面LTDC,可以用來直接驅動RGBLCD,另外配上專用於影象處理的DMA2D,
使得RGBLCD用起來更加方便快速。
下面開始介紹使用到的微控制器引腳對應:
PI9 ------> LTDC_VSYNC
PI10 ------> LTDC_HSYNC
PF10 ------> LTDC_DE
PG7 ------> LTDC_CLK
PH9 ------> LTDC_R3
PH10 ------> LTDC_R4
PH11 ------> LTDC_R5
PH12 ------> LTDC_R6
PG6 ------> LTDC_R7
PH13 ------> LTDC_G2
PH14 ------> LTDC_G3
PH15 ------> LTDC_G4
PI0 ------> LTDC_G5
PI1 ------> LTDC_G6
PI2 ------> LTDC_G7
PG11 ------> LTDC_B3
PI4 ------> LTDC_B4
PI5 ------> LTDC_B5
PI6 ------> LTDC_B6
PI7 ------> LTDC_B7
通過配置STM32CubeMx直接生成的LTDC部分初始化程式碼如下:
void MX_LTDC_Init(void) { LTDC_LayerCfgTypeDef pLayerCfg; hltdc.Instance = LTDC; hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL; //水平同步極性:低有效 hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL; //垂直同步極性:低有效 hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL; //資料使能極性:低有效 hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC; //畫素時鐘極性:輸入畫素時鐘 hltdc.Init.HorizontalSync = 0; //水平同步寬度,1個時鐘訊號 hltdc.Init.VerticalSync = 0; //垂直同步寬度,1行畫素對應的時鐘 hltdc.Init.AccumulatedHBP = 40; //水平後沿寬度:40 hltdc.Init.AccumulatedVBP = 8; //垂直後沿寬度:8 hltdc.Init.AccumulatedActiveW = 520; //顯示有效寬度:520-40=480 hltdc.Init.AccumulatedActiveH = 280; //顯示有效高度:280-8=272 hltdc.Init.TotalWidth = 525; //總寬度:525(包含了5個水平前沿寬度) hltdc.Init.TotalHeigh = 288; //總高度:288(包含了8個垂直前沿寬度) hltdc.Init.Backcolor.Blue = 0; //螢幕背景層藍色部分 hltdc.Init.Backcolor.Green = 0; //螢幕背景層綠色部分 hltdc.Init.Backcolor.Red = 0; //螢幕背景層紅色部分 if (HAL_LTDC_Init(&hltdc) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } pLayerCfg.WindowX0 = 0; //視窗起點x座標 pLayerCfg.WindowX1 = 480; //視窗終點x座標 pLayerCfg.WindowY0 = 0; //視窗起點y座標 pLayerCfg.WindowY1 = 272; //視窗終點y座標 pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565; //畫素格式RGB565格式 pLayerCfg.Alpha = 255; //恆定alpha值 pLayerCfg.Alpha0 = 0; //預設alpha值 pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; //混合係數1:畫素alpha*恆定alpha pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; //混合洗漱2:畫素alpha*恆定alpha pLayerCfg.FBStartAdress = 0xC0000000; //顏色資料所在的記憶體起始地址 pLayerCfg.ImageWidth = 480; //影象寬度 pLayerCfg.ImageHeight = 272; //影象高度 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__); } }
函式MX_LTDC_Init()將外設LTDC進行了初始化配置,在配置好ltdc之後,我們只需要改變對應的記憶體的資料,
ltdc就會自動幫我們改變LCD上對應畫素點的顏色。
下面通過初始化LCD的函式,將LCD螢幕清屏為全白:/**
* @brief : LCD清屏,使用DMA2D將顏色資料傳輸到記憶體中
* @par Full description : 填充範圍是座標(sx,sy),(ex,ey)形成的矩形區域,
* 區域大小畫素點個數是:(ex-sx+1)*(ey-sy+1)
* @param :
* sx -- x軸起點座標
* sy -- y軸起點座標
* ex -- x軸終點座標
* ey -- y軸終點座標
* Colour -- 填充的顏色
* @retval : 無
*/
void LcdClear(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t Colour)
{
__HAL_RCC_DMA2D_CLK_ENABLE(); //使能DMA2D時鐘
DMA2D->CR &= ~(DMA2D_CR_START); //先停止DMA2D
DMA2D->CR = DMA2D_R2M; //暫存器到儲存器模式
DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_RGB565; //設定顏色格式
DMA2D->OOR = 0; //設定行偏移
DMA2D->OMAR = uhLtdcFrameBuf; //輸出儲存器地址
DMA2D->NLR = (ey - sy + 1) | ((ex - sx + 1) << 16); //設定行數暫存器
DMA2D->OCOLR = Colour; //設定輸出顏色暫存器
DMA2D->CR |= DMA2D_CR_START; //啟動DMA2D
while((DMA2D->ISR & DMA2D_FLAG_TC) == 0); //等待傳輸完成
DMA2D->IFCR |= DMA2D_FLAG_TC; //清除傳輸完成標誌
}
void LcdInit(void)
{
LCD_BIAS_LIGHT_ENALBE; //使能LCD背光
LcdClear(0, 0, 479, 271, 0xFFFF); //清屏全白,0xFFFF是全白
}
使用DMA2D將大量的資料傳輸到指定的記憶體之中,0xFFFF對應的是白色,對應的記憶體地址是uhLtdcFrameBuf陣列的首地址。
至此,我們就完成了將RGBLCD清屏成全白的測試。