|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2010-11-8 22:05:13
|
显示全部楼层
这么快就有回复啊,先占个位
在这个方案中,主要注意FIFO的读写时序,以及什么时候开启FIFO,什么时候从FIFO读数据来处理(比如显示)。一下是一些经验:
调试该摄像头的时候最好有个LCD配合,否则大量的数据将给调试带来困难。首先我遇到的困难是OV7670的配置问题,粗看一眼,OV的寄存器多达100多个,涉及到很多专业的光学和摄像专业词汇。我的做法是网上找了别人能用的初始化配置数据,然后写到我的OV里面,然后再翻开datasheet,根据需要更改特定的寄存器值。以下是一些我目前认为重要的寄存器:
0x12:这个寄存器用来设置图像的输出格式,有VGA(640*480),QVGA(320*240)等,另外就是配置图像数据的格式,有YUV,RGB565,Bayer RGB RAW。最后这个寄存器的最高位是用来软件复位所有寄存器的值的。
0x71:这个寄存器对于调试的时候是很有用的,通过将其值配置为0x80,可以让摄像头输出8条彩带,当采集不到数据,或采集到的图像不正确的时候不妨设置一下该寄存器的值看图像是否为彩带,或是发生了什么样的畸变。下图是采集到的彩带图形(其实彩带图形0x70和0x71配合使用的,一般设置0x70寄存器为0即可)。
0x11:这个寄存器用来配置OV的内部时钟相对于外部时钟的分频,即内部时钟是通过外部时钟分频得到的。资料上说OV的外部时钟典型值是24M,我按要求给了,但是当设置分频3时按道理像素时钟应该为8M,但得到的结果并非如此,但通过设置不同的分频系数,像素时钟确实是按照分频系数线性变化的,具体的时钟变化公式需要进一步研究。这个寄存器也是通过与0x6b寄存器配合使用的。接下来讲一下0x6b。
0x6b:这个寄存器是内部时钟的倍频系数配置寄存器。我也尚未清楚为何有了分频(0x11)还要一个倍频。通过实验确实发现这两个寄存器的配置以不同的组合出现时对应的像素时钟是安线性关系改变的。但无论怎么组合,最后的内部时钟是无法超过外部时钟的。这个寄存器还可以配置内部LDO是否开启。开启了内部LDO功能后硬件上可以少一个1.8V的线性稳压器给内核供电。
其他的寄存器诸如白平衡,RGB增益设置等因为暂时未用到,所以没有具体配置来看效果。
另一方面,OV与FIFO的组合要需要注意一定的时序。一个简单而有效的组合是这样的:OV的场同步接入MCU的外部中断(上升沿触发),这样当一个场同步的到来时(在较窄的高电平到来后,接着就是有效的场同步了【低电平】)开启FIFO的写时使能,这样数据就在行同步与MCU的控制下按照像素时钟依次写入FIFO。当一场图像数据已经进入了FIFO以后,也标志着下一场数据将要来到,也即下一个场同步的上升沿即将到来,当下一个上升沿触发并进入中断后,MCU应该关掉FIFO的写使能,然后开始读FIFO的数据,知道数据读完以后再开始下一次的数据采集。所以调试的第一步是一个正常工作的外中断。我在用STM32调试时由于对其外中断不甚了解,走了些弯路,主要注意刚进外中断时应该先清中断标志再进行中断操作,否则系统可能一直处于中断嵌套中。
再一点是FIFO的读写指针复位。FIFO的这两个指针复位对于数据同步很重要,如果不能正常复位,得到图像会出现移位或畸变。按照FIFO的datasheet,指针的复位分别有两种:Write Reset ,Read Reset;RE RRST,WE WRST。在读复位时我采用的是Read Reste,要求RE和OE都为低,然后在读复位引脚为低时重复两个以上的读时钟。写复位使用的是WE WRST,当WE为高时,拉低写复位引脚,稍微延时后拉高写复位引脚,WE引脚状态不用再管,交由中断程序正常控制,只要记住写复位的时候WE要先为高即可。 |
|