这个例程测试了在连续串行模式下配置imx335相机斌且配置为800*480分辨率 RGB565模式将像素数据通过ISP推流到LTDC屏幕上,这里我们使用GPIO翻转和示波器来测量ISP处理图像数据的性能。由于屏幕接口为LTDC
所以这个项目的瓶颈在于屏幕显示速度而非ISP本身的性能限制
首先使能D-CACHE和I-CACHE 这两个cache缓存功能可以极大提升代码运行效率
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
将STLINK连接的串口配置为115200波特率,并使能LED1
BSP_LED_Init(LED_GREEN);
BSP_LED_Init(LED_RED);
/* UART log */
#if USE_COM_LOG
COM_InitTypeDef COM_Init;
/* Initialize COM init structure */
COM_Init.BaudRate = 115200;
COM_Init.WordLength = COM_WORDLENGTH_8B;
COM_Init.StopBits = COM_STOPBITS_1;
COM_Init.Parity = COM_PARITY_NONE;
COM_Init.HwFlowCtl = COM_HWCONTROL_NONE;
BSP_COM_Init(COM1, &COM_Init);
if (BSP_COM_SelectLogPort(COM1) != BSP_ERROR_NONE)
{
Error_Handler();
}
#endif
调用BSP支持包 初始化IMX335摄像头
IMX335_Probe(IMX335_R2592_1944, IMX335_RAW_RGGB10);
查阅IMX335手册可知 摄像头像素格式为RGGB模式
初始化屏幕,并配置像素
LCD_Init(FRAME_WIDTH, FRAME_HEIGHT);
使能ISP模块 并通过CSI接口将图像经过ISP模块推流到屏幕帧缓冲区并显示
if(ISP_Init(&hcamera_isp, &hdcmipp, 0, &appliHelpers, ISP_IQParamCacheInit[0]) != ISP_OK)
{
Error_Handler();
}
if (HAL_DCMIPP_CSI_PIPE_Start(&hdcmipp, DCMIPP_PIPE1, DCMIPP_VIRTUAL_CHANNEL0 , BUFFER_ADDRESS, DCMIPP_MODE_CONTINUOUS) != HAL_OK)
{
Error_Handler();
}
/* Start the Image Signal Processing */
if (ISP_Start(&hcamera_isp) != ISP_OK)
{
Error_Handler();
}
其中关键的部分为上文中的LCD_INIT函数
static void LCD_Init(uint32_t Width, uint32_t Height)
{
LTDC_LayerCfgTypeDef pLayerCfg ={0};
hltdc.Instance = LTDC;
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 = RK050HR18_HSYNC - 1;
hltdc.Init.AccumulatedHBP = RK050HR18_HSYNC + RK050HR18_HBP - 1;
hltdc.Init.AccumulatedActiveW = RK050HR18_HSYNC + Width + RK050HR18_HBP -1;
hltdc.Init.TotalWidth = RK050HR18_HSYNC + Width + RK050HR18_HBP + RK050HR18_HFP - 1;
hltdc.Init.VerticalSync = RK050HR18_VSYNC - 1;
hltdc.Init.AccumulatedVBP = RK050HR18_VSYNC + RK050HR18_VBP - 1;
hltdc.Init.AccumulatedActiveH = RK050HR18_VSYNC + Height + RK050HR18_VBP -1 ;
hltdc.Init.TotalHeigh = RK050HR18_VSYNC + Height + RK050HR18_VBP + RK050HR18_VFP - 1;
hltdc.Init.Backcolor.Blue = 0x0;
hltdc.Init.Backcolor.Green = 0xFF;
hltdc.Init.Backcolor.Red = 0x0;
if(HAL_LTDC_Init(&hltdc) != HAL_OK)
{
Error_Handler();
}
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = Width;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = Height;
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
pLayerCfg.FBStartAdress = BUFFER_ADDRESS;
pLayerCfg.Alpha = LTDC_LxCACR_CONSTA;
pLayerCfg.Alpha0 = 0;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
pLayerCfg.ImageWidth = Width;
pLayerCfg.ImageHeight = Height;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
if(HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, LTDC_LAYER_1))
{
Error_Handler();
}
}
在这里开辟了一个帧缓冲区的buffer 即BUFFER_ADDRESS
ISP将数据处理完成之后来内需的搬运到这里,LTDC控制器将buffer中的数据连续搬运到屏幕中 完成了现实的过程
while (1)
{
/* USER CODE END WHILE */
BSP_LED_Toggle(LED_GREEN);
if (ISP_BackgroundProcess(&hcamera_isp) != ISP_OK)
{
BSP_LED_Toggle(LED_RED);
}
/* USER CODE BEGIN 3 */
}
在while中翻转io引脚 用示波器观察
![C@RR]KMH59EPF(2D5~HDW2C.png C@RRKMH59EPF2D5~HDW2C.png](data/attachment/forum/202503/19/001456lpxpql962ub2bbpj.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300)
平均处理时间为1.85us处理完一幅图像数据 整个画面表现得十分丝滑流畅
