【FPGA-AC620V2】基于USB2.0高速数据传输模块的RGB摄像头实验-学习记录

🎉欢迎来到FPGA专栏~基于FPGA的RGB摄像头实验


  • ☆* o(≧▽≦)o *☆~我是小夏与酒🍹
  • 博客主页:小夏与酒的博客
  • 🎈该系列文章专栏:FPGA学习之旅
  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • 📜 欢迎大家关注! ❤️
    FPGQ2

CSDN

遇见未来

一、效果演示

效果展示1

来自于小梅哥【学习资料】:
数字图像处理是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。图像处理最早出现于20世纪50年代,当时的电子计算机已经发展到一定水平,人们开始利用计算机来处理图形和图像信息。数字图像处理作为一门学科大约形成于20世纪60年代初期。早期的图像处理的目的是改善图像的质量,它以人为对象,以改善人的视觉效果为目的。图像处理中,输入的是质量低的图像,输出的是改善质量后的图像,常用的图像处理方法有图像增强、复原、编码、压缩等。
数字图像处理常用方法有以下几种:
1、图像变换
2、图像编码压缩
3、图像增强和复原
4、图像分割
5、图像描述
6、图像分类(识别)

二、项目说明

该系列文章只是作为学习记录,并无其余用途。所发文章内容是经过自己本身操作和记录整理得来。

本篇文章记录基于ACM68013模块的OV5640 RGB摄像头实验

🥝项目资料获取

该项目资料获取:基于ACM68013模块的OV5640 RGB摄像头实验

项目资料详细内容:
开发文件夹
ACM68013模块资料:
模块资料

🥝实验硬件

本次文章中所使用到的硬件为:AC620V2开发板、ACM68013模块和OV5640摄像头模块

实验所需硬件如下图所示:
硬件展示1

❤️特别鸣谢:小梅哥FPGA
📜硬件购买链接及详细介绍:
🔸【FPGA】USB2.0高速通信模块:ACM68013模块
🔸【FPGA】OV5640高清摄像头模块:OV5640摄像头模块

🔸更多资料和模块请前往淘宝店铺:小梅哥FPGA

🥝项目分析

系统整体设计如下图所示(来自于项目资料中的PDF文档):
整体设计

以下是资料中对于各部分作用的介绍:

  1. PLL模块:锁相环模块,生成本次实验每个模块所需要的工作时钟,其中输入时钟为 50M 的系统时钟,由开发板上的晶振提供,输出 24M 的时钟给到摄像头模块使用,输出 50M 的时钟给其他模块使用。
  2. usb_stream_out 模块:USB 数据流发送控制模块,不断的将端点 2 中的数据读取出来,数据读取后直接作为端口输出。
  3. usb_cmd 模块:接收转命令模块,对 USB 接收到的数据进行分析,提取出每个控制命令帧。
  4. usb_cmd_rx 模块:指令转控制模块,将从接收转命令模块接收到的数据转换为相应的控制 USB 启动传输的信号。
  5. camera_init 模块:摄像头初始化模块,完成对 OV5640 众多模式设置寄存器的写入操作。
  6. DVP_Capture 模块:实现每两个数据拼接为 1 个 16 位的数据并按照写RAM 或 FIFO 的接口形式输出。
  7. usb_send_ctrl模块:USB数据输出控制模块,控制 USB 启动传输和USB FIFO 的清除工作。
  8. usb_stream_in模块:USB数据流发送模块,将采集到的数据通过USB发送出去。

其中,模块fx2_stream_in_ov5640的内容为:

/
// Module Name   : fx2_stream_in_ov5640
// Description   : 摄像头采集,USB发送
/

module fx2_stream_in_ov5640(
  //System clock reset
  input       clk50m        , //系统时钟输入,50MHz
  input       reset_n       , //复位信号输入
  //usb interface
  output      fx2_clear     , //连接USB模块的PA0
  usb_ctrl
  inout [15:0]fx2_fdata     ,
  input       fx2_flagb     ,
  input       fx2_flagc     ,
  input       fx2_ifclk     ,
  
  output [1:0]fx2_faddr     ,
  output      fx2_sloe      ,
  output      fx2_slwr      ,
  output      fx2_slrd      ,
  output      fx2_pkt_end   , 
  output      fx2_slcs      ,
  //camera interface
  output      camera_sclk   ,
  inout       camera_sdat   ,
  input       camera_vsync  ,
  input       camera_href   ,
  input       camera_pclk   ,
  output      camera_xclk   ,
  input  [7:0]camera_data   ,
  output      camera_rst_n  ,
  output      camera_pwdn   ,
  //led
  output [1:0]led         
);
  //*****************************
  //Set IMAGE Size  
  parameter IMAGE_WIDTH  = 800;
  parameter IMAGE_HEIGHT = 480;
  //*****************************
  //clock
  wire          pll_locked;
  wire          loc_clk50m;
  wire          loc_clk24m;
  //reset
  wire          g_rst_p;
  //camera interface
  wire          camera_init_done;
  wire          pclk_bufg_o;
  wire [15:0]   image_data;
  wire          image_data_valid;
  wire          image_data_hs;
  wire          image_data_vs;
  wire [11:0]   image_data_xaddr;
  wire [11:0]   image_data_yaddr;

  reg           pixel_data_valid;
  reg  [15:0]   pixel_data;
  
  //USB Ctrl
  wire [1:0]fx2_faddr0;//FX2型USB2.0芯片的SlaveFIFO的FIFO地址线
  wire fx2_slrd0;//FX2型USB2.0芯片的SlaveFIFO的读控制信号,低电平有效
  wire fx2_slwr0;//FX2型USB2.0芯片的SlaveFIFO的写控制信号,低电平有效
  wire fx2_sloe0;//FX2型USB2.0芯片的SlaveFIFO的输出使能信号,低电平有效
  wire fx2_flagc0;//FX2型USB2.0芯片的端点6满标志
  wire fx2_flagb0; //FX2型USB2.0芯片的端点2空标志
  wire fx2_pkt_end0;//数据包结束标志信号
  wire fx2_slcs0;
  
  wire [15:0]fx2_fdata1;
  wire [1:0]fx2_faddr1;//FX2型USB2.0芯片的SlaveFIFO的FIFO地址线
  wire fx2_slrd1;//FX2型USB2.0芯片的SlaveFIFO的读控制信号,低电平有效
  wire fx2_slwr1;//FX2型USB2.0芯片的SlaveFIFO的写控制信号,低电平有效
  wire fx2_sloe1;//FX2型USB2.0芯片的SlaveFIFO的输出使能信号,低电平有效
  wire fx2_flagc1;//FX2型USB2.0芯片的端点6满标志
  wire fx2_flagb1;//FX2型USB2.0芯片的端点2空标志
  wire fx2_pkt_end1;//数据包结束标志信号
  wire fx2_slcs1;
  
  wire inout_switch;    
  //0: read由pc向FPGA下发指令   1:write由FPGA向fx2芯片继而向pc上传数据
  wire rw_switch;
      
  wire usb_fifo_full;
  wire          usb_fifo_wrempty; 
  wire [15:0]   usb_fifo_wrdata;
  wire          usb_fifo_wrreq;
  wire [10:0]   usb_fifo_usedw;
 
  assign rw_switch = (inout_switch || (usb_fifo_wrempty == 0 ))?1'd1:1'd0;
  //inout_switch为1是rw_switch为1的充分条件,
  //如果usb_fifo_wrempty没有为1,
  //说明usbfifo还没有读完,需要再给它一点读完的时间直到收到它为0的反馈
  assign fx2_fdata=rw_switch? fx2_fdata1 : 16'dz;

  assign fx2_faddr=rw_switch ? fx2_faddr1 : fx2_faddr0;
  assign fx2_sloe=rw_switch ? fx2_sloe1 : fx2_sloe0;
  assign fx2_slwr=rw_switch ? fx2_slwr1 : fx2_slwr0;
  assign fx2_slrd=rw_switch ? fx2_slrd1 : fx2_slrd0;
  assign fx2_pkt_end=rw_switch ? fx2_pkt_end1 : fx2_pkt_end0;
  assign fx2_slcs=rw_switch ? fx2_slcs1 : fx2_slcs0;
  

  assign led         = {~camera_init_done,~pll_locked};

  
  pll pll (
	.areset(~reset_n),
	.inclk0(clk50m),
	.c0(loc_clk50m),
	.c1(loc_clk24m),
	.locked(pll_locked)
	);
	
  
  wire [15:0]usb_data_out;
  wire usb_data_valid;
  
  //USB数据流发送控制模块:不断的将端点2中的数据读取出来,数据读取后直接作为端口输出
  usb_stream_out usb_stream_out(
    .clk (loc_clk50m),
    .fx2_fdata (fx2_fdata), //  FX2型USB2.0芯片的SlaveFIFO的数据线
    .fx2_faddr (fx2_faddr0), //  FX2型USB2.0芯片的SlaveFIFO的FIFO地址线
    .fx2_slrd (fx2_slrd0),  //  FX2型USB2.0芯片的SlaveFIFO的读控制信号,低电平有效
    .fx2_slwr (fx2_slwr0),  //  FX2型USB2.0芯片的SlaveFIFO的写控制信号,低电平有效
    .fx2_sloe (fx2_sloe0),  //  FX2型USB2.0芯片的SlaveFIFO的输出使能信号,低电平有效
    .fx2_flagc (fx2_flagc ), //  FX2型USB2.0芯片的端点6满标志
    .fx2_flagb (fx2_flagb ), //  FX2型USB2.0芯片的端点2空标志
    .fx2_ifclk (fx2_ifclk ), //  FX2型USB2.0芯片的接口时钟信号
    .fx2_pkt_end (fx2_pkt_end0),	//数据包结束标志信号
    .fx2_slcs (fx2_slcs0),
    .reset_n (reset_n),
    .data_out (usb_data_out),	
    //经过FPGA接收了的USB数据.这个数据从pc经过fx2芯片提供给FPGA
    .data_valid (usb_data_valid),	
    //经过FPGA接收了的USB数据有效标志信号.FPGA只要在读数据,这个信号一直拉高输出给FX2
    .source_ready (~rw_switch)	
    //外部数据消费者数据接收允许信号,例如FPGA中的缓存FIFO中有足够的空间存储一帧USB数据,则允许从Slave FIFO中去读取数据。当FPGA有能力读取一帧数据,则向外
   ); 
   
  wire [7:0]cmd_addr;
  wire [31:0]cmd_data;
  wire cmdvalid;
   下方模块对接收的信号进行解析,输出地址、数据、有效,然后通过地址判断这个数据是采样起始信号,采样数量,还是采样通道
  usb_cmd usb_cmd_inst(
    .Clk (fx2_ifclk),
    .Reset_n (reset_n),
    .rx_data (usb_data_out),
    .rx_done (usb_data_valid),
    .address (cmd_addr),
    .data (cmd_data),
    .cmdvalid (cmdvalid)
  );
  
  wire start_sample;
  //命令解析函数
 usb_cmd_rx usb_cmd_rx(
    .clk(fx2_ifclk),
    .reset_n(reset_n),
    .cmdvalid(cmdvalid),
    .cmd_addr(cmd_addr),
    .cmd_data(cmd_data),
    .start_sample(start_sample)
 );

  assign camera_xclk = loc_clk24m;
  camera_init
  #(
    .SYS_CLOCK      ( 50_000_000   ),//系统时钟采用50MHz
    .SCL_CLOCK      ( 400_000      ),//SCL总线时钟采用400kHz
    .CAMERA_TYPE    ( "ov5640"     ),//"ov5640" or "ov7725"
    .IMAGE_TYPE     ( 0            ),// 0: RGB; 1: JPEG
    .IMAGE_WIDTH    ( IMAGE_WIDTH  ),// 图片宽度
    .IMAGE_HEIGHT   ( IMAGE_HEIGHT ),// 图片高度
    .IMAGE_FLIP_EN  ( 0            ),// 0: 不翻转,1: 上下翻转
    .IMAGE_MIRROR_EN( 0            ) // 0: 不镜像,1: 左右镜像
  )camera_init
  (
    .Clk         (loc_clk50m       ),
    .Rst_n       (reset_n          ),
    .Init_Done   (camera_init_done ),
    .camera_rst_n(camera_rst_n     ),
    .camera_pwdn (camera_pwdn      ),
    .i2c_sclk    (camera_sclk      ),
    .i2c_sdat    (camera_sdat      )
  );

  
 assign pclk_bufg_o = camera_pclk;
  
 wire ImageState;
  DVP_Capture DVP_Capture(
    .Rst_n      (reset_n          ),//input
    .PCLK       (pclk_bufg_o      ),//input
    .Vsync      (camera_vsync     ),//input
    .Href       (camera_href      ),//input
    .Data       (camera_data      ),//input     [7:0]

    .ImageState (ImageState       ),//output reg
    .DataValid  (image_data_valid ),//output
    .DataPixel  (image_data       ),//output    [15:0]
    .DataHs     (image_data_hs    ),//output
    .DataVs     (image_data_vs    ),//output
    .Xaddr      (image_data_xaddr ),//output    [11:0],start is 1
    .Yaddr      (image_data_yaddr ) //output    [11:0],start is 1
  );
  
    reg[4:0] start_sample_r;
    always@(posedge fx2_ifclk)
    begin
        start_sample_r <= {start_sample_r[3:0],start_sample};           //拓宽start_sample信号,确保能收到启动开始信号,使摄像头的数据通过USB进行传输
    end

  reg        image_data_vs_dly1;
  reg [15:0] image_data_dly1;
  reg        image_data_valid_dly1;

  always@(posedge pclk_bufg_o)
  begin
    image_data_vs_dly1    <= image_data_vs;
    image_data_dly1       <= image_data;
    image_data_valid_dly1 <= image_data_valid;
  end

    usb_send_ctrl usb_send_ctrl
    (
      .reset_n          (reset_n)         ,

      .clk              (pclk_bufg_o)              ,  //pclk_bufg_o
      .data_i           (image_data_dly1),
      .data_valid_i     (image_data_valid_dly1)     ,
      .start_sample     (|start_sample_r)     , //按位或,只要检测到start_sample_r中某一时刻得到start_sample信号就启动传输
      .camera_vs_start  (~image_data_vs_dly1 && image_data_vs),
      
      .usb_fifo_full    (usb_fifo_full),
      .inout_switch     (inout_switch)      ,
      .usb_fifo_wrreq   (usb_fifo_wrreq)    , //USB FIFO的写请求信号,产生该信号,USB开始发送数据
      .fx2_clear        (fx2_clear)         ,//USB清除
      .usb_fifo_wrdata  (usb_fifo_wrdata)    //USB需要发送的数据
      );
    
  //USB数据流发送控制模块
  usb_stream_in usb_stream_in(
    .reset_n (reset_n),
    .fx2_fdata (fx2_fdata1), //FX2型USB2.0芯片的SlaveFIFO的数据线
    .fx2_faddr (fx2_faddr1), //FX2型USB2.0芯片的SlaveFIFO的FIFO地址线
    .fx2_slrd (fx2_slrd1), //FX2型USB2.0芯片的SlaveFIFO的读控制信号,低电平有效
    .fx2_slwr (fx2_slwr1), //FX2型USB2.0芯片的SlaveFIFO的写控制信号,低电平有效
    .fx2_sloe (fx2_sloe1), //FX2型USB2.0芯片的SlaveFIFO的输出使能信号,低电平有效
    .fx2_flagc (fx2_flagc), //FX2型USB2.0芯片的端点6满标志
    .fx2_flagb (fx2_flagb), //FX2型USB2.0芯片的端点2空标志
    .fx2_ifclk (fx2_ifclk), //FX2型USB2.0芯片的接口时钟信号
    .fx2_pkt_end (fx2_pkt_end1), //数据包结束标志信号
    .fx2_slcs (fx2_slcs1),

    .usb_fifo_wrclk (pclk_bufg_o),
    .usb_fifo_wrdata(usb_fifo_wrdata),
    .usb_fifo_full(usb_fifo_full),
    .usb_fifo_wrreq (usb_fifo_wrreq),
    .usb_fifo_usedw (usb_fifo_usedw),
    .usb_fifo_wrempty(usb_fifo_wrempty),
    .usb_fifo_rst(fx2_clear)
  );
  
endmodule

三、过程记录

🍋搭建硬件

将ACM68013模块和OV5640摄像头模块按照AC620V2开发板的对应位置接好,如图所示:
硬件连接

🍋程序烧录

AC620V2开发板程序烧录JIC文件:
程序烧录

开发板上的 LED0 和 LED1 点亮。LED0 被点亮说明 PLL 锁相环工作正常;LED1 被点亮说明摄像头初始化完成。

ACM68013模块烧写固件, 烧写文件夹下的“slave_for_adc.iic”文件至EEPROM中:
烧写固件

🍋注意事项

相关内容在盘A_AC620V2开发板标准配套资料\01_教材文档\02A文件中查看。

对ACM68013模块与电脑连接的问题,未识别该模块:
驱动问题
正确安装好对应的驱动之后:
安装驱动1
在设备管理器中看到设备名称:
安装驱动2

🍋结果显示

通过小梅哥USB摄像头上位机显示结果:
显示结果
结果

csdn

🧸结尾


  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小夏与酒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值