基于 OV2640 的图像采集显示系统(camera_init 摄像头初始化模块)

news2025/1/12 10:07:45

此部分可参考IIC系列文章:
(1)I2C 接口控制器理论讲解
(2)I2C接口控制设计与实现
(3)I2C连续读写实现

文章目录

  • 前言
  • 一、OV2640 摄像头初始化模块设计思路
  • 二、OV2640 摄像头初始化模块用法介绍
  • 三、复位时序设计
  • 四、数据写入操作
  • 五、数据查找表
  • 六、完整代码展示
  • 六、仿真代码展示
  • 七、仿真结果展示


前言

本节将在实验“基于 DDR3 的串口传图帧缓存系统设计”实现一个图像采集显示应用系统,来设计 OV2640 应用系统中所需的基本应用逻辑电路。

提示:以下是本篇文章正文内容,下面案例可供参考

一、OV2640 摄像头初始化模块设计思路

所谓的 OV2640 摄像头初始化模块,其工作就是完成对 OV2640 中众多模式设置寄存器的写入操作。本质上就是使用 I2C 控制器将一些预先定义好的数据值写入到 OV2640 对应的寄存器中。所以我们完全可以使用之前设计好的 I2C 控制器加上一个存储好所有 OV2640 所需设置的寄存器参数的查找表,配合一定的控制逻辑实现,该设计实际比较简单。下图为我们设计的一个比较通用的 OV2640 初始化逻辑电路。
1
图 中 例 化 了 设 计 好 的 通 用 I2C 控 制 器 ( i2c_control )【参考文章最上方的i2c_control 文章】 和 一 个 ROM 查 找 表( camera_init_table ), 在 camera_init 顶 层 逻 辑 中 , 通 过 简 单 的 状 态 机 循 环 读 取camera_init_table 中的数据值并通过 i2c_control 即可写入到 OV2640 的各个寄存器中。

二、OV2640 摄像头初始化模块用法介绍

使用时,仅需在整个系统顶层例化的时候加入如下代码即可

camera_init
 #(
 .IMAGE_TYPE ( 0 ),// 0: RGB; 1: JPEG
 .IMAGE_WIDTH ( IMAGE_WIDTH ),// 图片宽度
 .IMAGE_HEIGHT( IMAGE_HEIGHT ),// 图片高度
 .IMAGE_FLIP ( 0 ),// 0: 不翻转,1: 上下翻转
 .IMAGE_MIRROR( 0 ) // 0: 不镜像,1: 左右镜像
 )camera_init
 (
 .Clk (loc_clk50m ),
 .Rst_p (g_rst_p ),
 .Init_Done (camera_init_done ),
 .camera_rst_n(camera_rst_n ),
 .camera_pwdn ( ),
 .i2c_sclk (camera_sclk ),
 .i2c_sdat (camera_sdat )
 );

在代码中,加入了几个参数定义,每个参数对应了 OV5640 使用时的一个常用模式。现就这几个模式参数分别介绍如下。
1
使用时,关于控制图像的类型、分辨率、翻转、镜像,可以通过修改#后面括号里面的对应内容。根据这些设置,camera_init.v 中通过条件编译的方式选择性的编译代码,从而达到通过参数设置不同工种模式的目的。整个条件编译主要分为两个分支,一个是图像类型为 RGB 类型的分支,另外一个是 JPEG 类型的分支。每个分支里面又根据不同的参数设置来控制图片的翻转和镜像,所以有四种组合,为了匹配四种模式,这里使用了 generate-if语句来实现。以下是部分代码:

generate
  ov5640///
  if(CAMERA_TYPE == "ov2640")
		  begin
					assign device_id = 8'h60;
					assign addr_mode = 1'b0;
					assign addr = {
   8'd0, lut[15:8]};
					assign wrdata = lut[7:0];

					if(IMAGE_TYPE == RGB) //------RGB------
								begin
								  assign lut_size = 185;

								  ov2640_init_table_rgb #(
									.IMAGE_WIDTH     (IMAGE_WIDTH     ),
									.IMAGE_HEIGHT    (IMAGE_HEIGHT    ),
									.IMAGE_FLIP_EN   (IMAGE_FLIP_EN   ),
									.IMAGE_MIRROR_EN (IMAGE_MIRROR_EN )
								  )ov2640_init_table_rgb_inst
								  (
									.addr (cnt ),
									.clk  (Clk ),
									.q    (lut )
								  );
								end
					else  //------JPEG------
								begin
								  assign lut_size = 250;

								  ov5640_init_table_jpeg #(
									.IMAGE_WIDTH     (IMAGE_WIDTH     ),
									.IMAGE_HEIGHT    (IMAGE_HEIGHT    ),
									.IMAGE_FLIP_EN   (IMAGE_FLIP_EN   ),
									.IMAGE_MIRROR_EN (IMAGE_MIRROR_EN )
								  )ov5640_init_table_jpeg_inst
								  (
									.addr (cnt ),
									.clk  (Clk ),
									.q    (lut )
								  );
								end
		   end
  ov7725
		  else if(CAMERA_TYPE == "ov7725")
				  begin
							assign device_id = 8'h42;
							assign addr_mode = 1'b0;
							assign addr = lut[15:8];
							assign wrdata = lut[7:0];

							if(IMAGE_TYPE == RGB) //------RGB------
									begin
									  assign lut_size  = 68;

									  ov7725_init_table_rgb #(
										.IMAGE_WIDTH     (IMAGE_WIDTH     ),
										.IMAGE_HEIGHT    (IMAGE_HEIGHT    ),
										.IMAGE_FLIP_EN   (IMAGE_FLIP_EN   ),
										.IMAGE_MIRROR_EN (IMAGE_MIRROR_EN )
									  )ov7725_init_table_rgb_inst
									  (
										.addr (cnt ),
										.clk  (Clk ),
										.q    (lut )
									  );
									end
				  end
  endgenerate



/













三、复位时序设计

设计合理的复位时序,有助于正确的让 OV2640 进入正常工作状态。复位时序在大家设计时经常不被关注,但是却经常直接导致了设计的不成功,所以这里介绍下 OV2640 的复位时序设计。
一般的器件都会在其 datasheet 中提供其上电和复位时序要求,OV2640 也不例外,下图为 OV2640 器件手册中提供的 OV5640 的上电复位时序图。

1

根据手册描述:
 PWDN 信号为掉电控制信号,当该引脚为高电平时整个图像传感器的模拟和数字部分都处于掉电不工作状态,为低电平时整个器件才可以开始工作;
 如果不希望控制 PWDN 信号,则该信号可以直接接到低电平;
 如果需要控制 PWDN 信号,则需要在上电至少 5ms 之后再拉低 PWDN。
 RESET 信号为复位信号,低电平复位。
 RESET 引脚必须在上电稳定后保持 t3(1ms)时间后才能变为高电平让整个系统开始工作。
 SCCB 接口工作需要在复位信号拉高 t4(20ms)时间之后才能开始工作
 XCLK 信号必须在 SCCB 接口正常工作之前 1ms 就就绪,换句话说,如果 XCLK 没有正常提供,OV5640 的 SCCB 接口也将无法正常的读写寄存器。

据此可以总结出对于 OV5640 的从上电到开始读写寄存器的一个基本的控制顺序:
1、 PWDN 和 RESET 都为低电平。
2、 等待 PWDN
3、 等待至少 1ms 的时间,此期间 RESET 一直为低电平,然后拉高 RESET 信号
4、 RESET 拉高之后,再等待至少 20ms 的时间
5、 开始通过 SCCB 读写 OV5640 的寄存器
6、 XVCLK 提前操作 SCCB 的 1ms 时间一般都能满足,所以一般情况下可以不用关心。

在实际设计时,只需要使用一个计数器即可实现。以下为 camera_init 代码中设计的复位时序的相关代码。

//-------------------------------------------------------------------------------------------------------------------
  //上电并复位完成 20ms 后再配置摄像头,这里为了优化逻辑,直接使延迟比较值为 21'h1007ff,大约21.012460ms
  //上电到摄像头复位时间为1ms ,这里为简便设置为20'h00C400,为1.003520ms
  wire Go;   //initial enable
	reg [20:0] delay_cnt;
	always @ (posedge Clk or negedge Rst_n)
	if (!Rst_n)
		delay_cnt <= 20'd0;
	else if (delay_cnt == 21'h100800)
		delay_cnt <= delay_cnt;
	else
		delay_cnt <= delay_cnt + 1'd1;
	
	assign Go = (delay_cnt == 21'h1007ff) ? 1'b1 : 1'b0;
	assign camera_rst_n = (delay_cnt > 21'h00C400);
//-------------------------------------------------------------------------------------------------------------------

四、数据写入操作

/-------------------------------------------------------------------------------------------------------------------
//状态机产生wrreg_req、与延时i2c_dly_cnt_max信号

  reg [1:0]state;

  always@(posedge Clk or negedge Rst_n)
  if(~Rst_n)begin
    state <= 0;
    wrreg_req <= 1'b0;
    i2c_dly_cnt_max <= 32'd0;
  end
  else if(cnt < lut_size)begin
    case(state)
      0:
        if(Go)
          state <= 1;
        else
          state <= 0;
      1:
        begin
          wrreg_req <= 1'b

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/945310.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VIT 和Swin Transformer

VIT&#xff1a;https://blog.csdn.net/qq_37541097/article/details/118242600 Swin Transform&#xff1a;https://blog.csdn.net/qq_37541097/article/details/121119988 一、VIT 模型由三个模块组成&#xff1a; Linear Projection of Flattened Patches(Embedding层) Tran…

中文情感分类

本文通过ChnSentiCorp数据集介绍了文本分类任务过程&#xff0c;主要使用预训练语言模型bert-base-chinese直接在测试集上进行测试&#xff0c;也简要介绍了模型训练流程&#xff0c;不过最后没有保存训练好的模型。 一.任务和数据集介绍 1.任务 中文情感分类本质还是一个文本…

会员管理系统实战开发教程05-会员开卡

上一篇我们讲解了如何点击按钮弹出层&#xff0c;已经罗列了会员管理的一些常见功能。本篇我们介绍一下会员开卡的业务。 1 创建变量 我们会员开卡的业务的话&#xff0c;也是要在本页面弹出&#xff0c;弹出其实只是让组件是否显示和隐藏&#xff0c;我们先定义一个布尔值类…

柠檬水找零【贪心算法-】

柠檬水找零 在柠檬水摊上&#xff0c;每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品&#xff0c;&#xff08;按账单 bills 支付的顺序&#xff09;一次购买一杯。 每位顾客只买一杯柠檬水&#xff0c;然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零&…

读书笔记-《ON JAVA 中文版》-摘要23[第二十章 泛型-2]

文章目录 第二十章 泛型5. 泛型擦除5.1 泛型擦除5.2 迁移兼容性5.3 擦除的问题5.4 边界处的动作 6. 补偿擦除7. 边界8. 通配符8.1 通配符8.2 逆变 9. 问题10. 动态类型安全11. 泛型异常 第二十章 泛型 普通的类和方法只能使用特定的类型&#xff1a;基本数据类型或类类型。如果…

驱动代码验证

要求 代码 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h>int main(int argc,const char * a…

移动端h5项目的兼容和适配问题

解决兼容性问题的关键在于对移动端产品的生存环境进行梳理&#xff0c;在此基础之上制定应对策略。 所谓生存环境主要分为三个维度&#xff1a; 硬件环境&#xff0c;细分为品牌和机型&#xff0c;决定了屏幕大小、性能等硬件限制 操作系统&#xff0c;比如iOS6和iOS7&#xf…

Redis数据类型(list\set\zset)

"maybe its why" List类型 列表类型是⽤来存储多个有序的字符串&#xff0c;列表中的每个字符串称为元素&#xff08;element&#xff09;&#xff0c;⼀个列表最多可以存储个2^32 - 1个元素。在Redis中&#xff0c;可以对列表两端插⼊&#xff08;push&#xff09…

555定时器

一、定义 定时器是一种多用途的数字-模拟混合集成电路&#xff0c;可极方便的构成施密特触发器、单稳态触发器和多谐振荡器&#xff0c;其简化原理图及引脚定义如下所示 3个绿色电阻&#xff0c;电阻值为5K&#xff1b;2个黄色和粉色比较器&#xff1b;1个紫色SR触发器&#x…

WPF实战项目十三(API篇):备忘录功能api接口、优化待办事项api接口

1、新建MenoDto.cs /// <summary>/// 备忘录传输实体/// </summary>public class MenoDto : BaseDto{private string title;/// <summary>/// 标题/// </summary>public string Title{get { return title; }set { title value; }}private string con…

实验三十一、OCL 电路输出功率和效率的研究

一、题目 研究 OCL 功率放大电路的输出功率和效率。 二、仿真电路 OCL 功率放大电路如图1所示。 图 1 OCL 功率放大电路 图1\,\,\,\textrm{OCL}\,功率放大电路 图1OCL功率放大电路图中采用 NPN 型低频功率晶体管 2SC2001&#xff0c;其参数为&#xff1a; I C M 700 mA I_…

5G NR:RACH流程 -- Msg1之选择正确的PRACH时频资源

PRACH的时域资源是如何确定的 PRACH的时域资源主要由参数“prach-ConfigurationIndex”决定。拿着这个参数的取值去协议38211查表6.3.3.2-2/3/4&#xff0c;需要注意根据实际情况在这三张表中进行选择&#xff1a; FR1 FDD/SULFR1 TDDFR2 TDD Random access preambles can onl…

信号和槽的相关操作

目录 信号和槽 connect()函数 自定义信号槽 例子 自定义信号槽需要注意的事项 信号槽的更多用法 Lambda表达式 ① 函数对象参数 ② 操作符重载函数参数 ③ 可修改标示符 ④ 错误抛出标示符 ⑤ 函数返回值 ⑥ 是函数体 所谓信号槽&#xff0c;实际就是观察者模式。当…

AVS3变换:PBT、ST和SBT

前面的文章介绍了AVS3中的变换工具IST和ISTS&#xff0c;本文将介绍AVS3中剩余的几种变换工具&#xff1a;基于位置的变换&#xff08;PBT,Position Based Transform&#xff09;、二次变换&#xff08;ST, Secondary Transform&#xff09;和子块变换&#xff08;SBT, Sub-Blo…

SmartInspect Professional .Net Delphi Crack

SmartInspect Professional .Net & Delphi Crack SmartInspect Professional是一个用于调试和跟踪.NET、Java和Delphi软件的高级日志记录工具。它使您能够识别错误&#xff0c;找到客户问题的解决方案&#xff0c;并让您清楚地了解软件在不同环境和条件下的工作方式。可以轻…

给oracle逻辑导出clob大字段、大数据量表提提速

文章目录 前言一、大表数据附&#xff1a;查询大表 二、解题思路1.导出排除大表的数据2.rowid切片导出大表数据Linux代码如下&#xff08;示例&#xff09;&#xff1a;Windows代码如下&#xff08;示例&#xff09;&#xff1a;手工执行代码如下&#xff08;示例&#xff09;&…

java八股文面试[多线程]——Synchronized的底层实现原理

笔试&#xff1a;画出Synchronized 线程状态流转实现原理图 synchronized关键字解决的是多个线程之间访问资源的同步性&#xff0c;synchronized 翻译为中文的意思是同步&#xff0c;也称之为”同步锁“。 synchronized的作用是保证在同一时刻&#xff0c; 被修饰的代码块或方…

任意文件上传

文章目录 渗透测试漏洞原理任意文件上传1. 任意文件上传概述1.1 漏洞成因1.2 漏洞原理1.3 漏洞危害1.4 漏洞的利用方法1.5 漏洞的验证 2. WebShell解析2.1 Shell2.1.1 命令解释器 2.2 WebShell2.2.1 大马2.2.2 小马2.2.3 GetShell2.2.4 WebShell项目 3. 任意文件上传攻防3.1 毫…

注册字符设备

五、注册字符设备 struct cdev {struct kobject kobj;//表示该类型实体是一种内核对象struct module *owner;//填THIS_MODULE&#xff0c;表示该字符设备从属于哪个内核模块const struct file_operations *ops;//指向空间存放着针对该设备的各种操作函数地址struct list_head …

RAD Installer Crack,集成到RAD Studio IDE支持

RAD & Installer Crack,集成到RAD Studio IDE支持 用于创建NSIS和Inno Setup安装程序的RAD Studio扩展。它将NSIS(Nullsoft Scriptable Install System)和Inno Setup与Embarcadero RAD Studio IDE结合在一起。它允许您在RAD Studio中设计和构建NSIS和Inno Setup项目&#x…