超级版主
- 积分
- 4754
- 金钱
- 4754
- 注册时间
- 2019-5-8
- 在线时间
- 1239 小时
|
本帖最后由 正点原子运营 于 2021-10-30 10:19 编辑
1)实验平台:正点原子新起点V2FPGA开发板
2) 章节摘自【正点原子】《新起点之FPGA开发指南 V2.1》
3)购买链接:https://detail.tmall.com/item.htm?id=609758951113
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz_xinqidian(V2).html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子FPGA技术交流QQ群:712557122
第四十四章 MT9V034摄像头HDMI显示实验
在MT9V034摄像头LCD显示实验中,成功地在LCD屏上实时显示出了摄像头采集的图像。本章将使用FPGA开发板实现对MT9V034的数字图像采集并在HDMI显示器上实时显示。
本章包括以下几个部分:
43.1简介
43.2实验任务
43.3硬件设计
43.4程序设计
43.5下载验证
43.6
44.1简介
在“MT9V034摄像头TFT-LCD显示实验”中对MT9V034的视频传输时序、两线式接口总线协议以及寄存器的配置信息等内容作了详细的介绍,如果大家对这部分内容不是很熟悉的话,请参考“MT9V034摄像头TFT-LCD显示实验”中的MT9V034简介部分。
44.2实验任务
本节实验任务是使用新起点开发板及MT9V034摄像头实现图像采集,通过HDMI接口驱动HDMI显示器,并实时显示出图像。
44.3硬件设计
摄像头扩展接口原理图及MT9V034模块说明与“MT9V034摄像头TFT-LCD显示实验”完全相同,请参考“MT9V034摄像头TFT-LCD显示实验”硬件设计部分。HDMI接口部分的硬件设计请参考“HDMI彩条显示实验”中的硬件设计部分。
由于MT9V034、HDMI接口和SDRAM引脚数目较多且在前面相应的章节中已经给出它们的管脚列表,这里不再列出管脚分配。
44.4程序设计
图 44.4.1是根据本章实验任务画出的系统框图。对比“MT9V034摄像头RGB-LCD显示实验”的系统框图可以发现,本次实验只是把LCD顶层模块替换成了HDMI顶层模块,并将图像采集模块中的图片裁剪模块去掉了,其余模块(除时钟模块外)完全相同。之所以本节实验将图片裁剪模块去掉是因为本次实验所用HDMI显示器的分辨率是大于摄像头分辨率的,所以只需要在HDMI驱动模块中稍微改下数据请求即可,改动部分和OV7725 HDMI显示实验一摸一样,这里就不再详细讲解了。时钟模块(由两个pll锁相环组成,一个负责提供LCD、SDRAM和IIC模块的参考时钟;另一个负责提供HDMI模块的像素时钟与5倍频时钟)用于为I2C驱动模块、HDMI顶层模块以及SDRAM控制模块提供驱动时钟;I2C驱动模块和I2C配置模块用于初始化MT9V034图像传感器;摄像头采集模块负责采集摄像头图像数据,并且把图像数据写入SDRAM控制模块中;SDRAM控制模块负责将用户数据写入和读出片外SDRAM存储器;HDMI顶层模块负责驱动HDMI显示器。本章使用的HDMI显示器其分辨率为1280*800,而MT9V034传感器的本次实验所配置的分辨率为640*480,所以HDMI显示器需要填充黑色的像素点。
图 44.4.1 顶层系统框图
由上图可知,时钟模块为HDMI顶层模块、SDRAM控制模块以及I2C驱动模块提供驱动时钟。I2C配置模块和I2C驱动模块控制着传感器初始化的开始与结束,传感器初始化完成后图像采集模块将采集到的数据写入SDRAM控制模块,HDMI顶层模块从SDRAM控制模块中读出数据并驱动显示器显示,这时整个系统才完成了数据的采集、缓存与显示。需要注意的是图像数据采集模块是在SDRAM和传感器都初始化完成之后才开始输出数据的,避免了在SDRAM初始化过程中向里面写入数据。
顶层代码如下所示:
- 1 module mt9v034_hdmi(
- 2 input sys_clk , //系统时钟
- 3 input sys_rst_n , //系统复位,低电平有效
- 4 //摄像头接口
- 5 //cmos interface
- 6 output cmos_scl , //cmos i2c clock
- 7 inout cmos_sda , //cmos i2c data
- 8 input cmos_vsync, //cmos vsync
- 9 input cmos_href , //cmos hsync refrence
- 10 input cmos_pclk , //cmos pxiel clock
- 11 input [7:0] cmos_data , //cmos data
- 12 output cmos_reset , //cmos reset
- 13 output cmos_pwdn , //cmos pwer down
- 14 //SDRAM接口
- 15 output sdram_clk , //SDRAM 时钟
- 16 output sdram_cke , //SDRAM 时钟有效
- 17 output sdram_cs_n , //SDRAM 片选
- 18 output sdram_ras_n , //SDRAM 行有效
- 19 output sdram_cas_n , //SDRAM 列有效
- 20 output sdram_we_n , //SDRAM 写有效
- 21 output [1:0] sdram_ba , //SDRAM Bank地址
- 22 output [1:0] sdram_dqm , //SDRAM 数据掩码
- 23 output [12:0] sdram_addr , //SDRAM 地址
- 24 inout [15:0] sdram_data , //SDRAM 数据
- 25 //hdmi接口
- 26 output tmds_clk_p , // TMDS 时钟通道
- 27 output tmds_clk_n ,
- 28 output [2:0] tmds_data_p , // TMDS 数据通道
- 29 output [2:0] tmds_data_n
- 30
- 31 );
- 32
- 33 //parameter define
- 34 parameter SLAVE_ADD = 7'b1001_000 ; //slave address
- 35 parameter BIT_CTRL = 1'b0 ; //MT9V034的字节地址为8位 0:8位 1:16位
- 36 parameter DATA_CTRL = 1'b1 ; // MT9V034的数据为16位 0:8位 1:16位
- 37 parameter CLK_FREQ = 26'd50_000_000 ; //i2c_dri模块的驱动时钟频率 50.0MHz
- 38 parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL时钟频率,不超过400KHz
- 39
- 40 //wire define
- 41 wire clk_100m ; //100mhz时钟
- 42 wire clk_100m_shift ; //100mhz时钟,相位偏移时钟
- 43 wire clk_50m ; //50mhz时钟,提供给lcd驱动时钟
- 44 wire clk_24m ;
- 45 wire locked ; //时钟锁定信号
- 46 wire rst_n ; //全局复位
- 47 wire i2c_exec ; //I2C触发执行信号
- 48 wire [15:0] i2c_data ; //I2C要配置的地址与数据(高8位地址,低8位数据)
- 49 wire cam_init_done ; //摄像头初始化完成
- 50 wire i2c_done ; //I2C寄存器配置完成信号
- 51 wire i2c_dri_clk ; //I2C操作时钟
- 52 wire wr_en ; //sdram控制器模块写使能
- 53 wire [15:0] wr_data ; //sdram控制器模块写数据
- 54 wire rdata_req ; //sdram控制器模块读使能
- 55 wire [15:0] rd_data ; //sdram控制器模块读数据
- 56 wire cmos_frame_valid ; //数据有效使能信号
- 57 wire init_calib_complete ; //sdram初始化完成init_calib_complete
- 58 wire sys_init_done ; //系统初始化完成(sdram初始化+摄像头初始化)
- 59 wire cmos_frame_vsync ; //输出帧有效场同步信号
- 60 wire cmos_frame_href ; //输出帧有效行同步信号
- 61 wire [9:0] pixel_xpos_w ; //像素点横坐标
- 62 wire [9:0] pixel_ypos_w ; //像素点纵坐标
- 63 wire lcd_clk ; //分频产生的LCD 采样时钟
- 64 wire [10:0] h_disp ; //LCD屏水平分辨率
- 65 wire [10:0] v_disp ; //LCD屏垂直分辨率
- 66 wire [10:0] h_pixel ; //存入sdram的水平分辨率
- 67 wire [10:0] v_pixel ; //存入sdram的屏垂直分辨率
- 68 wire [15:0] lcd_id ; //LCD屏的ID号
- 69 wire [7:0] cmos_frame_data ; //cmos frame data output
- 70 wire [7:0] i2c_addr ;
- 71 wire [15:0] i2c_wr_data ;
- 72 wire [27:0] sdram_addr_max ; //存入sdram的最大读写地址
- 73 wire cmos_xclk ;
- 74 wire locked_hdmi ;
- 75 wire hdmi_clk ;
- 76 wire hdmi_clk_5 ;
- 77 //*****************************************************
- 78 //** main code
- 79 //*****************************************************
- 80
- 81 //待时钟锁定后产生复位结束信号
- 82 assign rst_n = sys_rst_n & locked & locked_hdmi;
- 83
- 84 //系统初始化完成:sdram初始化完成
- 85 assign sys_init_done = sdram_init_done & i2c_config_done;
- 86
- 87 assign cmos_reset = 1'b1; //cmos work state (50us delay)
- 88 assign cmos_pwdn = 1'b0; //cmos power on
- 89
- 90 pll_clk pll_clk_inst (
- 91 .areset ( ~sys_rst_n ),
- 92 .inclk0 ( sys_clk ),
- 93 .c0 ( clk_50m ),
- 94 .c1 ( clk_100m ),
- 95 .c2 (clk_100m_shift),
- 96 .locked ( locked )
- 97 );
- 98
- 99 pll_hdmi pll_hdmi_inst (
- 100 .areset ( ~sys_rst_n ),
- 101 .inclk0 ( sys_clk ),
- 102 .c0 ( hdmi_clk ),//hdmi pixel clock 71Mhz
- 103 .c1 ( hdmi_clk_5 ),//hdmi pixel clock*5 355Mhz
- 104 .locked ( locked_hdmi )
- 105 );
- 106
- 107 i2c_cfg u_i2c_cfg(
- 108 .clk (i2c_dri_clk ),
- 109 .rst_n (sys_rst_n ),
- 110 .i2c_done (i2c_done ),
- 111 .i2c_exec (i2c_exec ),
- 112 .i2c_addr (i2c_addr ),
- 113 .i2c_wr_data (i2c_wr_data ),
- 114 .cfg_done (i2c_config_done)
- 115 );
- 116
- 117 //I2C驱动模块
- 118 i2c_dri #(
- 119 .SLAVE_ADDR (SLAVE_ADD ), //参数传递
- 120 .CLK_FREQ (CLK_FREQ ),
- 121 .I2C_FREQ (I2C_FREQ )
- 122 )
- 123 u_i2c_dr(
- 124 .clk (clk_50m ),
- 125 .rst_n (sys_rst_n ),
- 126
- 127 .i2c_exec (i2c_exec ),
- 128 .bit_ctrl (BIT_CTRL ),
- 129 .data_ctrl (DATA_CTRL ),
- 130 .i2c_rh_wl (0), //固定为0,只用到了IIC驱动的写操作
- 131 .i2c_addr ({8'b0,i2c_addr}),
- 132 .i2c_data_w (i2c_wr_data),
- 133 .i2c_data_r (),
- 134 .i2c_done (i2c_done ),
- 135 .scl (cmos_scl ),
- 136 .sda (cmos_sda ),
- 137 .dri_clk (i2c_dri_clk) //I2C操作时钟
- 138 );
- 139
- 140 //图像采集顶层模块
- 141 cmos_data_top u_cmos_data_top(
- 142 .rst_n (sys_init_done), //系统初始化完成之后再开始采集数据
- 143 .clk_cmos (clk_24m), //24MHz CMOS Driver clock input
- 144 .cam_pclk (cmos_pclk),
- 145 .cmos_xclk (cmos_xclk), //24MHz drive clock
- 146 .cam_vsync (cmos_vsync),
- 147 .cam_href (cmos_href),
- 148 .cam_data (cmos_data),
- 149 .lcd_id (lcd_id),
- 150 .h_pixel (h_pixel),
- 151 .v_pixel (v_pixel),
- 152 .sdram_addr_max (sdram_addr_max),
- 153 .cmos_frame_vsync (cmos_frame_vsync),
- 154 .cmos_frame_href (cmos_frame_href),
- 155 .cmos_frame_valid (cmos_frame_valid), //数据有效使能信号
- 156 .cmos_frame_data (wr_data) //有效数据
- 157 );
- 158
- 159 //SDRAM 控制器顶层模块,封装成FIFO接口
- 160 //SDRAM 控制器地址组成: {bank_addr[1:0],row_addr[12:0],col_addr[8:0]}
- 161 sdram_top u_sdram_top(
- 162 .ref_clk (clk_100m), //sdram 控制器参考时钟
- 163 .out_clk (clk_100m_shift), //用于输出的相位偏移时钟
- 164 .rst_n (rst_n), //系统复位
- 165
- 166 //用户写端口
- 167 .wr_clk (cmos_pclk), //写端口FIFO: 写时钟
- 168 .wr_en (cmos_frame_valid), //写端口FIFO: 写使能
- 169 .wr_data (wr_data), //写端口FIFO: 写数据
- 170 .wr_min_addr (24'd0), //写SDRAM的起始地址
- 171 .wr_max_addr (sdram_addr_max), //写SDRAM的结束地址
- 172 .wr_len (10'd512), //写SDRAM时的数据突发长度
- 173 .wr_load (~rst_n), //写端口复位: 复位写地址,清空写FIFO
- 174
- 175 //用户读端口
- 176 .rd_clk (hdmi_clk), //读端口FIFO: 读时钟
- 177 .rd_en (rdata_req), //读端口FIFO: 读使能
- 178 .rd_data (rd_data), //读端口FIFO: 读数据
- 179 .rd_min_addr (24'd0), //读SDRAM的起始地址
- 180 .rd_max_addr (sdram_addr_max), //读SDRAM的结束地址
- 181 .rd_len (10'd512), //从SDRAM中读数据时的突发长度
- 182 .rd_load (~rst_n), //读端口复位: 复位读地址,清空读FIFO
- 183
- 184 //用户控制端口
- 185 .sdram_read_valid (1'b1), //SDRAM 读使能
- 186 .sdram_pingpang_en (1'b1), //SDRAM 乒乓操作使能
- 187 .sdram_init_done (sdram_init_done), //SDRAM 初始化完成标志
- 188
- 189 //SDRAM 芯片接口
- 190 .sdram_clk (sdram_clk), //SDRAM 芯片时钟
- 191 .sdram_cke (sdram_cke), //SDRAM 时钟有效
- 192 .sdram_cs_n (sdram_cs_n), //SDRAM 片选
- 193 .sdram_ras_n (sdram_ras_n), //SDRAM 行有效
- 194 .sdram_cas_n (sdram_cas_n), //SDRAM 列有效
- 195 .sdram_we_n (sdram_we_n), //SDRAM 写有效
- 196 .sdram_ba (sdram_ba), //SDRAM Bank地址
- 197 .sdram_addr (sdram_addr), //SDRAM 行/列地址
- 198 .sdram_data (sdram_data), //SDRAM 数据
- 199 .sdram_dqm (sdram_dqm) //SDRAM 数据掩码
- 200 );
- 201
- 202 //例化HDMI顶层模块
- 203 hdmi_top u_hdmi_top(
- 204 .hdmi_clk (hdmi_clk ),
- 205 .hdmi_clk_5 (hdmi_clk_5 ),
- 206 .rst_n (rst_n ),
- 207
- 208 .rd_data (rd_data ),
- 209 .rd_en (rdata_req),
- 210 .h_disp (h_disp ),
- 211 .v_disp (v_disp ),
- 212 .pixel_xpos (),
- 213 .pixel_ypos (),
- 214 .video_vs (),
- 215 .tmds_clk_p (tmds_clk_p ),
- 216 .tmds_clk_n (tmds_clk_n ),
- 217 .tmds_data_p (tmds_data_p ),
- 218 .tmds_data_n (tmds_data_n )
- 219 );
- 220
- 221 endmodule
复制代码
FPGA顶层模块(mt9v034_hdmi)例化了以下7个模块:时钟模块(时钟模块由两个锁相环组成,分别是pll_clk和pll_hdmi)、I2C驱动模块(i2c_dri)、I2C配置模块(i2c_cfg)、图像采集模块(cmos_data_top)、SDRAM控制模块(sdram_top)和HDMI顶层模块(hdmi_top)。
时钟模块(pll_clk和pll_hdmi):时钟模块通过调用PLL IP核实现,其中pll_clk为SDRAM控制模块以及I2C驱动模块提供驱动时钟,pll_hdmi 主要是为HDMI模块提供像素时钟和5倍像素时钟(频率分别是71Mhz和355Mhz)。
I2C驱动模块(i2c_dri):I2C驱动模块负责驱动MT9V034的两线式接口总线,用户可根据该模块提供的用户接口可以很方便的对MT9V034的寄存器进行配置,该模块和“EEPROM读写实验”章节中用到的I2C驱动模块为同一个模块,有关该模块的详细介绍请大家参考“EEPROM读写实验”章节。
I2C配置模块(i2c_cfg):I2C配置模块的驱动时钟是由I2C驱动模块输出的时钟提供的,这样方便了I2C驱动模块和I2C配置模块之间的数据交互。该模块寄存需要配置的寄存器地址和数据,同时该模块输出MT9V034的寄存器地址和数据以及控制I2C驱动模块开始执行的控制信号,直接连接到I2C驱动模块的用户接口,从而完成对MT9V034传感器的配置。
图像采集模块(cmos_data_top):在像素时钟的驱动下将传感器输出的场同步信号、行同步信号以及8位数据信号进行采集,在摄像头数据稳定后输出场同步信号、行同步信号以及8位数据信号,以提供给SDRAM控制模块所使用。
SDRAM控制模块(sdram_top):SDRAM读写控制器模块负责驱动SDRAM片外存储器,缓存图像传感器输出的图像数据。该模块将SDRAM复杂的读写操作封装成类似FIFO的用户接口,非常方便用户的使用。有关SDRAM控制模块的详细介绍请大家参考“SDRAM读写实验”章节。
HDMI顶层模块(hdmi_top):HDMI顶层模块负责驱动HDMI显示器的驱动信号的输出,同时为其他模块提供LCD屏参数、场同步信号和数据请求信号。HDMI顶层模块例化了HDMI驱动模块(video_driver)和HDMI驱动转换顶层模块(dvi_transmitter_top)。HDMI驱动模块负责产生行场信号和数据有效使能信号和像素点的横纵坐标,并将内部信号data_req(数据请求信号)输出至端口,方便从SDRAM控制器中读取数据。HDMI驱动转换顶层模块负责将RGB565格式的视频图像转换成TMDS数据输出。有关HDMI驱动模块、HDMI驱动转换顶层模块的详细介绍请大家参考“HDMI彩条显示实验”章节,HDMI显示模块详细介绍请大家参考“OV7725摄像头RGB-LCD显示实验”章节。
44.5下载验证
编译完工程之后就可以开始下载程序了。将MT9V034摄像头模块插在新起点开发板的“OLED/CAMERA”插座上,并将HDMI电缆一端连接到开发板上的HDMI插座、另一端连接到显示器。将下载器一端连电脑,另一端与开发板上的JTAG端口连接,连接电源线并打开电源开关。接下来我们下载程序,验证MT9V034 HDMI实时显示功能。下载完成后观察HDMI显示器显示的图案如下图所示,说明MT9V034 HDMI实时显示程序下载验证成功。
图 44.5.1 HDMI实时显示图像 |
|