12643|16

55

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

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[0], 2);
                RETAILMSG(OV9650_DEBUG,(TEXT("HW_WriteRegisters: Reg[0x%x] = 0x%x, i = %d.\r\n"), ov9650_reg[0], ov9650_reg[1], i));
        }

        ModuleSetImageSize(VGA);

#if OV9650_DEBUG   
        for(i = 0; i < OV9650_REGS; i++)
        {
                HW_ReadRegisters(&BUF, ov9650_reg[0], 1);
                RETAILMSG(OV9650_DEBUG,(TEXT("HW_ReadRegisters: Reg[0x%x] = 0x%x, i = %d.\r\n"), ov9650_reg[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;
}

最新回复

DWORD HW_ReadRegisters( PUCHAR pBuff,      // Optional buffer UCHAR StartReg,    // Start Register DWORD nRegs        // Number of Registers ) 问题解决了,仔细看过程序后发现问题出在这里,传入参数StartReg是一个无符号整形,而OV5642的寄存器地址不再是UCHAR了,而是一个WORD,所以如果直接传WORD进去的话就被截断了。地址不对当然就不能正确读出来了。  详情 回复 发表于 2009-9-21 09:22
点赞 关注

回复
举报

65

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
// --------------------------------------------------------------------------------------
// Macros Definitions
#define OV9650_ERROR       1
#define OV9650_DEBUG           1

#define OV9650_PID       0x96
#define OV9650_VER       0x52

#define OV9650_PID_REG         0x300A  // chip id high byte, should be 56
#define OV9650_VER_REG   0x300B  // chip id low byte, should be 42

#define OV9650_SLAVE_ID  0x78  
#define CAMERA_WRITE    (OV9650_SLAVE_ID | 0x0)  // 0x78 for write
#define CAMERA_READ     (OV9650_SLAVE_ID | 0x1)  // 0x79 for read

#define DEFAULT_MODULE_ITUXXX        CAM_ITU601
#define DEFAULT_MODULE_YUVORDER      CAM_ORDER_YCBYCR
#define DEFAULT_MODULE_HSIZE         640
#define DEFAULT_MODULE_VSIZE         480
#define DEFAULT_MODULE_HOFFSET       0
#define DEFAULT_MODULE_VOFFSET       0
#define DEFAULT_MODULE_UVOFFSET      CAM_UVOFFSET_0
#define DEFAULT_MODULE_CLOCK         24000000
#define DEFAULT_MODULE_CODEC         CAM_CODEC_422
#define DEFAULT_MODULE_HIGHRST       1
#define DEFAULT_MODULE_INVPCLK       1
#define DEFAULT_MODULE_INVVSYNC      0
#define DEFAULT_MODULE_INVHREF       0
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
ACK not received


从这个错误提示看,应该是芯片没有响应。


不知道你开发板上有没有其它 I2C 芯片,如 E2PROM 等;

可以先用它测试一下你的 I2C 驱动和调用方式是否正确。

如果你读写 E2PROM 正确,那说明摄像头硬件或连线还有问题。



不知道驱动是不是你写的,你确定你这样写【从设备】地址是正确的吗?
 
 
 

回复

89

帖子

0

TA的资源

一粒金砂(初级)

4
 
SDL
SDA
都上拉了吗?不上啦不行的。
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

5
 
帮顶。
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

6
 
1 上拉sda scl
2 确认物理连接
3 上示波器 等着看sda
 
 
 

回复

98

帖子

0

TA的资源

一粒金砂(初级)

7
 
最可能是物理连接问题 芯片不正常工作 然后没响应

仔细看spec,少数笨蛋芯片要求scl拉5次之类才开始工作,相当于启动信号
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

8
 
呵呵,每次I2C操作之间加delay。。。
不知道什么平台,如果用三星的,是有这个bug的,需要加delay。
再说了,sensor芯片向来都很慢的,多加点delay试试吧。(我的前提是在上面各位兄弟讲的driver是好的,芯片是好的基础上的,如果driver不好,或者I2C代码本身有问题,或者芯片坏掉的,不在我的讨论之列。)
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

9
 
上示波器了,发现iic发送正常,只是没有响应。原因查找中。。。
 
 
 

回复

97

帖子

7

TA的资源

一粒金砂(初级)

10
 
引用 8 楼 lbqhope 的回复:
上示波器了,发现iic发送正常,只是没有响应。原因查找中。。。


首先要确定你的I2C驱动没问题;

你设置的芯片地址【从机地址】没问题。

有些驱动使用的地址是【7位地址】,有些则是【8位地址】。



其次,摄像头芯片需要复位操作吗?
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

11
 
引用 9 楼 zaodt 的回复:
引用 8 楼 lbqhope 的回复:
上示波器了,发现iic发送正常,只是没有响应。原因查找中。。。


首先要确定你的I2C驱动没问题;

你设置的芯片地址【从机地址】没问题。

有些驱动使用的地址是【7位地址】,有些则是【8位地址】。


其次,摄像头芯片需要复位操作吗?

 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

12
 
目前找到一个问题,由于小弟的大意。经过对比OV9650和OV5642的Data sheet以及6410的data sheet,发现5642的复位线是高电平使能,常态为低电平。而9650恰恰相反,另外6410的camera reset线常态是低电平输出。所以9650不需要注意这个问题,5642正好相反。

现在貌似IIC可以写进去寄存器了,但是读的时候,iic操作0正常,没有报出Ack not received,但是现在iic的1操作还是会报出Ack not received。

HWI2C_IST[0xd31d8120, 1]: ACK NOT received

这里的0和1指的是什么?是指写和读么? 我看iic的使用方式,貌似读的时候要把要读的寄存器地址写到写地址上。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

13
 
帮顶
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

14
 
估计IIC驱动问题,我也遇到,但不影响使用。没理
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

15
 
OV系列的摄像头有个什么sccb通讯标准,写和I2C一样,读和I2C有一点差别,如果直接用I2C控制器读可能就会读不到,如果用GPIO模拟sccb应该是可以读到(我猜测)。我在用ov9650就遇到这种情况,初始化前一直读PID和VID失败,还以为I2C操作失败,后来查到相关说明就只关注写是否成功,问题解决。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

16
 
学习,帮顶
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

17
 
DWORD
HW_ReadRegisters(
PUCHAR pBuff,      // Optional buffer
UCHAR StartReg,    // Start Register
DWORD nRegs        // Number of Registers
)

问题解决了,仔细看过程序后发现问题出在这里,传入参数StartReg是一个无符号整形,而OV5642的寄存器地址不再是UCHAR了,而是一个WORD,所以如果直接传WORD进去的话就被截断了。地址不对当然就不能正确读出来了。
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表