小弟最近在折腾 使用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("rnOV2640_SENSOR_MID:%#X",err); return err ; }
err = CAMERA_Read_PID( (u16 * ) & Xid); if(Xid != CAMERA_OV2640_PID) // 0X2642 { printf("rnOV2640_SENSOR_PID:%#X",err); return err; }
/* Initialize OV2640 */ switch (_ImageFormat) { case JPEG_160x120: { cnt = (sizeof(OV2640_160x120_JPEG)/2); for(index=0; 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
{ 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
{ 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
{ 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
{ 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
{ 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
{ 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
{ 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
{ 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
{ 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
{ 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; // 字体颜色 tFont.BackColor = CL_MASK; // 透明色 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); //色彩饱和度 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("rnCAMERA Init Success ... ...rn");
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("rnHAL 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("rnDCMI 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(); }
0
|