嵌入式技术论坛
直播中

万航渡路

9年用户 1409经验值
擅长:电源/新能源
私信 关注
[经验]

浅析RT Thread Studio RGB屏幕的LTDC驱动

软件:RT Thread Studio sdram:
stm36
sdram: W9812G2 16M 322 SDRAM RGBbit4.3
寸屏幕,尺寸为400*400
原理图接口
1.jpg
2.jpg
Step1: RGB之SDRAM配置修改程序的上进行
使用 cubemx 配置 LTDC
1.jpg
2.jpg
3.jpg
根据RGB屏幕要求修改系统时钟
4.jpg
步骤2复制drv_lcd.c到驱动文件夹内
:[drv_lcd.c位置] "D:/RT-ThreadStudio/repo/Extract/RT-Thread_Source_Code/RT-Thread/4.1.0/bsp/STM32/libraries/HAL_Drivers"
Step3:修改drv_lcd.c文件
3.1 在drv_lcd.c中添加头文件
#include
#ifdef BSP_USING_LCD
#include
#include
#include
#define DRV_DEBUG
#define LOG_TAG             "drv.lcd"
#include
3.2 在drv_lcd.c中添加RGB屏幕的GPIO口初始化函数
打开“ cubemx/Src”文件夹里面的ltdc.c,将
void HAL_LTDC_MspInit(LTDC_HandleTypeDef* ltdcHandle)函数复制到drv_lcd.c 文件内,并将函数名改为static void MX_LTDC_MspInit(void),修改后如下
static void MX_LTDC_MspInit(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  /** Initializes the peripherals clock  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
    PeriphClkInitStruct.PLLSAI.PLLSAIN = 150;
    PeriphClkInitStruct.PLLSAI.PLLSAIR = 3;
    PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
    /* LTDC clock enable */
    __HAL_RCC_LTDC_CLK_ENABLE();
    __HAL_RCC_GPIOI_CLK_ENABLE();
    __HAL_RCC_GPIOJ_CLK_ENABLE();
    __HAL_RCC_GPIOK_CLK_ENABLE();
    /**LTDC GPIO Configuration
    PI12     ------> LTDC_HSYNC
    PI13     ------> LTDC_VSYNC
    PI14     ------> LTDC_CLK
    PI15     ------> LTDC_R0
    PJ0     ------> LTDC_R1
    PJ1     ------> LTDC_R2
    PJ2     ------> LTDC_R3
    PJ3     ------> LTDC_R4
    PJ4     ------> LTDC_R5
    PJ5     ------> LTDC_R6
    PJ6     ------> LTDC_R7
    PJ7     ------> LTDC_G0
    PJ8     ------> LTDC_G1
    PJ9     ------> LTDC_G2
    PJ10     ------> LTDC_G3
    PJ11     ------> LTDC_G4
    PK0     ------> LTDC_G5
    PK1     ------> LTDC_G6
    PK2     ------> LTDC_G7
    PJ12     ------> LTDC_B0
    PJ13     ------> LTDC_B1
    PJ14     ------> LTDC_B2
    PJ15     ------> LTDC_B3
    PK3     ------> LTDC_B4
    PK4     ------> LTDC_B5
    PK5     ------> LTDC_B6
    PK6     ------> LTDC_B7
    PK7     ------> LTDC_DE
    */
    GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
    HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
                          |GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
    HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
    HAL_GPIO_Init(GPIOK, &GPIO_InitStruct);
    GPIO_InitStruct.Pin =         
    GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
    HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);
}
3.3 将static void MX_LTDC_MspInit(void)函数添加到drv_lcd.c里面的 rt_err_t stm32_lcd_init(struct drv_lcd_device *lcd)函数中
rt_err_t stm32_lcd_init(struct drv_lcd_device *lcd)
{
    LTDC_LayerCfgTypeDef pLayerCfg = {0};
    /* LTDC GPIO Initialization -------------------------------------------------------*/
    MX_LTDC_MspInit();    //RGB屏幕GPIO初始化,并启用时钟
    /* LTDC Initialization -------------------------------------------------------*/
    /* Polarity configuration */
    /* Initialize the horizontal synchronization polarity as active low */
    LtdcHandle.Init.HSPolarity = LTDC_HSPOLARITY_AL;
    /* Initialize the vertical synchronization polarity as active low */
    LtdcHandle.Init.VSPolarity = LTDC_VSPOLARITY_AL;
    /* Initialize the data enable polarity as active low */
    LtdcHandle.Init.DEPolarity = LTDC_DEPOLARITY_AL;
    /* Initialize the pixel clock polarity as input pixel clock */
    LtdcHandle.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
    /* Timing configuration */
    /* Horizontal synchronization width = Hsync - 1 */
    LtdcHandle.Init.HorizontalSync = LCD_HSYNC_WIDTH - 1;
    /* Vertical synchronization height = Vsync - 1 */
    LtdcHandle.Init.VerticalSync = LCD_VSYNC_HEIGHT - 1;
    /* Accumulated horizontal back porch = Hsync + HBP - 1 */
    LtdcHandle.Init.AccumulatedHBP = LCD_HSYNC_WIDTH + LCD_HBP - 1;
    /* Accumulated vertical back porch = Vsync + VBP - 1 */
    LtdcHandle.Init.AccumulatedVBP = LCD_VSYNC_HEIGHT + LCD_VBP - 1;
    /* Accumulated active width = Hsync + HBP + Active Width - 1 */
    LtdcHandle.Init.AccumulatedActiveW = LCD_HSYNC_WIDTH + LCD_HBP + lcd->lcd_info.width - 1 ;
    /* Accumulated active height = Vsync + VBP + Active Heigh - 1 */
    LtdcHandle.Init.AccumulatedActiveH = LCD_VSYNC_HEIGHT + LCD_VBP + lcd->lcd_info.height - 1;
    /* Total height = Vsync + VBP + Active Heigh + VFP - 1 */
    LtdcHandle.Init.TotalHeigh = LtdcHandle.Init.AccumulatedActiveH + LCD_VFP;
    /* Total width = Hsync + HBP + Active Width + HFP - 1 */
    LtdcHandle.Init.TotalWidth = LtdcHandle.Init.AccumulatedActiveW + LCD_HFP;
    /* Configure R,G,B component values for LCD background color */
    LtdcHandle.Init.Backcolor.Blue = 0;
    LtdcHandle.Init.Backcolor.Green = 0;
    LtdcHandle.Init.Backcolor.Red = 0;
    LtdcHandle.Instance = LTDC;
    /* Layer1 Configuration ------------------------------------------------------*/
    /* Windowing configuration */
    pLayerCfg.WindowX0 = 0;
    pLayerCfg.WindowX1 = lcd->lcd_info.width;
    pLayerCfg.WindowY0 = 0;
    pLayerCfg.WindowY1 = lcd->lcd_info.height;
    /* Pixel Format configuration*/
    if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
    {
        pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
    }
    else if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
    {
        pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
    }
    else if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB888)
    {
        pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
    }
    else if (lcd->lcd_info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB888)
    {
        pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
    }
    else
    {
        LOG_E("unsupported pixel format");
        return -RT_ERROR;
    }
    /* Start Address configuration : frame buffer is located at FLASH memory */
    pLayerCfg.FBStartAdress = (uint32_t)lcd->front_buf;
//    pLayerCfg.FBStartAdress = 0xD0000000;
    /* Alpha constant (255 totally opaque) */
    pLayerCfg.Alpha = 255;
    /* Default Color configuration (configure A,R,G,B component values) */
    pLayerCfg.Alpha0 = 0;
    pLayerCfg.Backcolor.Blue = 0;
    pLayerCfg.Backcolor.Green = 0;
    pLayerCfg.Backcolor.Red = 0;
    /* Configure blending factors */
    /* Constant Alpha value:  pLayerCfg.Alpha / 255
       C: Current Layer Color
       Cs: Background color
       BC = Constant Alpha x C + (1 - Constant Alpha ) x Cs */
    /* BlendingFactor1: Pixel Alpha x Constant Alpha */
    pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
    /* BlendingFactor2: 1 - (Pixel Alpha x Constant Alpha) */
    pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
    /* Configure the number of lines and number of pixels per line */
    pLayerCfg.ImageWidth = lcd->lcd_info.width;
    pLayerCfg.ImageHeight = lcd->lcd_info.height;
    /* Configure the LTDC */
    if (HAL_LTDC_Init(&LtdcHandle) != HAL_OK)
    {
        LOG_E("LTDC init failed");
        return -RT_ERROR;
    }
    /* Configure the Background Layer*/
    if (HAL_LTDC_ConfigLayer(&LtdcHandle, &pLayerCfg, 0) != HAL_OK)
    {
        LOG_E("LTDC layer init failed");
        return -RT_ERROR;
    }
    else
    {
        /* enable LTDC interrupt */
        HAL_NVIC_SetPriority(LTDC_IRQn, 1, 0);
        HAL_NVIC_EnableIRQ(LTDC_IRQn);
        LOG_D("LTDC init success");
        return RT_EOK;
    }
}
步骤4:复制lcd_port.h到driver/include文件夹内 [lcd_port.h]位置"D:/RT-ThreadStudio/repo/Extract/RT-Thread_Source_Code/RT-Thread/4.1.0/bsp/stm32/stm32f429-挑战者/板/端口"
步骤4根据规格进行, 修改RGB为客户端的屏幕截图5:为细分界面为PD13,参数配置
#ifndef __LCD_PORT_H__
#define __LCD_PORT_H__
/* FanKe 4.3 inch screen, 800 * 480 */
#define LCD_WIDTH           800
#define LCD_HEIGHT          480
#define LCD_BITS_PER_PIXEL  16
#define LCD_BUF_SIZE        (LCD_WIDTH * LCD_HEIGHT * LCD_BITS_PER_PIXEL / 8)
#define LCD_PIXEL_FORMAT    RTGRAPHIC_PIXEL_FORMAT_RGB565
#define LCD_HSYNC_WIDTH     1
#define LCD_VSYNC_HEIGHT    1
#define LCD_HBP             80
#define LCD_VBP             40
#define LCD_HFP             200
#define LCD_VFP             22
/* 屏幕背光引脚 */
#define LCD_BACKLIGHT_USING_GPIO
#define LCD_BL_GPIO_NUM     GET_PIN(D, 13)
/* FanKe 4.3 inch screen, 800 * 480 */
#endif /* __LCD_PORT_H__ */
步骤6:配置RT-Thread Setting,内核-> 内存管理
1.jpg
注意:使能动态内存根据需要进行修改,否则会出现[E/drv.lcd] init frame buffer failed!”错误
步骤7:下载,运行,输入lcd_test屏幕按照红、绿、蓝闪烁
1.jpg

原作者:博洛克

更多回帖

发帖
×
20
完善资料,
赚取积分