IIC读写摄像头寄存器失败,为何?
小弟使用IIC读写摄像头OV5642寄存器,读写都失败,IIC驱动提示“ACK not received”。
从设备寄存器地址是datasheet上写的,应该不会错。
是何原因那?
附上一段代码:
int ModuleWriteBlock()
{
int i;
UCHAR BUF = 0;
RETAILMSG(OV9650_DEBUG,(TEXT("[CAMERA] ModuleWriteBlock++ \r\n")));
// Read OV9650 PID
HW_ReadRegisters(&BUF, OV9650_PID_REG, 1);
if (OV9650_PID == BUF)
{
RETAILMSG(OV9650_DEBUG,(TEXT("[CAMERA] Read OV9650_PID: 0x%x successfully! \r\n"), BUF));
}
else
{
RETAILMSG(OV9650_ERROR,(TEXT("[CAMERA] Read OV9650_PID: 0x%x failed! \r\n"), BUF));
}
// Read OV9650 VID
HW_ReadRegisters(&BUF, OV9650_VER_REG, 1);
if (OV9650_VER == BUF)
{
RETAILMSG(OV9650_DEBUG,(TEXT("[CAMERA] Read OV9650_VER_REG: 0x%x successfully! \r\n"), BUF));
}
else
{
RETAILMSG(OV9650_ERROR,(TEXT("[CAMERA] Read OV9650_VER_REG: 0x%x failed! \r\n"), BUF));
}
RETAILMSG(OV9650_DEBUG, (TEXT("sizeof(ov9650_reg)= %d, sizeof(ov9650_reg[0]) = %d, OV9650_REGS = %d.\r\n"), sizeof(ov9650_reg), sizeof(ov9650_reg[0]), OV9650_REGS));
#if OV9650_DEBUG
for(i = 0; i < 6; i++)
{
HW_ReadRegisters(&BUF, 0x3400|i, 1);
RETAILMSG(OV9650_DEBUG,(TEXT("HW_ReadRegisters: Reg[0x%x] = 0x%x, i = %d.\r\n"), 0x3400|i, BUF ,i));
}
#endif
for(i = 0; i < OV9650_REGS; i++)
{
HW_WriteRegisters(&ov9650_reg[i][0], 2);
RETAILMSG(OV9650_DEBUG,(TEXT("HW_WriteRegisters: Reg[0x%x] = 0x%x, i = %d.\r\n"), ov9650_reg[i][0], ov9650_reg[i][1], i));
}
ModuleSetImageSize(VGA);
#if OV9650_DEBUG
for(i = 0; i < OV9650_REGS; i++)
{
HW_ReadRegisters(&BUF, ov9650_reg[i][0], 1);
RETAILMSG(OV9650_DEBUG,(TEXT("HW_ReadRegisters: Reg[0x%x] = 0x%x, i = %d.\r\n"), ov9650_reg[i][0], BUF ,i));
}
#endif
RETAILMSG(OV9650_DEBUG,(TEXT("ModuleWriteBloc-- \r\n")));
return TRUE;
}
// ------------------------------------------------
// 写模组寄存器
// ------------------------------------------------
DWORD
HW_WriteRegisters(
PUCHAR pBuff, // Optional buffer
DWORD nRegs // number of registers
)
{
DWORD dwErr = 0;
DWORD bytes;
IIC_IO_DESC IIC_Data;
RETAILMSG(OV9650_DEBUG,(TEXT("HW_WriteRegisters++ \r\n")));
IIC_Data.SlaveAddress = CAMERA_WRITE;
IIC_Data.Count = nRegs;
IIC_Data.Data = pBuff;
// use iocontrol to write
if ( !DeviceIoControl( hI2C,
IOCTL_IIC_WRITE,
&IIC_Data,
sizeof(IIC_IO_DESC),
NULL,
0,
&bytes,
NULL) )
{
dwErr = GetLastError();
RETAILMSG(OV9650_ERROR,(TEXT("IOCTL_IIC_WRITE ERROR: %u \r\n"), dwErr));
}
if ( dwErr )
{
RETAILMSG(OV9650_ERROR, (TEXT("I2CWrite ERROR: %u \r\n"), dwErr));
}
RETAILMSG(OV9650_DEBUG,(TEXT("HW_WriteRegisters-- \r\n")));
return dwErr;
}
// ------------------------------------------------
// 读模组寄存器
// ------------------------------------------------
DWORD
HW_ReadRegisters(
PUCHAR pBuff, // Optional buffer
UCHAR StartReg, // Start Register
DWORD nRegs // Number of Registers
)
{
DWORD dwErr = 0;
DWORD bytes;
IIC_IO_DESC IIC_AddressData;
IIC_IO_DESC IIC_Data;
RETAILMSG(OV9650_DEBUG,(TEXT("HW_ReadRegisters++ \r\n")));
IIC_AddressData.SlaveAddress = CAMERA_WRITE;
IIC_AddressData.Data = &StartReg;
IIC_AddressData.Count = 1;
IIC_Data.SlaveAddress = CAMERA_READ;
IIC_Data.Data = pBuff;
IIC_Data.Count = 1;
// use iocontrol to read
if ( !DeviceIoControl( hI2C,
IOCTL_IIC_READ,
&IIC_AddressData,
sizeof(IIC_IO_DESC),
&IIC_Data,
sizeof(IIC_IO_DESC),
&bytes,
NULL) )
{
dwErr = GetLastError();
RETAILMSG(OV9650_ERROR,(TEXT("IOCTL_IIC_READ ERROR: %u \r\n"), dwErr));
}
if ( dwErr )
{
RETAILMSG(OV9650_ERROR,(TEXT("I2CRead ERROR: %u \r\n"), dwErr));
}
RETAILMSG(OV9650_DEBUG,(TEXT("HW_ReadRegisters-- \r\n")));
return dwErr;
}
[解决办法]
ACK not received
从这个错误提示看,应该是芯片没有响应。
不知道你开发板上有没有其它 I2C 芯片,如 E2PROM 等;
可以先用它测试一下你的 I2C 驱动和调用方式是否正确。
如果你读写 E2PROM 正确,那说明摄像头硬件或连线还有问题。
不知道驱动是不是你写的,你确定你这样写【从设备】地址是正确的吗?
[解决办法]
SDL
SDA
都上拉了吗?不上啦不行的。
[解决办法]
帮顶。
[解决办法]
最可能是物理连接问题 芯片不正常工作 然后没响应
仔细看spec,少数笨蛋芯片要求scl拉5次之类才开始工作,相当于启动信号
[解决办法]
呵呵,每次I2C操作之间加delay。。。
不知道什么平台,如果用三星的,是有这个bug的,需要加delay。
再说了,sensor芯片向来都很慢的,多加点delay试试吧。(我的前提是在上面各位兄弟讲的driver是好的,芯片是好的基础上的,如果driver不好,或者I2C代码本身有问题,或者芯片坏掉的,不在我的讨论之列。)
[解决办法]