为了配合开发板的使用,笔者搞了一个OV5640的摄像头模组,OV5640具体的相关手册及资料网上已经很多,感兴趣的都可以自行去查找,基本大同小异。这里也不把OV5640初始化的代码贴出来,因为就是简单的类似I2C接口配置数据。这里主要讲下初始化后的CMOS数据的解码,笔者是根据自己的需求把数据的VS,HS信号分别表示在了数据流的第一第二位,不过也是处理后的表示。

  这里初始化后的数据是RGB565的数据格式,对于初始化完成的COMS,一般情况是先要把前面不稳定的帧弃,笔者这里设置为15帧。具体可根据代码来解读,笔者前面做的边缘检测,高斯滤波就是基于此解码方式做的实验。

  顶层文件Cmosbuf.v:

  1 //**************************************************************************
2 // *** file name : Cmosbuf.v
3 // *** version : 1.0
4 // *** Description : Cmos data turn to stream
5 // *** Blogs : https://www.cnblogs.com/WenGalois123/
6 // *** Author : Galois_V
7 // *** Date : 2022.08.23
8 // *** Changes : Initial
9 //**************************************************************************
10 `timescale 1ns/1ps
11 module Cmosbuf
12 #(
13 parameter DROP_FPS = 15 ,
14 parameter FIFO_DEPTH = 2048 ,
15 parameter H_Active = 1280 ,
16 parameter V_Active = 720
17 )
18 (
19 input i_sys_clk ,
20 input i_sys_rstn ,
21 input i_cmos_clk ,
22 input i_cmos_pclk ,
23 input i_cmos_vs ,
24 input i_cmos_hs ,
25 input [7:0] i_cmos_data ,
26 output o_cmos_xclk ,
27 input i_fifo_ready ,
28 output [31:0] o_stream_data ,
29 output o_stream_valid ,
30 output o_frame_rst ,
31 output o_cmos_vs
32 );
33 wire w_cmos_vs ;
34 wire w_cmos_hs ;
35 wire w_cmos_de ;
36 wire [15:0] w_cmos_data ;
37 wire w_start_frame ;
38 wire w_end_line ;
39 wire [17:0] w_fifo_din ;
40 wire [17:0] w_fifo_dout ;
41 wire w_rst_vs ;
42 reg [5:0] r_sys_rstn ;
43 reg [3:0] r_vs_buf ;
44
45 function integer clog;
46 input [31:0] i_data;
47 begin
48 for(clog=0;i_data >0; clog = clog + 1)
49 begin
50 i_data = i_data >> 1;
51 end
52 end
53 endfunction
54
55 always@(posedge i_cmos_clk)
56 begin
57 r_sys_rstn <= {r_sys_rstn[4:0],i_sys_rstn};
58 end
59 Cmosdecode
60 #(
61 .DROP_FPS (DROP_FPS ),
62 .H_Active (H_Active ),
63 .V_Active (V_Active )
64 )u_Cmosdecode
65 (
66 .i_sys_clk (i_sys_clk ),
67 .i_sys_rstn (i_sys_rstn ),
68 .i_cmos_clk (i_cmos_clk ),
69 .i_cmos_vs (i_cmos_vs ),
70 .i_cmos_hs (i_cmos_hs ),
71 .i_cmos_data (i_cmos_data ),
72 .o_cmos_xclk ( ),
73 .o_cmos_vs (w_cmos_vs ),
74 .o_cmos_hs (w_cmos_hs ),
75 .o_cmos_de (w_cmos_de ),
76 .o_cmos_data (w_cmos_data ),
77 .o_start_frame (w_start_frame ),
78 .o_end_line (w_end_line )
79 );
80
81 always@(posedge i_sys_clk)
82 begin
83 r_vs_buf <= {r_vs_buf[2:0],i_cmos_vs};
84 end
85
86 assign w_rst_vs = ~r_vs_buf[2] & r_vs_buf[3];
87 assign w_fifo_din = {w_start_frame,w_end_line,w_cmos_data};
88
89 xpm_fifo_async
90 #(
91 .FIFO_MEMORY_TYPE ("block" ),
92 .ECC_MODE ("no_ecc" ),
93 .RELATED_CLOCKS (0 ),
94 .FIFO_WRITE_DEPTH (FIFO_DEPTH ),
95 .WRITE_DATA_WIDTH (18 ),
96 .WR_DATA_COUNT_WIDTH (clog(FIFO_DEPTH) ),
97 .PROG_FULL_THRESH (10 ),
98 .FULL_RESET_VALUE (0 ),
99 .USE_ADV_FEATURES ("0707" ),
100 .READ_MODE ("fwft" ),
101 .FIFO_READ_LATENCY (0 ),
102 .READ_DATA_WIDTH (18 ),
103 .RD_DATA_COUNT_WIDTH (clog(FIFO_DEPTH) ),
104 .PROG_EMPTY_THRESH (10 ),
105 .DOUT_RESET_VALUE ("0" ),
106 .CDC_SYNC_STAGES (2 ),
107 .WAKEUP_TIME (0 )
108 )
109 u_cmos_fifo
110 (
111 .rst (w_rst_vs | (~r_sys_rstn[5])),
112 .wr_clk (i_cmos_clk ),
113 .wr_en (w_cmos_de ),
114 .din (w_fifo_din ),
115 .full ( ),
116 .overflow ( ),
117 .prog_full ( ),
118 .wr_data_count ( ),
119 .almost_full ( ),
120 .wr_ack ( ),
121 .wr_rst_busy ( ),
122 .rd_clk (i_sys_clk ),
123 .rd_en (i_fifo_ready ),
124 .dout (w_fifo_dout ),
125 .empty (w_fifo_empty ),
126 .underflow ( ),
127 .rd_rst_busy ( ),
128 .prog_empty ( ),
129 .rd_data_count ( ),
130 .almost_empty ( ),
131 .data_valid ( ),
132 .sleep (1'b0 ),
133 .injectsbiterr (1'b0 ),
134 .injectdbiterr (1'b0 ),
135 .sbiterr ( ),
136 .dbiterr ( )
137 );
138 assign o_cmos_xclk = i_cmos_pclk;
139 assign o_stream_valid = ~w_fifo_empty & i_fifo_ready;
140 assign o_cmos_vs = w_cmos_vs;
141 assign o_frame_rst = w_rst_vs;
142 assign o_stream_data = {w_fifo_dout[17:16],6'd0,w_fifo_dout[15:11],3'd0,w_fifo_dout[10:5],2'd0,w_fifo_dout[4:0],3'd0};
143
144 endmodule

  上述的i_cmos_pclk是需要提供给FPGA外部OV5640的o_cmos_xclk,而i_cmos_clk则是OV5640输入像素数据的同步时钟,i_sys_clk这里是整个系统的时钟。如果i_sys_clk与i_cmos_clk不是同一个时钟就存在跨时钟域,因此这里通过一个异步FIFO来实现跨时钟域的处理。

  数据解码模块Cmosdecode.v

  1 //**************************************************************************
2 // *** file name : Cmosdecode.v
3 // *** version : 1.0
4 // *** Description : Cmos data decode
5 // *** Blogs : https://www.cnblogs.com/WenGalois123/
6 // *** Author : Galois_V
7 // *** Date : 2022.08.23
8 // *** Changes : Initial
9 //**************************************************************************
10 `timescale 1ns/1ps
11 module Cmosdecode
12 #(
13 parameter DROP_FPS = 15 ,
14 parameter H_Active = 640 ,
15 parameter V_Active = 480
16 )
17 (
18 input i_sys_clk ,
19 input i_sys_rstn ,
20 input i_cmos_clk ,
21 input i_cmos_vs ,
22 input i_cmos_hs ,
23 input [7:0] i_cmos_data ,
24 output o_cmos_xclk ,
25 output o_cmos_vs ,
26 output o_cmos_hs ,
27 output o_cmos_de ,
28 output [15:0] o_cmos_data ,
29 output o_start_frame ,
30 output o_end_line
31 );
32 wire w_vs_pos ;
33 wire w_vs_neg ;
34 wire w_hs_neg ;
35 reg [5:0] r_sys_rstn ;
36 reg [2:0] r_vs ;
37 reg [2:0] r_hs ;
38 reg [7:0] r_cmos_data ;
39 reg [6:0] r_cmos_fps ;
40 reg r_out_en ;
41 reg r_1st_hs ;
42 reg r_reverse_en ;
43 reg r_reverse_en_dly;
44 reg [15:0] r_rgb_data ;
45 reg [11:0] r_cnt_pixel ;
46
47 always@(posedge i_cmos_clk)
48 begin
49 r_sys_rstn <= {r_sys_rstn[4:0],i_sys_rstn};
50 end
51
52 always@(posedge i_cmos_clk)
53 begin
54 r_vs <= {r_vs[1:0],i_cmos_vs};
55 r_hs <= {r_hs[1:0],i_cmos_hs};
56 end
57 always@(posedge i_cmos_clk)
58 begin
59 r_cmos_data <= i_cmos_data;
60 end
61 assign w_vs_pos = ~r_vs[2] & r_vs[1];
62 assign w_vs_neg = ~r_vs[1] & r_vs[2];
63 assign w_hs_neg = ~r_hs[1] & r_hs[2];
64 /******************************************************************************\
65 Drop some frames
66 \******************************************************************************/
67 always@(posedge i_cmos_clk)
68 begin
69 if(~r_sys_rstn[5])
70 begin
71 r_cmos_fps <= 'd0;
72 end
73 else if(r_cmos_fps >= DROP_FPS)
74 begin
75 r_cmos_fps <= r_cmos_fps;
76 end
77 else if(w_vs_pos)
78 begin
79 r_cmos_fps <= r_cmos_fps + 1'b1;
80 end
81 end
82 always@(posedge i_cmos_clk)
83 begin
84 if(~r_sys_rstn[5])
85 begin
86 r_out_en <= 'd0;
87 end
88 else if(r_cmos_fps >= DROP_FPS)
89 begin
90 r_out_en <= 1'b1;
91 end
92 else
93 begin
94 r_out_en <= r_out_en;
95 end
96 end
97 always@(posedge i_cmos_clk)
98 begin
99 if(~r_sys_rstn[5])
100 begin
101 r_1st_hs <= 'd0;
102 end
103 else if(w_vs_neg)
104 begin
105 r_1st_hs <= 1'b1;
106 end
107 else if(w_hs_neg)
108 begin
109 r_1st_hs <= 'd0;
110 end
111 end
112 /******************************************************************************\
113 decode the data from cmos
114 \******************************************************************************/
115 always@(posedge i_cmos_clk)
116 begin
117 if(~r_sys_rstn[5])
118 begin
119 r_reverse_en <= 'd0;
120 end
121 else if(r_hs[1])
122 begin
123 r_reverse_en <= ~r_reverse_en;
124 end
125 else
126 begin
127 r_reverse_en <= 'd0;
128 end
129 end
130 always@(i_cmos_clk)
131 begin
132 if(~r_sys_rstn[5])
133 begin
134 r_reverse_en_dly <= 'd0;
135 end
136 else
137 begin
138 r_reverse_en_dly <= r_reverse_en;
139 end
140 end
141 always@(posedge i_cmos_clk)
142 begin
143 if(~r_sys_rstn[5])
144 begin
145 r_rgb_data <= 'd0;
146 end
147 else if(r_hs[1])
148 begin
149 r_rgb_data <= {r_rgb_data[7:0],r_cmos_data};
150 end
151 else if(~r_hs[1])
152 begin
153 r_rgb_data <= 'd0;
154 end
155 end
156 always@(posedge i_cmos_clk)
157 begin
158 if(~r_sys_rstn[5])
159 begin
160 r_cnt_pixel <= 'd0;
161 end
162 else if(~r_hs[2])
163 begin
164 r_cnt_pixel <= 'd0;
165 end
166 else if(r_reverse_en)
167 begin
168 r_cnt_pixel <= r_cnt_pixel + 1'b1;
169 end
170 end
171 /******************************************************************************\
172 output cmos signal
173 \******************************************************************************/
174 assign o_cmos_vs = r_out_en ? r_vs[2] : 1'b0;
175 assign o_cmos_hs = r_out_en ? r_hs[2] : 1'b0;
176 assign o_cmos_de = r_reverse_en & o_cmos_hs & (r_cnt_pixel < H_Active);
177 assign o_start_frame = r_reverse_en & (r_cnt_pixel == 'd0) & r_1st_hs;
178 assign o_end_line = r_reverse_en & (r_cnt_pixel == H_Active - 1'b1);
179 assign o_cmos_xclk = i_cmos_clk;
180 assign o_cmos_data = r_rgb_data;
181
182 endmodule

  以上便是CMOS数据的解码的Verilog代码,笔者在前面两个实验已经验证过了,是可以正常使用的。

最新文章

  1. C#实现K-MEDOIDS聚类算法
  2. js方式找出数组中重复数最多的那个数,并返回该数以及重复次数
  3. 深入理解gradle编译-Android基础篇
  4. mmo设计
  5. Asp.net Mvc4 使用Cas单点登录
  6. form表单类标签汇总
  7. SpringMVC 避免IE执行AJAX时,返回JSON出现下载文件
  8. 调度器(scheduler)
  9. table导出到excel的两种方法
  10. indexOf()--数组去重
  11. python 异步协程
  12. 聊聊javaMail
  13. How to get Pycharm
  14. NODE_ENV不是内部或外部命令,也不是可运行的程序
  15. ionic 锁定方向 禁止横屏 orientation
  16. 转:The Difference Between a LayoutTransform and a RenderTransform
  17. unhandledException
  18. 安装e(fx)clipse到Eclipse (JavaFX工具)
  19. lync2013 错误: 已为不同的传输层安全性(TLS)目标找到类型为“McxInternal”且完全限定的域名(FQDN)为
  20. 【Spring学习笔记-MVC-8】SpringMVC之类型转换Converter

热门文章

  1. php中 mysql 中文乱码解决办法
  2. sql查询多个结果字段通过逗号分隔为同一行显示、sql查询结果有符号分隔的字段拆分多行显示
  3. 溢出标志位OF与进位标志位CF判断
  4. node.js 中删除,修改等接口
  5. I2C接口
  6. DevExpress gridControl 字体居住
  7. 右键无法新建word文件怎么办?
  8. grafana+prometheus+tomcat 监控tomcat
  9. 别再写一堆的 for 循环了!Java 8 中的 Stream 轻松遍历树形结构,是真的牛逼
  10. 文件下载,后端接口,django,flask