小弟最近在折腾 使用STM32f429 cube/HAL库 驱动 OV2640 显示不成功 ???
程序可以通过I2C读出 OV2640的ID号,说明 i2c通讯是正常的,还有之前使用 标准库驱动是完全没有任何问题的,所以硬件是完全正确的。
LCD控制器: ILI9486 3.5寸,480*320 lcd 驱动我就不上传了 ,采用16位接口,
代码如下:
大神们帮忙看看问题是出在哪里 ???
#define LCD_35_HEIGHT 480 /* 3.5寸宽屏 高度,单位:像素 */
#define LCD_35_WIDTH 320 /* 3.5寸宽屏 宽度,单位:像素 */
/* Private define ------------------------------------------------------------*/
#define LCD_REG (*(volatile uint16_t *)(0x6C000000)) /* RS = 0 disp Reg ADDR*/
#define LCD_RAM (*(volatile uint16_t *)(0x6C000000 + (1 << (18 + 1)))) /* FSMC 16位总线模式下,FSMC_A18口线对应物理地址A19 , RS = 1 disp Data ADDR*/
CAMERA_StatusTypeDef CAMERA_Init(CAMERA_ImageFormat_TypeDef _ImageFormat)
{
CAMERA_StatusTypeDef err;
u16 index=0;
u16 cnt=0;
u16 Xid;
CAMERA_Reset();
err = CAMERA_Read_MID( (u16 * ) & Xid);
if(Xid != CAMERA_OV2640_MID) // 0X7FA2
{
printf("
OV2640_SENSOR_MID:%#X",err);
return err ;
}
err = CAMERA_Read_PID( (u16 * ) & Xid);
if(Xid != CAMERA_OV2640_PID) // 0X2642
{
printf("
OV2640_SENSOR_PID:%#X",err);
return err;
}
/* Initialize OV2640 */
switch (_ImageFormat)
{
case JPEG_160x120:
{
cnt = (sizeof(OV2640_160x120_JPEG)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_160x120_JPEG[index][0], OV2640_160x120_JPEG[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case JPEG_176x144:
{
cnt = (sizeof(OV2640_176x144_JPEG)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_176x144_JPEG[index][0], OV2640_176x144_JPEG[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case JPEG_320x240:
{
cnt = (sizeof(OV2640_320x240_JPEG)/2);
for(index=0; index<cnt; index++)
{
CAMERA_WR_Reg(OV2640_320x240_JPEG[index][0], OV2640_320x240_JPEG[index][1]);
// BSP_OS_TimeDlyMs(1);
}
break;
}
case JPEG_352x288:
{
cnt = (sizeof(OV2640_352x288_JPEG)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_352x288_JPEG[index][0], OV2640_352x288_JPEG[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case CAMERA_R160x120:
{
cnt = (sizeof(OV2640_QQVGA_160x120)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_QQVGA_160x120[index][0], OV2640_QQVGA_160x120[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case CAMERA_R320x240:
{
cnt = (sizeof(OV2640_QVGA_320x240)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_QVGA_320x240[index][0], OV2640_QVGA_320x240[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case CAMERA_R480x272:
{
cnt = (sizeof(OV2640_480x272)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_480x272[index][0], OV2640_480x272[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case CAMERA_R480x320:
{
cnt = (sizeof(OV2640_480x320)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_480x320[index][0], OV2640_480x320[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case CAMERA_R640x480:
{
cnt = (sizeof(OV2640_VGA_640x480)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_VGA_640x480[index][0], OV2640_VGA_640x480[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case CAMERA_R800x600:
{
cnt = (sizeof(OV2640_SVGA_800x600)/2);
for(index=0; index<cnt; index++)
{
err = CAMERA_WR_Reg(OV2640_SVGA_800x600[index][0], OV2640_SVGA_800x600[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
case CAMERA_R1600x1200:
{
cnt = (sizeof(OV2640_SXGA_1600x1200)/2);
//初始化 OV2640,采用SXGA分辨率(1600*1200)
for(index=0;index<cnt;index++)
{
err = CAMERA_WR_Reg(OV2640_SXGA_1600x1200[index][0], OV2640_SXGA_1600x1200[index][1]);
if(CAMERA_OK != err)
return err;
// BSP_OS_TimeDlyMs(1);
}
break;
}
default:
{
break;
}
}
return CAMERA_OK;
}
/* DCMI init function */
CAMERA_StatusTypeDef BSP_CAMERA_Init(CAMERA_ImageFormat_TypeDef _ImageFormat)
{
DCMI_HandleTypeDef *phdcmi;
CAMERA_StatusTypeDef ret = CAMERA_ERROR;
/* Get the DCMI handle structure */
phdcmi = &hdcmi_eval;
// HAL_DCMI_DeInit(phdcmi); //清除原来的设置
/*** Configures the DCMI to interface with the camera module ***/
/* DCMI configuration */
phdcmi->Init.CaptureRate = DCMI_CR_ALL_FRAME;
phdcmi->Init.HSPolarity = DCMI_HSPOLARITY_LOW;
phdcmi->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
phdcmi->Init.VSPolarity = DCMI_VSPOLARITY_LOW;
phdcmi->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
phdcmi->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
phdcmi->Instance = DCMI;
/* DCMI Initialization */
DCMI_MspInit();
switch(_ImageFormat)
{
case BMP_QQVGA:
{
/* DCMI configuration */
phdcmi->Init.VSPolarity = DCMI_VSPOLARITY_HIGH;
HAL_DCMI_Init(phdcmi);
break;
}
case BMP_QVGA:
{
/* DCMI configuration */
HAL_DCMI_Init(phdcmi);
break;
}
default:
{
/* DCMI configuration */
phdcmi->Init.VSPolarity = DCMI_VSPOLARITY_LOW; //DCMI_VSPolarity_High;
HAL_DCMI_Init(phdcmi);
break;
}
}
ret = CAMERA_Init( _ImageFormat); // 此函数里面实现 读取 ID, 设置图片分辨率等
current_resolution = _ImageFormat;
return ret;
}
/**
* @brief Initializes the DCMI MSP.
* @param None
* @retval None
*/
static void DCMI_MspInit(void) //HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
{
static DMA_HandleTypeDef hdma_eval;
GPIO_InitTypeDef GPIO_InitStruct;
DCMI_HandleTypeDef *_phdcmi = &hdcmi_eval;
if(_phdcmi->Instance == DCMI) //如果不使用 HAL_DCMI_MspInit 这个函数,那么此处需要屏蔽
{
/*** Enable peripherals and GPIO clocks ***/
/* Enable DCMI clock */
__DCMI_CLK_ENABLE();
// __HAL_RCC_DCMI_CLK_ENABLE();
/* Enable DMA2 clock */
__DMA2_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOI_CLK_ENABLE();
/**DCMI GPIO Configuration
PH9 ------> DCMI_D0
PH10 ------> DCMI_D1
PH11 ------> DCMI_D2
PH12 ------> DCMI_D3
PH14 ------> DCMI_D4
PI4 ------> DCMI_D5
PI6 ------> DCMI_D6
PI7 ------> DCMI_D7
PH8 ------> DCMI_HSYNC
PA6 ------> DCMI_PIXCK
PI5 ------> DCMI_VSYNC
*/
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*** Configure the DMA ***/
/* Set the parameters to be configured */
hdma_eval.Init.Channel = DMA_CHANNEL_1;
hdma_eval.Init.Direction = DMA_PERIPH_TO_MEMORY; //外设到存储器模式
hdma_eval.Init.PeriphInc = DMA_PINC_DISABLE; //外设非增量模式
hdma_eval.Init.MemInc = DMA_MINC_ENABLE; //存储器增量模式
hdma_eval.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; //外设数据长度:32位
hdma_eval.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; //DMA_MDATAALIGN_WORD; //存储器数据长度
hdma_eval.Init.Mode = DMA_CIRCULAR; // 使用循环模式
hdma_eval.Init.Priority = DMA_PRIORITY_HIGH; //高优先级
hdma_eval.Init.FIFOMode = DMA_FIFOMODE_DISABLE; // ???
// hdma_eval.Init.FIFOMode = DMA_FIFOMODE_ENABLE; //FIFO模式
hdma_eval.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; //使用全FIFO
hdma_eval.Init.MemBurst = DMA_MBURST_SINGLE; //外设突发单次传输
hdma_eval.Init.PeriphBurst = DMA_PBURST_SINGLE; //存储器突发单次传输
hdma_eval.Instance = DMA2_Stream1;
__HAL_LINKDMA(_phdcmi, DMA_Handle, hdma_eval);
/*** Configure the NVIC for DCMI and DMA ***/
/* NVIC configuration for DCMI transfer complete interrupt */
HAL_NVIC_SetPriority(DCMI_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DCMI_IRQn);
/* NVIC configuration for DMA2D transfer complete interrupt */
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
// HAL_DMA_Init(&hdma_dcmi);
/* Configure the DMA stream */
HAL_DMA_Init(_phdcmi->DMA_Handle);
}
}
/**
* @brief Starts the camera capture in continuous mode. 在连续模式下启动相机捕获。
* @param buff: pointer to the camera output buffer
* @retval None
*/
void BSP_CAMERA_ContinuousStart(uint8_t *buff)
{
/* Start the camera capture */
HAL_DCMI_Start_DMA(&hdcmi_eval, DCMI_MODE_CONTINUOUS, (uint32_t )buff, CAMERA_GetSize(current_resolution));
}
//RGB565测试
//RGB数据直接显示在LCD上面
CAMERA_StatusTypeDef DCMI_RGB565_LcdTest(void)
{
CAMERA_StatusTypeDef err;
tFont.FontCode = FC_ST_16; // 字体代码 16点阵
tFont.FrontColor = CL_WHITE; // 字体颜 {MOD}
tFont.BackColor = CL_MASK; // 透明 {MOD}
tFont.Space = 10;
LCD_ClrScr(CL_BLUE);
LCD_DispStr( 30, 10, (const u8 *)"SWS STM32F429IIT6 LQFP-176", &tFont);
LCD_DispStr( 30, 34, (const u8 *)"OV2640 RGB565 Mode", &tFont);
LCD_DispStr( 30, 58, (const u8 *)"KEY0 Contrast", &tFont); //对比度
LCD_DispStr( 30, 82, (const u8 *)"KEY1 Saturation", &tFont); // {MOD}彩饱和度
LCD_DispStr( 30, 106, (const u8 *)"KEY2 Effects", &tFont); //特效
LCD_DispStr( 30, 130, (const u8 *)"KEY_UP FullSize / Scale", &tFont); //1:1尺寸(显示真实尺寸)/全尺寸缩放
bsp_DelayMS(500);
/* 初始化OV2640摄像头及读取摄像头芯片ID,确定摄像头正常连接 */
if(CAMERA_OK == BSP_CAMERA_Init(CAMERA_R480x320))
{
/* Wait 1s before Camera snapshot */
HAL_Delay(1000);
err = CAMERA_RGB565_Mode(); //RGB565模式
if( CAMERA_OK != err )
return err;
printf("
CAMERA Init Success ... ...
");
CAMERA_SetImageOutPixelSize(DCMI_OUT_SIZE_X, DCMI_OUT_SIZE_Y);
//在屏幕中间显示
LCD_SetCursor_B((MAX_X - DCMI_OUT_SIZE_X) / 2, DCMI_OUT_SIZE_X + ((MAX_X - DCMI_OUT_SIZE_X) / 2) - 1, //图像输出320,输出范围要与此“OV2640_OutSize_Set(320, 240); ”的设置一致
(MAX_Y - DCMI_OUT_SIZE_Y) / 2, DCMI_OUT_SIZE_Y + ((MAX_Y - DCMI_OUT_SIZE_Y) / 2) - 1); //图像输出240,
// CAMERA_SetImageOutSize (DCMI_OUT_SIZE_X/2, DCMI_OUT_SIZE_Y/2);
DCMI_FrameBuf = mymalloc(SRAMEX, 1288) ; // 申请外部SRAM内存地址
/* Start the Camera Capture 启动相机捕捉 */
BSP_CAMERA_ContinuousStart((uint8_t *) & DCMI_FrameBuf);
}
while(1)
{
}
}
//**********************************************************************************************
/**
* @brief Converts a line to an ARGB8888 pixel format.
* @param pSrc: Pointer to source buffer
* @param pDst: Output color
* @param xSize: Buffer width
* @param ColorMode: Input color mode
* @retval None
*/
static void DCMI_LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst)
{
/* Enable DMA2D clock */
__HAL_RCC_DMA2D_CLK_ENABLE();
/* Configure the DMA2D Mode, Color Mode and output offset */
hdma2d_eval.Init.Mode = DMA2D_M2M_PFC;
hdma2d_eval.Init.ColorMode = DMA2D_ARGB8888;
hdma2d_eval.Init.OutputOffset = 0;
/* Foreground Configuration */
hdma2d_eval.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
hdma2d_eval.LayerCfg[1].InputAlpha = 0xFF;
hdma2d_eval.LayerCfg[1].InputColorMode = CM_RGB565;
hdma2d_eval.LayerCfg[1].InputOffset = 0;
hdma2d_eval.Instance = DMA2D;
/* DMA2D Initialization */
if(HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK)
{
if(HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK)
{
if (HAL_DMA2D_Start(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, LCD_35_WIDTH, 1) == HAL_OK)
{
/* Polling For DMA transfer */
HAL_DMA2D_PollForTransfer(&hdma2d_eval, 10);
}
}
}
else
{
/* FatFs Initialization Error */
// Error_Handler();
printf("
HAL DMA2_Init Error ... ...");
}
}
//*******************************************************************************************
/**
* @brief Camera line evnet callback
* @param None
* @retval None
*/
void BSP_CAMERA_LineEventCallback(void)
{
static uint32_t tmp, tmp2, counter;
if(LCD_35_HEIGHT > counter)
{
DCMI_LCD_LL_ConvertLineToARGB8888((uint32_t *)(DCMI_FrameBuf + tmp), (uint32_t *)(LCD_RAM + tmp2));
tmp = tmp + LCD_35_WIDTH * sizeof ( uint16_t );
tmp2 = tmp2 + LCD_35_WIDTH * sizeof ( uint32_t );
counter ++;
printf("
DCMI OUT ... %d", counter); // 串口打应 正常 还有此处,我已经把他屏蔽的了,但是程序运行时串口还是会有输出,不知道是何故 ??????????????????????????????????
}
else
{
tmp = 0;
tmp2 = 0;
counter = 0;
}
}
/**
* @brief Frame event callback 帧事件回调
* @param hdcmi: pointer to the DCMI handle
* @retval None
*/
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
BSP_CAMERA_FrameEventCallback();
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2.debug模式下,看看图像的buffer,彩条模式下,buffer的值和大小都是一样的,看看是否顺利得到数据了。
3.我在其他论坛有个关于CUBE库获取OV2640的JPEG图像的例子,有源码,地址不方便贴了,百度一下【f446RE开发板试用】教你用HAL库DCMI捕捉OV2640
一周热门 更多>