STM32F4驱动OV5640卡在EV6
本帖最后由 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的,有问题的
这是I2C2的,正常运行的
STM32F4驱动OV5640卡在EV6
本帖最后由 feiyinglala 于 2022-10-14 19:28 编辑我跳过所有的校验,读到的是0x79(最后发送的地址 留存在I2C1的DR寄存器)中
STM32F4驱动OV5640卡在EV6
经调试,原来是因为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();
STM32F4驱动OV5640卡在EV6
需要添加库文件 摄像头时钟没打开
页:
[1]