简介:
我们在之前适配FreeRTOS工程的基础上继续更新,添加LCD模块的显示功能验证。STM32H7S78-DK 开发板上集成了5寸的TFT 800*480 的RGB显示屏幕(RK050HR18-CTG)。LCD屏幕连接到了了MCU 的LTDC IP,通过LTDC 模块来驱动LCD显示屏,对应原理图如下。

LCD 屏幕原理图如下

以下时LTDC 的features 说明

从上述的参数可以看出LTDC 支持多种格式的格式数据的显示,ARGB888,RGB888,RGB565 等常用格式的显示,支持单独的background 显示配置,并且有两个独立可配置的layers 进行配置,并能将多层数据进行混合在一起显示,说明能比较形象的看出融合过程。

LCD 参数配置
LCD 的驱动主要是对屏幕参数的配置,以下是开发板使用的RK050HR18-CTG 模块的规格书中的参数说明。

从上述timing table 可以看出dclk 的推荐值为25Mhz,我们在cubemx 中配置为25Mhz ,对应配置如下,对应的始终来源为PLL3.R

根据上述timing 的参数表配置LCD 的水平方向的同步参数配置,我们都按照推荐的典型值来配置。

根据上述timing 的参数表配置LCD 的垂直方向的同步参数配置,我们都按照推荐的典型值来配置。

从以上的参数配置也可以看出,H方向的配置是按照DCLK 为单位,V 方向的配置单位为line。
水平方向和垂直方向信号的极性配置,从lcd 的手册中是都支持的,我们在可以配置为任意一种模式。

本次试验我们只使用一个layer 显示图片,我们配置layer1 参数如下。

LCD 点亮还需要配置背光控制GPIO

Cube 配置后生成对应的初始化代码,ltdc 的初始化及clk 代码如下
/**
* @brief LTDC Initialization Function
* @param None
* @retval None
*/
static void MX_LTDC_Init(void)
{
/* USER CODE BEGIN LTDC_Init 0 */
/* USER CODE END LTDC_Init 0 */
LTDC_LayerCfgTypeDef pLayerCfg = {0};
/* USER CODE BEGIN LTDC_Init 1 */
/* USER CODE END LTDC_Init 1 */
hltdc.Instance = LTDC;
hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AH;
hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AH;
hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hltdc.Init.HorizontalSync = 3;
hltdc.Init.VerticalSync = 3;
hltdc.Init.AccumulatedHBP = 11;
hltdc.Init.AccumulatedVBP = 11;
hltdc.Init.AccumulatedActiveW = 811;
hltdc.Init.AccumulatedActiveH = 491;
hltdc.Init.TotalWidth = 819;
hltdc.Init.TotalHeigh = 499;
hltdc.Init.Backcolor.Blue = 0;
hltdc.Init.Backcolor.Green = 0;
hltdc.Init.Backcolor.Red = 0;
if (HAL_LTDC_Init(&hltdc) != HAL_OK)
{
Error_Handler();
}
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 799;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 479;
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
pLayerCfg.Alpha = 0xff;
pLayerCfg.Alpha0 = 0;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
pLayerCfg.FBStartAdress = (uint32_t)&_acrgb565data;
pLayerCfg.ImageWidth = 800;
pLayerCfg.ImageHeight = 480;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN LTDC_Init 2 */
/* USER CODE END LTDC_Init 2 */
}/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE0) != HAL_OK)
{
Error_Handler();
}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL1.PLLM = 32;
RCC_OscInitStruct.PLL1.PLLN = 300;
RCC_OscInitStruct.PLL1.PLLP = 1;
RCC_OscInitStruct.PLL1.PLLQ = 2;
RCC_OscInitStruct.PLL1.PLLR = 2;
RCC_OscInitStruct.PLL1.PLLS = 2;
RCC_OscInitStruct.PLL1.PLLT = 2;
RCC_OscInitStruct.PLL1.PLLFractional = 0;
RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL2.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL2.PLLM = 4;
RCC_OscInitStruct.PLL2.PLLN = 25;
RCC_OscInitStruct.PLL2.PLLP = 2;
RCC_OscInitStruct.PLL2.PLLQ = 2;
RCC_OscInitStruct.PLL2.PLLR = 2;
RCC_OscInitStruct.PLL2.PLLS = 2;
RCC_OscInitStruct.PLL2.PLLT = 2;
RCC_OscInitStruct.PLL2.PLLFractional = 0;
RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL3.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL3.PLLM = 4;
RCC_OscInitStruct.PLL3.PLLN = 25;
RCC_OscInitStruct.PLL3.PLLP = 2;
RCC_OscInitStruct.PLL3.PLLQ = 2;
RCC_OscInitStruct.PLL3.PLLR = 16;
RCC_OscInitStruct.PLL3.PLLS = 2;
RCC_OscInitStruct.PLL3.PLLT = 2;
RCC_OscInitStruct.PLL3.PLLFractional = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_PCLK4|RCC_CLOCKTYPE_PCLK5;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
RCC_ClkInitStruct.APB5CLKDivider = RCC_APB5_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
{
Error_Handler();
}
}将程序下载到板卡中运行本地配置的frame buff 中的数据已经按照预期的进行显示了,LTDC 模块已经正常工作了。

在FreeRtos 添加代码刷新显示,图片资源是直接加载flash 中的资源
void start_task1(void *pvParameters)
{
while(1)
{
printf("task2 .\r\n");
HAL_LTDC_SetAddress(&hltdc, (uint32_t)&_acrgb565data, 0);
HAL_LTDC_Reload( &hltdc,LTDC_RELOAD_IMMEDIATE);
vTaskDelay(1000);
HAL_LTDC_SetAddress(&hltdc, (uint32_t)&eepwlogo1, 0);
HAL_LTDC_Reload( &hltdc,LTDC_RELOAD_IMMEDIATE);
vTaskDelay(1000);
}
}
我要赚赏金
