700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【正点原子FPGA连载】第四十四章MT9V034摄像头HDMI显示实验 -摘自【正点原子】新起点

【正点原子FPGA连载】第四十四章MT9V034摄像头HDMI显示实验 -摘自【正点原子】新起点

时间:2020-09-02 14:09:52

相关推荐

【正点原子FPGA连载】第四十四章MT9V034摄像头HDMI显示实验 -摘自【正点原子】新起点

1)实验平台:正点原子新起点V2开发板

2)平台购买地址:/item.htm?id=609758951113

2)全套实验源码+手册+视频下载地址:/thread-300792-1-1.html

3)对正点原子FPGA感兴趣的同学可以加群讨论:994244016

4)关注正点原子公众号,获取最新资料更新

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

在MT9V034摄像头LCD显示实验中,成功地在LCD屏上实时显示出了摄像头采集的图像。本章将使用FPGA开发板实现对MT9V034的数字图像采集并在HDMI显示器上实时显示。

本章包括以下几个部分:

4343.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显示器其分辨率为1280800,而MT9V034传感器的本次实验所配置的分辨率为640480,所以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 interface6 output cmos_scl , //cmos i2c clock7 inout cmos_sda , //cmos i2c data8 input cmos_vsync, //cmos vsync9 input cmos_href , //cmos hsync refrence10input cmos_pclk , //cmos pxiel clock11input [7:0] cmos_data , //cmos data 12output cmos_reset , //cmos reset 13output cmos_pwdn , //cmos pwer down 14//SDRAM接口15outputsdram_clk , //SDRAM 时钟16outputsdram_cke , //SDRAM 时钟有效17outputsdram_cs_n , //SDRAM 片选18outputsdram_ras_n , //SDRAM 行有效19outputsdram_cas_n , //SDRAM 列有效20outputsdram_we_n , //SDRAM 写有效21output [1:0] sdram_ba , //SDRAM Bank地址22output [1:0] sdram_dqm , //SDRAM 数据掩码23output [12:0] sdram_addr , //SDRAM 地址24inout [15:0] sdram_data , //SDRAM 数据 25//hdmi接口26outputtmds_clk_p , // TMDS 时钟通道27outputtmds_clk_n ,28output [2:0] tmds_data_p , // TMDS 数据通道29output [2:0] tmds_data_n3031 );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.0MHz38 parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL时钟频率,不超过400KHz39 40 //wire define41 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_complete58 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 output70 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 code79 //*****************************************************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 on89 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 71Mhz103.c1 ( hdmi_clk_5 ),//hdmi pixel clock*5 355Mhz104.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);158159 //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), //系统复位165166//用户写端口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), //写端口复位: 复位写地址,清空写FIFO174175//用户读端口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), //读端口复位: 复位读地址,清空读FIFO183 184//用户控制端口 185.sdram_read_valid (1'b1), //SDRAM 读使能186.sdram_pingpang_en (1'b1), //SDRAM 乒乓操作使能187.sdram_init_done (sdram_init_done), //SDRAM 初始化完成标志188189//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); 02 //例化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实时显示图像

【正点原子FPGA连载】第四十四章MT9V034摄像头HDMI显示实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。