CMOS摄像头(4):SDRAM和乒乓操作

  OV7670/OV7725/OV5640开发记录终于到最后一讲了,还是蛮累的。

、SDRAM缓存处理

  很多摄像头工程都用到了SDRAM作为中间缓存,很多人一脸懵逼,我也是思考了好一阵才明白。先假设 OV5640 和 VGA 直接相连,中间不采用任何缓存器件,那会出现什么情况呢?

  OV5640 的帧率为 30fps, VGA 的帧率为 60fps,且时钟也完全不一样。假设分辨率是 3x2 = 6,数据为:1,2,3,4,5,6。OV5640 帧率小,生成一个像素的时间假设是2秒,而 VGA 帧率大,需要一个像素的时间假设是 1s。在 6s 的时间里,VGA就请求了一帧数据,可这个时间里 OV5640 只生成了1,2,3共三个像素,VGA那边就出现了空数据的情况。在 12s 的时间里,VGA 请求了两帧数据,可这个时间里 OV5640 只生成了一帧数据,怎么来说都是错的。上述假设是简化了时间点,实际情况是 OV5640 生成像素和 VGA 请求像素的时间不一致,导致VGA总是要不到一帧图像正确的数据,也要不全一帧图像正确的数据。因此,OV5640 和 VGA 之间需要加入一个缓存器件,用于缓存一帧的数据,这样 VGA 每次要一帧数据都可以被满足。加入缓存器件的根本原因就是两端时钟不一致,导致读写速率不一致。

  采用什么缓存器件呢?FIFO 和 RAM 是最常用的,但是一帧的图像数据往往是 640x480、1280x768、1920x1280,每个像素是 16bit。数据量大,FPGA的片内资源无法满足。因此需要引入外部缓存器件,如 SDRAM、DDR2、DDR3等。

 

二、无乒乓操作

  SDRAM 正常使用其实是无乒乓操作,无乒乓操作是考虑不周的,除非一帧图像是瞬间生成,OV5640 帧率 30fps,VGA 帧率 60fps,仿佛刚好可以写一帧读两帧。但是一帧图像实际情况是一行行的生成和读取的,所以会出现 VGA 从SDRAM处读的上半帧是新帧,而由于SDRAM缓存的下半帧还没有被 OV5640 写完,VGA 从SDRAM处读的下半帧还是老帧。示意图如下所示,红线为写,黑线为读。

  将上述 5 帧图像生成的时间点编号为 t1、t2、t3、t4、t5。在 t1、t3、t5 时刻图像都是残缺帧(新老帧参半),在 t2、t4 时刻图像才是完整的一帧,而 VGA 那边可不管,每个时间点都会要一帧图像,这就是错帧现象。而解决错帧现象的方法则是乒乓操作。

 

三、乒乓操作

1、乒乓操作原理

  乒乓操作,使用两个缓存区,写缓存区 1 时读缓存区 2,写缓存区 2 时读缓存区 1,读写交替。示意图如下,红线为写,黑线为读。

  由示意图可以看出,乒乓操作中,每次读的(黑线)都是完整的帧,每一帧读 2 次,这样便没有出现读残缺帧的现象,解决了错帧问题。

2、乒乓操作设计

  在上述设计中,由于写读速率为1:2,所以写一帧读两帧即可,但是很多时候写读速率的比例是其他数值,那怎么办呢?

  (1)写端在缓存区1写完一帧数据就切换到缓存区2写下一帧,写完后又切换回缓存区1写再下一帧,如此反复。

  (2)读端在缓存区2读完一帧:

    ①如果写端仍然在缓存区1,则读端不切换缓存区,而是继续在缓存区2重读一帧。

    ②如果写端离开了缓存区1,即切换到缓存区2了,说明写端已经在缓存区1写完了,则读端可以切换到缓存区1。这样就能保证读端每次读的都是完整的帧,就算有一小段时间是读写端都在同一个缓存区,但是由于写慢读快,写是不会追上读的,读还是能读完旧帧,之后旧帧才被新帧覆盖。

  写慢读快这样设计就行,那如果写快读慢呢?其实也是一样的思想,反过来即可。无论谁快谁慢,都是快端照顾慢端,即慢端一帧结束就离开自身缓存区到另一缓存区。快端则一帧结束后,先检测慢端是否离开自身缓存区,是则切换过去,否则不切换过去,而是重新在自身缓存区再工作一帧。示意图如下所示:

3、SDRAM乒乓操作

  用两片SDRAM来进行乒乓操作有些太浪费了,可以直接利用SDRAM里面的bank进行乒乓操作即可。虽然读写只有一根总线,但是SDRAM时钟高,读写足够快,可以满足乒乓操作的需求。具体实现可以看这篇博客《DDR2(5):DDR2自动读写控制器》,虽然是 DDR2,但道理是一样的。

 

 参考资料:

[1]正点原子FPGA教程

[2]小梅哥《OV5640图像采集从原理到应用》

[3]开源骚客《SDRAM那些事儿》

[4]韩彬, 于潇宇, 张雷鸣. FPGA设计技巧与案例开发详解[M]. 电子工业出版社, 2014.

 

posted @ 2020-02-08 15:31  咸鱼IC  阅读(7047)  评论(0编辑  收藏  举报