搜索
bottom↓
回复: 0

《ATK-DFPGL22G之FPGA开发指南_V1.0》第四十四章

[复制链接]

出0入234汤圆

发表于 2023-3-1 09:28:02 | 显示全部楼层 |阅读模式
本帖最后由 正点原子 于 2023-3-1 09:27 编辑

1)实验平台:正点原子紫光PGL22G开发板
2)购买链接:https://item.taobao.com/item.htm?&id=692368045899
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-340253-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子FPGA交流群:435699340 lQLPJxaFi2zaB4UWWrDAMgIsFEW2pwLb3abnwDMA_90_22.png
lQDPJxaFi2nfFizMjM0CbLCPlxn_FVheIQLb3aGrwFQA_620_140.jpg

lQLPJxaFi2nfFhLMkM0BXrDNvOUyeU_FPgLb3aGvQNIA_350_144.png
第四十四章 MT9V034摄像头HDMI显示实验

在MT9V034摄像头LCD显示实验中,成功的在LCD屏上实时显示出了摄像头采集的图像。本章将使用ATK-DFPGL22G开发板实现对MT9V034的数字图像采集并在HDMI显示器上实时显示。
本章包括以下几个部分:
44.1简介
44.2实验任务
44.3硬件设计
44.4软件设计
44.5下载验证


44.1简介

在“MT9V034摄像头RGB-LCD显示实验”中对MT9V034的视频传输时序、两线式接口总线协议以及寄存器的配置信息等内容作了详细的介绍,如果大家对这部分内容不是很熟悉的话,请参考“MT9V034摄像头RGB-LCD显示实验”中的简介部分。
44.2实验任务
本节实验任务是使用ATK-DFPGL22G开发板及MT9V034摄像头实现图像采集,通过HDMI接口驱动HDMI显示器,并实时显示出图像。
44.3硬件设计
摄像头扩展接口原理图及MT9V034模块说明与“MT9V034摄像头RGB-LCD显示实验”完全相同,请参考“MT9V034摄像头RGB-LCD显示实验”硬件设计部分。HDMI接口部分的硬件设计请参考“HDMI彩条显示实验”中的硬件设计部分。
由于MT9V034、HDMI接口和DDR3引脚数目较多且在前面相应的章节中已经给出它们的管脚列表,这里不再列出管脚分配。
44.4软件设计
图 44.4.1是根据本章实验任务画出的系统框图。对比“MT9V034摄像头RGB-LCD显示实验”的系统框图可以发现,本次实验只是把LCD顶层模块替换成了HDMI顶层模块,并将图像采集模块中的图片裁剪模块去掉了,其余模块(除时钟模块外)完全相同。之所以本节实验将图片裁剪模块去掉是因为本次实验所用HDMI显示器的分辨率是大于摄像头分辨率的,所以只需要在HDMI驱动模块中稍微改下数据请求即可,改动部分和OV7725摄像头HDMI显示实验一模一样,这里就不再详细讲解了。时钟模块用于为I2C驱动模块、HDMI顶层模块以及DDR3控制模块提供驱动时钟;I2C驱动模块和I2C配置模块用于初始化MT9V034图像传感器;摄像头采集模块负责采集摄像头图像数据,并且把图像数据写入DDR3控制模块中;DDR3控制模块负责将用户数据写入和读出片外DDR3存储器;HDMI顶层模块负责驱动HDMI显示器。本章使用的HDMI显示器其分辨率为1280*720,而MT9V034传感器的本次实验所配置的分辨率为640*480,所以HDMI显示器需要填充黑色的像素点。
MT9V034摄像头HDMI显示实验1050.png
图 44.4.1 顶层系统框图

由上图可知,时钟模块为HDMI顶层模块、DDR3控制模块以及I2C驱动模块提供驱动时钟。I2C配置模块和I2C驱动模块控制着传感器初始化的开始与结束,传感器初始化完成后图像采集模块将采集到的数据写入DDR3控制模块,HDMI顶层模块从DDR3控制模块中读出数据并驱动显示器显示,这时整个系统才完成了数据的采集、缓存与显示。需要注意的是图像数据采集模块是在DDR3和传感器都初始化完成之后才开始输出数据的,避免了在DDR3初始化过程中向里面写入数据。
顶层代码如下所示:
1    module mt9v034_hdmi(
2        input             sys_clk          ,
3        input             sys_rst_n        ,
4                                          
5        output            tmds_clk_p       ,  // TMDS 时钟通道
6        output            tmds_clk_n       ,
7        output [2:0]      tmds_data_p      ,  // TMDS 数据通道
8        output [2:0]      tmds_data_n      ,
9        //摄像头接口                       
10       input             cam_pclk         ,  //cmos 数据像素时钟
11       input             cam_vsync        ,  //cmos 场同步信号
12       input             cam_href         ,  //cmos 行同步信号
13       input  [7:0]      cam_data         ,  //cmos 数据
14       output            cam_rst_n        ,  //cmos 复位信号,低电平有效
15       output            cam_stb          ,  //cmos pwer down
16       output            cam_scl          ,  //cmos SCCB_SCL线
17       inout             cam_sda          ,  //cmos SCCB_SDA线
18       //DDR3接口
19       input             pad_loop_in      ,  //低位温度补偿输入
20       input             pad_loop_in_h    ,  //高位温度补偿输入
21       output            pad_rstn_ch0     ,  //Memory复位
22       output            pad_ddr_clk_w    ,  //Memory差分时钟正
23       output            pad_ddr_clkn_w   ,  //Memory差分时钟负
24       output            pad_csn_ch0      ,  //Memory片选
25       output [15:0]     pad_addr_ch0     ,  //Memory地址总线
26       inout  [16-1:0]   pad_dq_ch0       ,  //数据总线
27       inout  [16/8-1:0] pad_dqs_ch0      ,  //数据时钟正端
28       inout  [16/8-1:0] pad_dqsn_ch0     ,  //数据时钟负端
29       output [16/8-1:0] pad_dm_rdqs_ch0  ,  //数据Mask
30       output            pad_cke_ch0      ,  //Memory差分时钟使
31       output            pad_odt_ch0      ,  //On Die Terminati
32       output            pad_rasn_ch0     ,  //行地址strobe
33       output            pad_casn_ch0     ,  //列地址strobe
34       output            pad_wen_ch0      ,  //写使能
35       output [2:0]      pad_ba_ch0       ,  //Bank地址总线
36       output            pad_loop_out     ,  //低位温度补偿输出
37       output            pad_loop_out_h      //高位温度补偿输出
38      );
39   
40   //parameter define
41   parameter SLAVE_ADDR = 7'b1001_000   ; //mt9v034的器件地址7'h90
42   parameter BIT_CTRL   = 1'b0          ; //mt9v034的字节地址为8位  0:8位 1:16位
43   parameter DATA_CTRL  = 1'b1          ;  //mt9v034的数据为8位  0:8位 1:16位
44   parameter CLK_FREQ   = 27'd50_000_000; //i2c_dri模块的驱动时钟频率
45   parameter I2C_FREQ   = 18'd250_000   ; //I2C的SCL时钟频率,不超过400KHz
46   parameter APP_ADDR_MIN = 28'd0       ; //ddr3读写起始地址,以一个16bit的数据为一个单位
47   parameter APP_ADDR_MAX = 28'd307200  ; //ddr3读写结束地址,以一个16bit的数据为一个单位
48   parameter BURST_LENGTH = 8'd80       ; //ddr3读写突发长度,80个128bit的数据
49   
50   //wire define
51   //PLL
52   wire        pixel_clk       ;  //像素时钟75M
53   wire        pixel_clk_5x    ;  //5倍像素时钟375M
54   wire        clk_50m         ;  //output 50M
55   wire        clk_locked      ;
56   //MT9V034
57   wire        i2c_dri_clk     ;  //I2C操作时钟
58   wire        i2c_done        ;  //I2C寄存器配置完成信号
59   wire        i2c_exec        ;  //I2C触发执行信号
60   wire [7:0 ] i2c_addr        ;  //I2C要配置的地址
61   wire [15:0] i2c_wr_data     ;  //I2C要配置的数据
62   wire        cam_init_done   ;  //摄像头初始化完成
63   
64   wire        cmos_frame_vsync;  //帧有效信号
65   wire        cmos_frame_href ;  //行有效信号
66   wire        cmos_frame_valid;  //数据有效使能信号
67   wire [15:0] wr_data         ;  //OV7725写入DDR3控制器模块的数据
68   //HDMI
69   wire        video_vs        ;  //场同步信号
70   wire [15:0] rd_data         ;  //DDR3控制器模块读数据给HDMI
71   wire        rdata_req       ;  //DDR3控制器模块读使能
72   //DDR3
73   wire        fram_done       ; //DDR中已经存入一帧画面标志
74   wire        ddr_init_done   ; //ddr3初始化完成
75   
76   //*****************************************************
77   //**                    main code
78   //*****************************************************
79   assign  cam_stb   = 1'b0;
80   assign  cam_rst_n = 1'b1;
81   
82   //例化PLL IP核
83   pll_clk  u_pll_clk(
84       .pll_rst        (~sys_rst_n  ),
85       .clkin1         (sys_clk     ),
86       .clkout0        (pixel_clk   ), //像素时钟75M
87       .clkout1        (pixel_clk_5x), //5倍像素时钟375M
88       .clkout2        (clk_50m     ), //output 50M
89       .pll_lock       (clk_locked  )
90   );
91   
92   //I2C驱配置模块
93   i2c_cfg  u_i2c_cfg(
94       .clk          (i2c_dri_clk  ),
95       .rst_n        (sys_rst_n    ),
96       .i2c_done     (i2c_done     ),
97       .i2c_exec     (i2c_exec     ),
98       .i2c_addr     (i2c_addr     ),
99       .i2c_wr_data  (i2c_wr_data  ),
100      .cfg_done     (cam_init_done)
101  );
102  
103  //I2C驱动模块
104  i2c_dri
105    #(
106      .SLAVE_ADDR         (SLAVE_ADDR),    //参数传递
107      .CLK_FREQ           (CLK_FREQ  ),              
108      .I2C_FREQ           (I2C_FREQ  )
109      )
110    u_i2c_dr(
111      .clk                (clk_50m        ),
112      .rst_n              (sys_rst_n      ),
113      .i2c_exec           (i2c_exec       ),
114      .bit_ctrl           (BIT_CTRL       ),
115      .data_ctrl          (DATA_CTRL      ),
116      .i2c_rh_wl          (0              ), //固定为0,只用到了IIC驱动的写操作   
117      .i2c_addr           ({8'b0,i2c_addr}),
118      .i2c_data_w         (i2c_wr_data    ),
119      .i2c_data_r         (               ),
120      .i2c_done           (i2c_done       ),
121      .scl                (cam_scl        ),
122      .sda                (cam_sda        ),
123      .dri_clk            (i2c_dri_clk    )  //I2C操作时钟
124  );
125  
126  //图像采集模块
127   cmos_capture_raw_gray
128  #(
129      .CMOS_FRAME_WAITCNT  (4'd10)  //Wait n fps for steady(OmniVision need 10 Frame)
130  )
131  u_cmos_capture_raw_gray
132  (
133      //global clock
134      .clk_cmos          (1'b0                     ), //24MHz CMOS Driver clock input
135      .rst_n             (sys_rst_n & ddr_init_done), //global reset
136      //CMOS Sensor Interface
137      .cmos_pclk         (cam_pclk                 ), //24MHz CMOS Pixel clock input
138      .cmos_xclk         (                         ), //24MHz drive clock
139      .cmos_data         (cam_data                 ), //8 bits cmos data input
140      .cmos_vsync        (cam_vsync                ), //L: vaild, H: invalid
141      .cmos_href         (cam_href                 ), //H: vaild, L: invalid   
142      //CMOS SYNC Data output
143      .cmos_frame_vsync  (cmos_frame_vsync         ), //cmos frame data vsync valid signal
144      .cmos_frame_href   (cmos_frame_href          ), //cmos frame data href vaild  signal
145      .wr_data           (wr_data                  ), //cmos frame gray output
146      .cmos_frame_clken  (cmos_frame_valid         ), //cmos frame data output/capture enable clock   
147      //user interface
148      .cmos_fps_rate     (                         )  //cmos image output rate
149  );
150  
151  //ddr3
152  ddr3_top u_ddr3_top(
153      .refclk_in             (clk_50m         ),
154      .rst_n                 (sys_rst_n       ),
155      .app_addr_rd_min       (APP_ADDR_MIN    ),
156      .app_addr_rd_max       (APP_ADDR_MAX    ),
157      .rd_bust_len           (BURST_LENGTH    ),
158      .app_addr_wr_min       (APP_ADDR_MIN    ),
159      .app_addr_wr_max       (APP_ADDR_MAX    ),
160      .wr_bust_len           (BURST_LENGTH    ),
161      .ddr3_read_valid       (1'b1            ),
162      .ddr3_pingpang_en      (1'b1            ),
163      .wr_clk                (cam_pclk        ),
164      .rd_clk                (pixel_clk       ),
165      .datain_valid          (cmos_frame_valid),
166      .datain                (wr_data         ),
167      .rdata_req             (rdata_req       ),
168      .rd_load               (video_vs        ),
169      .wr_load               (cmos_frame_vsync),
170      .fram_done             (fram_done       ),
171      .dataout               (rd_data         ),
172      .pll_lock              (pll_lock        ),
173      .ddr_init_done         (ddr_init_done   ),
174      .ddrphy_rst_done       (                ),
175      .pad_loop_in           (pad_loop_in     ),
176      .pad_loop_in_h         (pad_loop_in_h   ),
177      .pad_rstn_ch0          (pad_rstn_ch0    ),
178      .pad_ddr_clk_w         (pad_ddr_clk_w   ),
179      .pad_ddr_clkn_w        (pad_ddr_clkn_w  ),
180      .pad_csn_ch0           (pad_csn_ch0     ),
181      .pad_addr_ch0          (pad_addr_ch0    ),
182      .pad_dq_ch0            (pad_dq_ch0      ),
183      .pad_dqs_ch0           (pad_dqs_ch0     ),
184      .pad_dqsn_ch0          (pad_dqsn_ch0    ),
185      .pad_dm_rdqs_ch0       (pad_dm_rdqs_ch0 ),
186      .pad_cke_ch0           (pad_cke_ch0     ),
187      .pad_odt_ch0           (pad_odt_ch0     ),
188      .pad_rasn_ch0          (pad_rasn_ch0    ),
189      .pad_casn_ch0          (pad_casn_ch0    ),
190      .pad_wen_ch0           (pad_wen_ch0     ),
191      .pad_ba_ch0            (pad_ba_ch0      ),
192      .pad_loop_out          (pad_loop_out    ),
193      .pad_loop_out_h        (pad_loop_out_h  )
194      
195      );
196  
197  //HDMI顶层模块
198  hdmi_top u_hdmi_top(
199      .hdmi_clk       (pixel_clk    ),
200      .hdmi_clk_5     (pixel_clk_5x ),
201      .sys_rst_n      (sys_rst_n    ),
202      .fram_done      (fram_done    ),
203      .clk_locked     (clk_locked   ),
204      .rd_data        (rd_data      ),
205      .rd_en          (rdata_req    ),
206      .video_vs       (video_vs     ),
207      .h_disp         (             ),
208      .v_disp         (             ),
209      .pixel_xpos     (             ),
210      .pixel_ypos     (             ),
211      .tmds_clk_p     (tmds_clk_p   ),
212      .tmds_clk_n     (tmds_clk_n   ),
213      .tmds_data_p    (tmds_data_p  ),
214      .tmds_data_n    (tmds_data_n  )
215      );
216  
217  endmodule
FPGA顶层模块(mt9v034_hdmi)例化了以下6个模块:时钟模块(pll_clk)、I2C驱动模块(i2c_dri)、I2C配置模块(i2c_cfg)、图像采集模块(cmos_capture_raw_gray)、DDR3控制模块(ddr3_top)和HDMI顶层模块(hdmi_top)。
时钟模块(pll_clk):时钟模块通过调用PLL IP核实现,为DDR3控制模块以及I2C驱动模块提供驱动时钟,为HDMI模块提供像素时钟和5倍像素时钟(频率分别是75Mhz和375Mhz)。
I2C驱动模块(i2c_dri):I2C驱动模块负责驱动MT9V034的两线式接口总线,用户根据该模块提供的用户接口可以很方便的对MT9V034的寄存器进行配置,该模块和“EEPROM读写实验”章节中用到的I2C驱动模块为同一个模块,有关该模块的详细介绍请大家参考“EEPROM读写实验”章节;其中代码改动部分的详细介绍请大家参考“MT9V034摄像头RGB-LCD显示实验”章节。
I2C配置模块(i2c_cfg):I2C配置模块的驱动时钟是由I2C驱动模块输出的时钟提供的,这样方便了I2C驱动模块和I2C配置模块之间的数据交互。该模块寄存需要配置的寄存器地址和数据,同时该模块输出MT9V034的寄存器地址和数据以及控制I2C驱动模块开始执行的控制信号,直接连接到I2C驱动模块的用户接口,从而完成对MT9V034传感器的配置。
图像采集模块(cmos_capture_raw_gray):在摄像头像素时钟的驱动下将传感器输出的场同步信号、行同步信号以及8位数据信号进行采集,在摄像头数据稳定后输出场同步信号、行同步信号以及8位数据信号,以提供给DDR3控制模块所使用。
DDR3控制模块(ddr3_top):DDR3读写控制器模块负责驱动DDR3片外存储器,缓存图像传感器输出的图像数据。该模块将DDR3复杂的读写操作封装成类似FIFO的用户接口,非常方便用户的使用。有关DDR3控制模块的详细介绍请大家参考“DDR3读写测试实验”章节。
HDMI顶层模块(hdmi_top):HDMI顶层模块负责驱动HDMI显示器的驱动信号的输出,同时为其他模块提供场同步信号和数据请求信号。HDMI顶层模块例化了HDMI视频显示模块(video_display)、HDMI视频显示驱动模块(video_driver)和HDMI驱动模块(dvi_transmitter_top)。
HDMI视频显示驱动模块负责产生行场信号和数据有效使能信号和像素点的横纵坐标。HDMI视频显示模块负责产生显示的像素点数据,并将内部信号data_req(数据请求信号)输出至端口,方便从DD3控制器中读取数据。HDMI驱动模块负责将RGB565格式的视频图像转换成TMDS数据输出。有关HDMI视频显示驱动模块、HDMI驱动模块的详细介绍请大家参考“HDMI彩条显示实验”章节,HDMI视频显示模块详细介绍请大家参考“OV7725摄像头HDMI显示实验”章节。
44.5下载验证
编译完工程之后就可以开始下载程序了。将MT9V034摄像头模块插在ATK-DFPGL22G开发板的“OLED/CAMERA”插座上,并将HDMI电缆一端连接到开发板上的HDMI插座、另一端连接到显示器。将下载器一端连电脑,另一端与开发板上的JTAG端口连接,连接电源线并打开电源开关。接下来我们下载程序,验证MT9V034 HDMI实时显示功能。下载完成后观察HDMI显示器显示的图案如下图所示,说明MT9V034 HDMI实时显示程序下载验证成功。
MT9V034摄像头HDMI显示实验12558.png
图 44.5.1 HDMI实时显示图像
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 17:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表