问答

汇集网友智慧,解决技术难题

21ic问答首页 - STM32F4驱动OV5640卡在EV6

ST OV5640 SCCB

STM32F4驱动OV5640卡在EV6 赏100家园币

feiyinglala2022-10-14
本帖最后由 feiyinglala 于 2022-10-14 19:27 编辑

使用STM32F429驱动OV5640模块,在使用硬件I2C(PB8 PB9)驱动,始终无法正常读写,OV5640地址配置为0x78
现象:总线可以正常启动,但发送完从设备地址后,立马卡住,在EV6中无法跳过
I2C1读取OV5640代码如下:
  • /**
  •   * @brief  从 OV5640 寄存器中读取一个字节的数据
  •   * @param Addr: 寄存器地址
  •   * @retval 返回读取得的数据
  •   */
  • u8 OV5640_ReadReg(uint16_t Addr)
  • {
  •   uint32_t timeout = DCMI_TIMEOUT_MAX;
  •   uint8_t Data = 0;
  •         while(I2C_GetFlagStatus(CAMERA_I2C, I2C_FLAG_BUSY))
  •                 if((timeout--) == 0)        return 0xFF;
  •         //1.开始【发送】--* Generate the Start Condition *
  •         I2C_GenerateSTART(CAMERA_I2C, ENABLE);                        //启动I2C STM32进入主模式 标志:SR1->SB 0-1
  •         //----* Test on CAMERA_I2C EV5 and clear it *
  •         timeout = DCMI_TIMEOUT_MAX; //----* Initialize timeout value *
  •         while (!I2C_CheckEvent(CAMERA_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  •         { //----* If the timeout delay is exeeded, exit with error code *
  •           if ((timeout--) == 0) return 0xFF;
  •         }
  •         //2.发送从设备地址 - 主发送--* Send DCMI selcted device slave Address for write *
  •         I2C_Send7bitAddress(CAMERA_I2C, OV5640_DEVICE_ADDRESS, I2C_Direction_Transmitter);     //启动I2C STM32发送从地址 标志:SR1->ADDR 0-1 【一直收不到】//执行完此句后,EV5结束,DR被赋值,SB1被重置
  •         //20220922 受https://shequ.stmicroelectronics.cn/forum.php?mod=viewthread&tid=602816启发,需排查此步后,EV5对应的A如何检测?标志是啥
  •         //----* Test on I2C1 EV6 and clear it *
  •         timeout = DCMI_TIMEOUT_MAX; //----* Initialize timeout value *
  •         while (!I2C_CheckEvent(CAMERA_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  •         {//----* If the timeout delay is exeeded, exit with error code *
  •                 if ((timeout--) == 0) return 0xFF;                //[卡在这行,读取ID时
  •         }
  •         //3.1        发送寄存器地址--* Send I2C1 location address MSB *
  •         I2C_SendData( CAMERA_I2C, (uint8_t)((Addr>>8) & 0xFF) );        //【存疑】是否分2次发???
  •         //----* Test on I2C1 EV8 and clear it *
  •         timeout = DCMI_TIMEOUT_MAX; //----* Initialize timeout value *
  •         while (!I2C_CheckEvent(CAMERA_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  •         { //----* If the timeout delay is exeeded, exit with error code *
  •           if ((timeout--) == 0) return 0xFF;
  •         }
  •         //----* Clear AF flag if arised *
  •         CAMERA_I2C->SR1 |= (uint16_t)0x0400;
  •         //3.2        发送寄存器地址--* Send I2C1 location address LSB *
  •         I2C_SendData( CAMERA_I2C, (uint8_t)(Addr & 0xFF) );
  •         //----* Test on I2C1 EV8 and clear it *
  •         timeout = DCMI_TIMEOUT_MAX; //----* Initialize timeout value *
  •         while (!I2C_CheckEvent(CAMERA_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  •         { //----* If the timeout delay is exeeded, exit with error code *
  •           if ((timeout--) == 0) return 0xFF;
  •         }
  •         //----* Clear AF flag if arised *
  •         CAMERA_I2C->SR1 |= (uint16_t)0x0400;
  •         //4.开始【接收】--* Generate the Start Condition *
  •         I2C_GenerateSTART(CAMERA_I2C, ENABLE);
  •         //----* Test on I2C1 EV6 and clear it *
  •         timeout = DCMI_TIMEOUT_MAX; //----* Initialize timeout value *
  •         while (!I2C_CheckEvent(CAMERA_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  •         {        //----* If the timeout delay is exeeded, exit with error code *
  •           if ((timeout--) == 0) return 0xFF;
  •         }
  •         //5.发送从设备地址 - 主接收,读取命令--* Send DCMI selcted device slave Address for write *
  •         I2C_Send7bitAddress(CAMERA_I2C, OV5640_DEVICE_ADDRESS, I2C_Direction_Receiver);
  •         //----* Test on I2C1 EV6 and clear it *
  •         timeout = DCMI_TIMEOUT_MAX; //----* Initialize timeout value *
  •         while (!I2C_CheckEvent(CAMERA_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  •         { //----* If the timeout delay is exeeded, exit with error code *
  •           if ((timeout--) == 0) return 0xFF;
  •         }
  •         //----* Prepare an NACK for the next data received *
  •         I2C_AcknowledgeConfig(CAMERA_I2C, DISABLE);
  •         //----* Test on I2C1 EV7 and clear it *
  •         timeout = DCMI_TIMEOUT_MAX; //----* Initialize timeout value *
  •         while (!I2C_CheckEvent(CAMERA_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))
  •         {
  •           //----* If the timeout delay is exeeded, exit with error code *
  •           if ((timeout--) == 0) return 0xFF;
  •         }
  •         //----* Prepare Stop after receiving data *
  •         I2C_GenerateSTOP(CAMERA_I2C, ENABLE);
  •         //----* Receive the Data *
  •         Data = I2C_ReceiveData(CAMERA_I2C);
  •         //----* return the read data *
  •         return Data;
  • }
我被这个问题困扰很久了,我特意还用I2C2驱动MPU6050 QMC5883两个模块都可以正常驱动。
我把I2C1(OV5640)    I2C2(MPU6050 QMC5883)在EV6验证时的截图如下:
这是I2C1的,有问题的
I2C1 持续无法响应.JPG



这是I2C2的,正常运行的
I2C2 正确.JPG



回答 +关注 1
3571人浏览 4人回答问题 分享 举报
4 个回答
  • 摄像头时钟没打开
  • 需要添加库文件
  • 经调试,原来是因为OV5640的XCLK未输入时钟,所以摄像头处于停工状态,我把TIM1-CH2的PWM输出到XCLK就好了
    XCLK对应PA8引脚,配置如下       
            //-----***PA8作为TIM1-ch2输出PWM到XCLK引脚***       
            GPIO_InitStructure.GPIO_Pin = MCO_XCLK_GPIO_PIN ;       
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
            GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
            GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
            GPIO_Init(MCO_XCLK_GPIO_PORT, &GPIO_InitStructure);
            GPIO_ResetBits(MCO_XCLK_GPIO_PORT,MCO_XCLK_GPIO_PIN);
            GPIO_PinAFConfig(MCO_XCLK_GPIO_PORT, MCO_XCLK_PINSOURCE, GPIO_AF_TIM1);//MCO_XCLK_AF);        //¸´ÓÃ
            //RCC_MCO1Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_1);        //ʹÄÜMCOʱÖÓ
            TIM1_Config();
  • 本帖最后由 feiyinglala 于 2022-10-14 19:28 编辑

    我跳过所有的校验,读到的是0x79(最后发送的地址 留存在I2C1的DR寄存器)中

您需要登录后才可以回复 登录 | 注册