本帖最后由 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的,正常运行的
|