OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 625|回复: 0

[国产FPGA] 《ATK-DFPGL22G 之FPGA开发指南》第四十二章 OV5640摄像头HDMI显示实验

[复制链接]

1070

主题

1081

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4443
金钱
4443
注册时间
2019-5-8
在线时间
1199 小时
发表于 2023-12-22 16:30:48 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2023-12-21 15:50 编辑

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

1)实验平台:正点原子 ATK-DFPGL22G开发板

2) 章节摘自【正点原子】ATK-DFPGL22G之FPGA开发指南_V1.0


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz-PGL22G.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)FPGA技术交流QQ群:435699340

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

在OV5640摄像头RGB-LCD显示实验中,成功的在LCD屏上实时显示出了摄像头采集的图像。本章将使用FPGA开发板实现对OV5640的数字图像采集并在HDMI显示器上实时显示。
本章包括以下几个部分:   
1.1        简介
1.2        实验任务
1.3        硬件设计
1.4        程序设计
1.5        下载验证

1.1 简介
在“OV5640摄像头RGB-LCD显示实验”中对OV5640的视频传输时序、SCCB协议以及寄存器的配置信息等内容作了详细的介绍,如果大家对这部分内容不是很熟悉的话,请参考“OV5640摄像头RGB-LCD显示实验”中的简介部分。

1.2 实验任务
本节实验任务是使用ATK-DFPGL22G开发板及OV5640摄像头实现图像采集,并通过HDMI接口驱动HDMI显示器,并实时显示出图像。

1.3 硬件设计
摄像头扩展接口原理图及OV5640模块说明与“OV5640摄像头RGB-LCD显示实验”完全相同,请参考“OV5640摄像头RGB-LCD显示实验”硬件设计部分。HDMI接口部分的硬件设计请参考“HDMI彩条显示实验”中的硬件设计部分。
由于OV5640、HDMI接口和DDR3引脚数目较多且在前面相应的章节中已经给出它们的管脚列表,这里不再列出管脚分配。

1.4 程序设计
根据实验任务,首先我们设计如图 42.4.1所示的系统框图,本章实验的系统框架延续了“OV5640摄像头RGB-LCD显示实验”的整体架构。本次实验包括以下模块:时钟模块、IIC配置模块、IIC驱动模块、DDR3控制器模块、摄像头图像采集模块和HDMI顶层模块。其中IIC配置模块、IIC驱动模块、摄像头图像采集模块和DDR3控制器模块我们没有做任何修改,这些模块在“OV5640摄像头RGB-LCD显示实验”中已经说明过,这里不再详述,本次实验只是将LCD顶层模块替换成了HDMI顶层模块。本次实验也不需要图像尺寸配置模块,因为本次实验摄像头的分辨率是固定的,其分辨率为1280x720。
OV5640摄像头HDMI显示系统框图如下图所示:
image001.png
图 42.4.1 顶层系统框图
由上图可知,时钟模块为HDMI顶层模块、DDR3控制模块以及I2C驱动模块提供驱动时钟。摄像头驱动模块控制着传感器初始化的开始与结束。传感器初始化完成后图像采集模块将采集到的数据写入DDR3控制模块,HDMI顶层模块从DDR3控制模块中读出数据并驱动显示器显示,这时整个系统才完成了数据的采集、缓存与显示。需要注意的是图像数据采集模块是在DDR3和传感器都初始化完成之后才开始输出数据的,避免了在DDR3初始化过程中向里面写入数据。
顶层模块的代码如下:
  1. 1   module ov5640_hdmi(
  2. 2        input            sys_clk         ,
  3. 3        input            sys_rst_n       ,
  4. 4                                          
  5. 5        output           tmds_clk_p      ,  // TMDS 时钟通道
  6. 6        output           tmds_clk_n      ,
  7. 7        output [2:0      tmds_data_p     ,  // TMDS 数据通道
  8. 8        output [2:0      tmds_data_n     ,
  9. 9        //摄像头接口                     
  10. 10       input            cam_pclk        ,  //cmos 数据像素时钟
  11. 11       input            cam_vsync       ,  //cmos 场同步信号
  12. 12       input            cam_href        ,  //cmos 行同步信号
  13. 13       input  [7:0     cam_data        ,  //cmos 数据
  14. 14       output           cam_rst_n       ,  //cmos 复位信号,低电平有效
  15. 15       output           cam_pwdn        ,  //电源休眠模式选择 0:正常模式 1:电源休眠模式
  16. 16       output            cam_scl         ,  //cmos SCCB_SCL线
  17. 17       inout            cam_sda         ,  //cmos SCCB_SDA线
  18. 18       //DDR3接口
  19. 19       input            pad_loop_in      ,  //低位温度补偿输入
  20. 20       input            pad_loop_in_h    ,  //高位温度补偿输入
  21. 21       output           pad_rstn_ch0     ,  //Memory复位
  22. 22       output           pad_ddr_clk_w    ,  //Memory差分时钟正
  23. 23       output           pad_ddr_clkn_w   ,  //Memory差分时钟负
  24. 24       output           pad_csn_ch0      ,  //Memory片选
  25. 25       output [15:0    pad_addr_ch0     ,  //Memory地址总线
  26. 26       inout  [16-1:0  pad_dq_ch0       ,  //数据总线
  27. 27       inout  [16/8-1:0 pad_dqs_ch0     ,  //数据时钟正端
  28. 28       inout  [16/8-1:0 pad_dqsn_ch0    ,  //数据时钟负端
  29. 29       output [16/8-1:0 pad_dm_rdqs_ch0 ,  //数据Mask
  30. 30       output           pad_cke_ch0      ,  //Memory差分时钟使
  31. 31       output           pad_odt_ch0      ,  //On Die Terminati
  32. 32       output           pad_rasn_ch0     ,  //行地址strobe
  33. 33       output           pad_casn_ch0     ,  //列地址strobe
  34. 34       output           pad_wen_ch0      ,  //写使能
  35. 35       output [2:0      pad_ba_ch0       ,  //Bank地址总线
  36. 36       output           pad_loop_out     ,  //低位温度补偿输出
  37. 37       output           pad_loop_out_h      //高位温度补偿输出
  38. 38      );
  39. 39  
  40. 40  //parameter define
  41. 41  parameter  V_CMOS_DISP = 11'd720     ; //CMOS分辨率--行
  42. 42  parameter  H_CMOS_DISP = 11'd1280    ; //CMOS分辨率--列  
  43. 43  parameter  TOTAL_H_PIXEL = 12'd2570  ;     
  44. 44  parameter  TOTAL_V_PIXEL = 12'd980   ;
  45. 45  parameter  APP_ADDR_MIN = 28'd0      ; //ddr3读写起始地址,以一个16bit的数据为一个单位
  46. 46  parameter  APP_ADDR_MAX = 28'd921600 ; //ddr3读写结束地址,以一个16bit的数据为一个单位
  47. 47  parameter  BURST_LENGTH = 8'd160     ; //ddr3读写突发长度,80个128bit的数据
  48. 48  
  49. 49  //wire define
  50. 50  //PLL
  51. 51  wire        pixel_clk       ;  //像素时钟75M
  52. 52  wire        pixel_clk_5x    ;  //5倍像素时钟375M
  53. 53  wire        clk_50m         ;  //output 50M
  54. 54  wire        clk_locked      ;
  55. 55  //OV5640
  56. 56  wire        cmos_frame_vsync;  //帧有效信号
  57. 57  wire        cmos_frame_valid;  //数据有效使能信号
  58. 58  wire [15:0 wr_data        ;  //OV7725写入DDR3控制器模块的数据
  59. 59  //HDMI
  60. 60  wire        video_vs        ;  //场同步信号
  61. 61  wire [15:0 rd_data        ;  //DDR3控制器模块读数据给HDMI
  62. 62  wire        rdata_req       ;  //DDR3控制器模块读使能
  63. 63  //DDR3
  64. 64  wire        fram_done       ; //DDR中已经存入一帧画面标志
  65. 65  wire        ddr_init_done   ;//ddr3初始化完成
  66. 66  
  67. 67  //*****************************************************
  68. 68  //**                    main code
  69. 69  //*****************************************************
  70. 70  
  71. 71  //例化PLL IP核
  72. 72  pll_clk  u_pll_clk(
  73. 73       .pll_rst        (~sys_rst_n  ),
  74. 74       .clkin1         (sys_clk     ),
  75. 75       .clkout0        (pixel_clk   ), //像素时钟75M
  76. 76       .clkout1        (pixel_clk_5x), //5倍像素时钟375M
  77. 77       .clkout2        (clk_50m     ), //output50M
  78. 78       .pll_lock       (clk_locked  )
  79. 79  );
  80. 80  
  81. 81  //ov5640 驱动
  82. 82  ov5640_dri u_ov5640_dri(
  83. 83       .clk               (clk_50m        ),
  84. 84       .rst_n             (sys_rst_n      ),
  85. 85                                          
  86. 86       .cam_pclk          (cam_pclk       ),
  87. 87       .cam_vsync         (cam_vsync      ),
  88. 88       .cam_href          (cam_href       ),
  89. 89       .cam_data          (cam_data       ),
  90. 90       .cam_rst_n         (cam_rst_n      ),
  91. 91       .cam_pwdn          (cam_pwdn       ),
  92. 92       .cam_scl           (cam_scl        ),
  93. 93       .cam_sda           (cam_sda        ),
  94. 94      
  95. 95       .capture_start     (ddr_init_done  ),
  96. 96       .cmos_h_pixel      (H_CMOS_DISP    ),
  97. 97       .cmos_v_pixel      (V_CMOS_DISP    ),
  98. 98       .total_h_pixel     (TOTAL_H_PIXEL  ),
  99. 99       .total_v_pixel     (TOTAL_V_PIXEL  ),
  100. 100      .cmos_frame_vsync  (cmos_frame_vsync),
  101. 101      .cmos_frame_href   (               ),
  102. 102      .cmos_frame_valid  (cmos_frame_valid),
  103. 103      .cmos_frame_data   (wr_data        )
  104. 104      );
  105. 105
  106. 106 //ddr3
  107. 107 ddr3_top u_ddr3_top(
  108. 108      .refclk_in             (clk_50m        ),
  109. 109      .rst_n                 (sys_rst_n      ),
  110. 110      .app_addr_rd_min       (APP_ADDR_MIN   ),
  111. 111      .app_addr_rd_max       (APP_ADDR_MAX   ),
  112. 112      .rd_bust_len           (BURST_LENGTH   ),
  113. 113      .app_addr_wr_min       (APP_ADDR_MIN   ),
  114. 114      .app_addr_wr_max       (APP_ADDR_MAX   ),
  115. 115      .wr_bust_len           (BURST_LENGTH   ),
  116. 116      .ddr3_read_valid       (1'b1            ),
  117. 117      .ddr3_pingpang_en      (1'b1            ),
  118. 118      .wr_clk                (cam_pclk       ),
  119. 119      .rd_clk                (pixel_clk      ),
  120. 120      .datain_valid          (cmos_frame_valid),
  121. 121      .datain                (wr_data        ),
  122. 122     .rdata_req             (rdata_req      ),
  123. 123      .rd_load               (video_vs       ),
  124. 124      .wr_load               (cmos_frame_vsync),
  125. 125      .fram_done             (fram_done      ),
  126. 126      .dataout               (rd_data        ),
  127. 127      .pll_lock              (pll_lock       ),
  128. 128      .ddr_init_done         (ddr_init_done  ),
  129. 129      .ddrphy_rst_done       (               ),
  130. 130      .pad_loop_in           (pad_loop_in    ),
  131. 131      .pad_loop_in_h         (pad_loop_in_h  ),
  132. 132      .pad_rstn_ch0          (pad_rstn_ch0   ),
  133. 133      .pad_ddr_clk_w         (pad_ddr_clk_w  ),
  134. 134      .pad_ddr_clkn_w        (pad_ddr_clkn_w ),
  135. 135      .pad_csn_ch0           (pad_csn_ch0    ),
  136. 136     .pad_addr_ch0          (pad_addr_ch0   ),
  137. 137      .pad_dq_ch0            (pad_dq_ch0     ),
  138. 138      .pad_dqs_ch0           (pad_dqs_ch0    ),
  139. 139      .pad_dqsn_ch0          (pad_dqsn_ch0   ),
  140. 140      .pad_dm_rdqs_ch0       (pad_dm_rdqs_ch0 ),
  141. 141      .pad_cke_ch0           (pad_cke_ch0    ),
  142. 142      .pad_odt_ch0           (pad_odt_ch0    ),
  143. 143      .pad_rasn_ch0          (pad_rasn_ch0   ),
  144. 144      .pad_casn_ch0          (pad_casn_ch0   ),
  145. 145      .pad_wen_ch0           (pad_wen_ch0     ),
  146. 146      .pad_ba_ch0            (pad_ba_ch0     ),
  147. 147      .pad_loop_out          (pad_loop_out   ),
  148. 148      .pad_loop_out_h        (pad_loop_out_h )
  149. 149      
  150. 150      );  
  151. 151
  152. 152 //HDMI顶层模块
  153. 153 hdmi_top u_hdmi_top(
  154. 154      .hdmi_clk       (pixel_clk    ),
  155. 155      .hdmi_clk_5     (pixel_clk_5x ),
  156. 156      .sys_rst_n      (sys_rst_n    ),
  157. 157      .fram_done      (fram_done    ),
  158. 158      .clk_locked     (clk_locked   ),
  159. 159      .rd_data        (rd_data      ),
  160. 160      .rd_en          (rdata_req    ),
  161. 161      .video_vs       (video_vs     ),
  162. 162      .h_disp         (             ),
  163. 163      .v_disp         (             ),
  164. 164      .pixel_xpos     (             ),
  165. 165      .pixel_ypos     (             ),
  166. 166      .tmds_clk_p     (tmds_clk_p   ),
  167. 167      .tmds_clk_n     (tmds_clk_n   ),
  168. 168      .tmds_data_p    (tmds_data_p  ),
  169. 169      .tmds_data_n    (tmds_data_n  )
  170. 170      );
  171. 171
  172. 172 endmodule
复制代码
FPGA顶层模块(ov5640_hdmi)例化了以下四个模块:时钟模块(pll_clk)、OV5640驱动模块(ov5640_dri)、DDR3控制顶层模块(ddr3_top)和HDMI顶层模块(hdmi_top)。
时钟模块(pll_clk):时钟模块通过调用PLL IP核实现,为DDR3控制模块以及OV5640驱动模块中的I2C驱动模块提供驱动时钟,为HDMI模块提供像素时钟和5倍像素时钟(频率分别是75Mhz和375Mhz)。
OV5640驱动模块(ov5640_dri):OV5640驱动模块负责驱动OV5640 SCCB接口总线,将像素时钟驱动下的传感器输出的场同步信号、行同步信号以及8位数据转换成DDR3读写控制模块的写使能信号和16位写数据信号,完成对OV5640传感器图像的采集。
DDR3控制模块(ddr3_top):DDR3读写控制器模块负责驱动DDR3片外存储器,缓存图像传感器输出的图像数据。该模块将DDR3复杂的读写操作封装成类似FIFO的用户接口,非常方便用户的使用。有关DDR3控制模块的详细介绍请大家参考“DDR3读写测试实验”章节。
HDMI顶层模块(hdmi_top):HDMI顶层模块负责驱动HDMI显示器的驱动信号的输出,同时为其他模块提供场同步信号和数据请求信号。HDMI顶层模块例化了HDMI视频显示驱动模块(video_driver)和HDMI驱动模块(dvi_transmitter_top)。
HDMI视频显示驱动模块负责产生行场信号和数据有效使能信号和像素点的横纵坐标,并将内部信号data_req(数据请求信号)输出至端口,方便从DD3控制器中读取数据。HDMI驱动模块负责将RGB565格式的视频图像转换成TMDS数据输出。有关HDMI视频显示驱动模块、HDMI驱动模块的详细介绍请大家参考“HDMI彩条显示实验”章节。

1.5 下载验证
编译完工程之后我们就可以开始下载程序。将OV5640摄像头模块插在ATK-DFPGL22G开发板的“OLED/CAMERA”插座上,并将HDMI电缆一端连接到开发板上的HDMI插座、另一端连接到显示器。将下载器一端连电脑,另一端与开发板上的JTAG端口连接,连接电源线并打开电源开关。接下来我们下载程序,验证OV5640 HDMI实时显示功能。下载完成后观察HDMI显示器显示的图案如下图所示,说明OV5640 HDMI实时显示程序下载验证成功。
QQ截图20231221154948.png
图 42.5.1 HDMI实时显示图像
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-6-10 01:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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