有读者在下载OV5640工程或者移植OV5640工程时,由于使用OV5640摄像头版本的不同,导致下载或移植后出现这样那样的一些问题,比如初始化无法成功,显示设备显示错位、不稳定、颜色异常等。
问题原因 摄像头复位时序,复位逻辑设计存在问题。 具体来说,OV5640摄像头提供了硬件复位管脚复位和软件写复位寄存器来复位两种复位方式。 硬件复位:通过对OV5640芯片的复位管脚拉低1ms左右实现完成复位 软件复位:通过3008寄存器的bit[7]位写入0来进入复位,写入1来退出复位。 无论是硬件复位还是软件复位,都有复位时间和恢复时间的要求,所谓复位时间,就是OV5640进入复位状态后,必须保持该复位状态一定的时间,才能确保所有寄存器全部恢复到默认状态。如果时间不够,就会导致部分寄存器无法完全恢复初始状态,甚至出现错误的值。 也正是这个复位时间的存在,要求我们不得不关注OV5640的复位时序,以确保满足其要求的复位时间。
小梅哥FPGA团队自己设计生产销售的OV5640摄像头都拥有独立的硬件复位管脚,而且我们在程序中也对该复位管脚加入了符合要求的复位时间控制。所以我们的程序通过硬件复位的方式能够确保OV5640的所有寄存器能够在初始化之前进入完全可靠的初始值状态。这种情况下,不使用软件复位即可。
部分第三方生产销售的OV5640摄像头(如CrazyBingo生产销售的红颜色的OV5640摄像头)没有设置该硬件复位管脚,所以使用我们的初始化程序来初始化该摄像头时,无法有效且可靠的对OV5640进行复位,从而导致部分寄存器复位值不对,进而使得输出图像异常。
解决思路
1、取消硬件复位功能,将复位信号设置为常值1,这样,对于没有复位引脚的摄像头,该信号不分配管脚即可,对于有复位引脚的摄像头,该信号保持高电平,避免摄像头进入复位状态。 2、加入软件复位并确保复位时间。
解决方案 1、修改SCCB/I2C控制器的i2c_control.v文件,加入一个新的状态作为每次一个完整的字节读/写完成后的强制等待延时,如下图所示。 其中,dly_cnt_max作为该模块的一个输入端口,给该端口不同的值,就能设置控制器在每次读/写完成后,在WAIT_DLY状态等待多久再回到空闲态以开始新一个寄存器的数据读/写,如下图所示: 同时,在camera_init.v文件的控制按顺序写入多个寄存器的控制状态器中,根据写入的是第几个寄存器,来确定该寄存器写完后延时多久再执行下一个寄存器的写入,如下图所示。其中cnt就是控制并标识当前正在写入的是第几个寄存器。
在OV5640的初始化表中,第2个写入的寄存器(rom[1])就是向复位寄存器写入软件复位值,所以我们需要确保rom[1]对应的寄存器写入完成后延迟5ms(OV5640推荐的复位时间)再去写其他寄存器,除了写复位寄存器进入复位状态,写复位寄存器退出复位状态以及写其他寄存器都不需要延迟,所以只需要在cnt=1的时候,设置dly_cnt_max值为249999(250000*20 = 5ms)
讲清楚了原理,大家在实际使用的时候,如果有兴趣可以自己跟着这个原理自己修改代码,当然,最简单的方式是从本帖直接下载我们修改好的代码替换工程中的内容。以下为修改好的camera_init. v和i2c_control.v文件的内容,ov5640_init_table_rgb.v文件中的内容,请大家自己检查,rom[0]~rom[3]的值需要与上图中的一致,如果不一致的,需要您自己修改为一致。
相关帖子
双目摄像头实验某侧图像又被多切分一次的原因及解决方法
http://www.corecourse.cn/forum.php?mod=viewthread&tid=28642
ACZ702开发板Verilog代码OV5640单目摄像头移植双目摄像头要点
http://www.corecourse.cn/forum.php?mod=viewthread&tid=28628
|