打印
[应用相关]

STM32驱动OV7670摄像头总结

[复制链接]
7216|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 chenqiang10 于 2018-6-11 19:05 编辑

OV7670模块:
     介绍一下OV7670传感器:CMOS器件;标准的SCCB接口,兼容IIC接口;内置感光阵列,时序发生器,AD转换器,模拟信号处理,数字信号处理器.....
     大致工作过程:光照射到感光阵列产生相应电荷,传输到相应的模拟信号处理单元,再由AD转换为数字信号,在经由数字信号处理器插值到RGB信号,最后传输到屏幕上......
沙发
chenqiang10|  楼主 | 2018-6-11 18:52 | 只看该作者
本帖最后由 chenqiang10 于 2018-6-11 19:09 编辑

    先了解一下基础知识:现在市面上的OV7670模块分两种:1、带FIFO芯片;2、不带FIFO芯片。当然带FIFO的要贵一点~下面介绍带FIFO和不带FIFO的工作原理




使用特权

评论回复
板凳
chenqiang10|  楼主 | 2018-6-11 18:53 | 只看该作者
本帖最后由 chenqiang10 于 2018-6-11 19:13 编辑

不带FIFO:这种方法最简单,最直接,但是最不好实现的方法,原因是多数的CMOS芯片(如OV7670)的时钟速度可以高达24M,一般单片机的IO口速度根本达不到(stm32的IO速度,寄存器比库函数快,博主之前测,用库函数IO口速度好像是2.5Mhz,而用寄存器IO口速度是8M吧,速度相差较大~)。当然,高级的MCU,如ARM9以上或者DSP图像处理芯片等,本身处理速度快,内存大而且有的还带camera接口,可以不用带FIFO。

使用特权

评论回复
地板
chenqiang10|  楼主 | 2018-6-11 19:12 | 只看该作者
但也不是不是完全没有办法在低速上实现采集,方法也很简单,那么就是降低CMOS 的输出速度,不过这需要靠外部的晶振和内部的PLL 电路以及像素时钟速度,帧速等多个寄存器共同设置,并且要和MCU 的IO 速度匹配才可实现。但不建议这么做,原因是:这种寄存器设置将带来更多的学习困难和理解困难,并导致硬件图像的采集速度可能下降到0.5 帧以下,同时带来图像失真的可能。

使用特权

评论回复
5
chenqiang10|  楼主 | 2018-6-11 19:15 | 只看该作者
还有一种方法就是DMA方式采集,代码复杂,速度在5-10帧左右。本来打算用该方法的,DMA没怎么学,也怕调试困难,就没在折腾了。

使用特权

评论回复
6
chenqiang10|  楼主 | 2018-6-11 19:16 | 只看该作者
有些CMOS 时钟速度不快,可以用单片机IO直接采集,例如OV7660,不幸的是该芯片已经停产。

使用特权

评论回复
7
chenqiang10|  楼主 | 2018-6-11 19:16 | 只看该作者
带FIFO:由于采用了FIFO 做为数据缓冲,数据采集大大简便,用户只需要关心是如何读取即可,不需要关心具体数据是如何采集到的,这样可减小甚至不用关心CMOS 的控制以及时序关系,就能够实现图像的采集。

使用特权

评论回复
8
chenqiang10|  楼主 | 2018-6-11 19:17 | 只看该作者
需要注意的是:FIFO不具备地址功能,因此他也就不具备数据的定位(选址)读取功能,所以不可能有真正的数据处理能力!

使用特权

评论回复
9
chenqiang10|  楼主 | 2018-6-11 19:18 | 只看该作者
总的来说:带FIFO比不带FIFO操作起来更简单,8位MCU也能胜任。
下面我们参考正点原子战舰摄像头实验(带FIFO的OV7670模块)

使用特权

评论回复
10
chenqiang10|  楼主 | 2018-6-11 19:20 | 只看该作者
本帖最后由 chenqiang10 于 2018-6-11 19:22 编辑

OV7670的图像数据输出格式,参考战舰开发指南。
  VGA:分辨率为640*480的输出模式
  QVGA:分辨率为320*240的输出格式
  QQVGA:分辨率为160*120的输出格式  
  PCLK:像素时钟,一个PCLK时钟,输出1个像素或半个像素
  VSYNC:帧同步信号

  HREF/HSYNC:行同步信号

使用特权

评论回复
11
chenqiang10|  楼主 | 2018-6-11 19:28 | 只看该作者
本帖最后由 chenqiang10 于 2018-6-11 19:31 编辑

行输出时序






使用特权

评论回复
12
chenqiang10|  楼主 | 2018-6-11 19:32 | 只看该作者
图像数据在HREF为高的时候输出,当HREF变高后,每一个PCLK时钟,输出一个字节数据。比如我们采用VGA时序,RGB565格式输出,每两个字节组成一个像素的颜色(高字节在前,低字节在后),这样每行输出总共有640*2个PCLK周期,输出640*2个字节。

使用特权

评论回复
13
chenqiang10|  楼主 | 2018-6-11 19:33 | 只看该作者
帧时序

使用特权

评论回复
14
chenqiang10|  楼主 | 2018-6-11 19:35 | 只看该作者
VSYNC位高时产生一个帧同步信号,故当产生两个帧同步信号时,一帧数据输出完成。注意:图中的HSYNC和HREF其实是一个引脚产生的信号,只是在不同的场合下面,使用不同的信号方式。

使用特权

评论回复
15
chenqiang10|  楼主 | 2018-6-11 19:37 | 只看该作者
本帖最后由 chenqiang10 于 2018-6-11 19:41 编辑

战舰OV7670模块原理图讲解










使用特权

评论回复
16
chenqiang10|  楼主 | 2018-6-11 19:42 | 只看该作者
存储和读取图像数据的过程及程序讲解(参考原子哥的开发指南和代码)
对于该模块,我们只关心两点:1、如何存储图像数据;2、如何读取图像数据

使用特权

评论回复
17
chenqiang10|  楼主 | 2018-6-11 19:43 | 只看该作者
1、存储(OV7670往FIFO中写数据)
       战舰OV7670模块存储图像数据的过程为:等待OV767同步信号->FIFO写指针复位->FIFO写使能->等待第二个同步信号->FIFO写禁止,通过以上5个步骤就可以完成一帧图像的存储
2、读取(MCU从FIFO中读取数据)
       读取过程:FIFO读指针复位->给FIFO读时钟(FIFO RCLK)->读取第一个像素高字节->给FIFO读时钟(FIFO RCLK)->读取第一个像素低字节->给FIFO读时钟(FIFO RCLK)->读取第二个像素高字节->循环读取剩余像素->结束
       比如QVGA模式,RGB565格式,我们总共循环读取320*240*2次,就可以读取一帧数据,把这些数据写入LCD模块,就可以看到摄像头的画面了。

使用特权

评论回复
18
chenqiang10|  楼主 | 2018-6-11 19:45 | 只看该作者
本帖最后由 chenqiang10 于 2018-6-11 20:02 编辑

程序讲解:(主要是OV7670对FIFO的写控制和MCU从FIFO中读取数据)
1、利用外部中断来对OV7670进行写操作控制

使用特权

评论回复
19
chenqiang10|  楼主 | 2018-6-11 20:03 | 只看该作者
MCU从FIFO中读取数据(更新LCD显示)

使用特权

评论回复
20
chenqiang10|  楼主 | 2018-6-11 20:04 | 只看该作者
此**转载 https://blog.csdn.net/houqi02/article/details/51712994,欢迎大家学习。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

39

主题

940

帖子

1

粉丝