STM32F1之OV7725摄像头·像素数据输出时序、FIFO 读写时序以及摄像头的驱动原理详解

本文主要是介绍STM32F1之OV7725摄像头·像素数据输出时序、FIFO 读写时序以及摄像头的驱动原理详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STM32F1之OV7725摄像头-CSDN博客

STM32F1之I2C通信-CSDN博客

目录

1.  像素数据输出时序

2.  FIFO 读写时序

2.1  写时序

2.2  读时序

3.  摄像头的驱动原理


1.  像素数据输出时序

        主控器控制 OV7725 时采用 SCCB 协议读写其寄存器,而它输出图像时则使用 VGA 或QVGA 时序,其中 VGA 在输出图像分辨率为 480*640 时采用,QVGA 是 Quarter VGA,其输出分辨率为 240*320,这些时序跟控制液晶屏输出图像数据时十分类似。OV7725 传感器输出图像时,一帧帧地输出,在帧内的数据一般从左到右,从上到下,一个像素一个像素地输出(也可通过寄存器修改方向)。

        若我们使用 D2-D9 数据线,图像格式设置为 RGB565,进行数据输出时,D2-D9 数据线在 PCLK 在上升沿阶段维持稳定,并且会在 1 个像素同步时钟 PCLK 的驱动下发送 1 字节的数据信号,所以 2 个 PCLK 时钟可发送 1 个 RGB565 格式的像素数据。当 HREF 为高电平时,像素数据依次传输,每传输完一行数据时,行同步信号HREF 会输出一个电平跳变信号间隔开当前行和下一行的数据;一帧的图像由 N 行数据组成,当 VSYNC 为低电平时,各行的像素数据依次传输,每传输完一帧图像时,VSYNC 会输出一个电平跳变信号。

2.  FIFO 读写时序

        STM32F4 系列的控制器主频高、一般会扩展外部 SRAM、SDRAM 等存储器,且具有DCMI 外设,可以直接根据 VGA 时序接收并存储摄像头输出的图像数据;而 STM32F1 系列的控制器一般主频较低、为节省成本可能不扩展 SRAM 存储器,而且不具 DCMI 外设,难以直接接收和存储 OV7725 图像传感器输出的数据。OV7725 摄像头在图像传感器之外还添加了一个型号为 AL422B 的 FIFO,用于缓冲数据。AL422B 的本质是一种 RAM 存储器,它的容量大小为 393216 字节,支持同时写入和读出数据。

管脚名称
管脚类型
管脚描述
DI[0:7]
输入
数据输入引脚
WCK
输入
数据输入同步时钟
/WE
输入
写使能信号,低电平有效
/WRST
输入
写指针复位信号,低电平有效
DO[0:7]
输出
数据输出引脚
RCK
输入
数据输出同步时钟
/RE
输入
读使能信号,低电平有效
/RRST
输入
读指针复位信号,低电平有效
/OE
输入
数据输出使能,低电平有效
TST
输入
测试引脚,实际使用时设置为低电平

        由于 AL422B 支持同时写入和读出数据,所以它的输入和输出的控制信号线都是互相独立的。写入和读出数据的时序类似,跟 VGA 的像素输出时序一致,读写时序介绍如下:

2.1  写时序

        在写时序中,当 WE 管脚为低电平时,FIFO 写入处于使能状态,随着读时钟 WCK 的运转, DI[0:7]表示的数据将会就会按地址递增的方式存入 FIFO;当 WE 管脚为高电平时,关闭输入,DI[0:7]的数据不会被写入 FIFO。

        在控制写入数据时,一般会先控制写指针作一个复位操作:把 WRST 设置为低电平,写指针会复位到 FIFO 的 0 地址,然后 FIFO 接收到的数据会从该地址开始按自增的方式写入。

2.2  读时序

        FIFO 的读时序类似,不过读使能由两个引脚共同控制,即 OE 和 RE 引脚均为低电平时,输出处于使能状态,随着读时钟 RCK 的运转,在数据输出管脚 DO[0:7]就会按地址递增的方式输出数据。

        类似地,在控制读出数据时,一般会先控制读指针作一个复位操作:把 RRST 设置为低电平,读指针会复位到 FIFO 的 0 地址,然后 FIFO 数据从该地址开始按自增的方式输出。

3.  摄像头的驱动原理

        这里我使用的是野火的OV7725摄像头,其接线如下对于排母部分:

管脚名称
管脚关系
管脚描述
OE
FIFO OE 引脚
数据输出使能,低电平有效
RRST
FIFO RRST 引脚
读指针复位信号,低电平有效
RCLK
FIFO RCK 引脚
数据输出同步时钟
VSYNC
OV7725 VSYNC 引脚
场同步信号
WRST
FIFO WRST 引脚
写指针复位信号,低电平有效
WEN
与下面的 HREF 共同组成与非门的输入
HREF 共同控制 FIFO WE 引脚, WEN 与HREF 同时为高电平时, WE 为低电平, OV7725可以向 FIFO 写入数据
HREF
OV7725 HREF 引脚
行同步信号
DO[0:7]
FIFO DO[0:7] 引脚
数据输出引脚
SIO_C
OV7725 SCL 引脚
SCCB 总线的时钟线
SIO_D
OV7725 SDA 引脚
SCCB 总线的数据线

        通过下图我们可以了解到,与 OV7725 传感器像素输出相关的PCLK 和 D[0:7]并没有引出,因为这些引脚被连接到了 FIFO 的输入部分,OV7725 的像素输出时序与 FIFO 的写入数据时序是一致的,所以在 OV7725 时钟 PCLK 的驱动下,它输出的数据会一个字节一个字节地被 FIFO 接收并存储起来。

        其中最为特殊的是 WEN 引脚,它与 OV7725 的 HREF 连接到一个与非门的输入,与非门的输出连接到 FIFO 的 WE 引脚,因此,当 WEN 与 HREF 均为高电平时,FIFO 的 WE 为低电平,此时允许 OV7725 向 FIFO 写入数据。

        外部控制器通过控制 WEN 引脚,可防止 OV7725 覆盖了还未被控制器读出的旧 FIFO数据。另外,在 OV7725 输出时序中,只有当 HREF 为高电平时,PCLK 驱动下 D[0:7]线表示的才是有效像素数据,因此,利用 HREF 控制 FIFO 的 WE 可以确保只有有效数据才被写入到 FIFO 中。

摄像头采集数据的过程如下:

(1) 利用 SIO_C、SIO_D 引脚通过 SCCB 协议向 OV7725 的寄存器写入初始化配置;

(2) 初始化完成后,OV7725 传感器会使用 VGA 时序输出图像数据,它的 VSYNC 会首先输出帧有效信号(低电平跳变),当外部的控制器(如 STM32)检测到该信号时,把 WEN 引脚设置为高电平,并且使用 WRST 引脚复位 FIFO 的写指针到 0 地址;

(3) 随着 OV7725 继续按 VGA 时序输出图像数据,它在传输每行有效数据时, HREF引脚都会持续输出高电平,由于 WEN 和 HREF 同时为高电平输入至与非门,使得其连接到 FIFO WE 引脚的输出为低电平,允许向 FIFO 写入数据,所以在这期间,OV7725 通过它的 PCLK 和 D[0:7]信号线把图像数据存储到 FIFO 中,由于前面复位了写指针,所以图像数据是从 FIFO 的 0 地址开始记录的;

(4) 各行图像数据持续传输至 FIFO,受 HREF 控制的 WE 引脚确保了写入到 FIFO 中的都是有效的图像数据,OV7725 输出完一帧数据时,VSYNC 会再次输出帧有效信号,表示一帧图像已输出完成;

(5) 控制器检测到上述 VSYNC 信号后,可知 FIFO 中已存储好一帧图像数据,这时控制 WEN 引脚为低电平,使得 FIFO 禁止写入,防止 OV7725 持续输出的下一帧数据覆盖当前 FIFO 数据;

(6) 控制器使用RRST复位读指针到FIFO的0地址,然后通过FIFO的RCLK和DO[0:7]引脚,从 0 地址开始把 FIFO 缓存的整帧图像数据读取出来。在这期间,OV7725是持续输出它采集到的图像数据的,但由于禁止写入 FIFO,这些数据被丢弃了;

(7) 控制器使用 WRST 复位写指针到 FIFO 的 0 地址,然后等待新的 VSYNC 有效信号到来,检测到后把 WEN 引脚设置为高电平,恢复 OV7725 向 FIFO 的写入权限,OV7725 输出的新一帧图像数据会被写入到 FIFO 的 0 地址中,重复上述过程。

        把 OV7725 配置为 240*320 分辨率(QVGA),RGB565 格式,那么 OV7725 输出一帧的图像大小为 240*320*2=153600 字节,而本摄像头采用的 FIFO 型号 AL422B 容量为 393216 字节,最多可以缓存 2 帧这样的图像,通过这样的方式,STM32 无需直接处理 OV7725 高速输出的数据。但是,如果配置 OV7725为 480*640 分辨率时,其一帧图像大小为 480*640*2=614400 字节,FIFO 的容量不足以直接存储一帧这样的图像,因此,当 OV7725 往 FIFO 写数据的时候,STM32 端要同时读取数据,确保在 OV7725 覆盖旧数据的之前,STM32 端已经把这部分数据读取出来了。

这篇关于STM32F1之OV7725摄像头·像素数据输出时序、FIFO 读写时序以及摄像头的驱动原理详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1004285

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1