OV5640攝像頭的數據處理配置流程(一)


  1 module RGB_init(
  2     //系統信號輸入(時鍾+復位)
  3     input cmos_clk_i,  //模塊控制時鍾
  4     input rst_n_i,     //系統復位信號
  5     //OV5640輸出信號(從5640輸入到FPGA)
  6     input cmos_pclk_i,  //攝像頭時鍾
  7     input cmos_href_i,   //幀輸出行同步信號
  8     input cmos_vsync_i,  //場同步信號
  9     input [7:0] cmos_data_i,  //像素數據
 10     //模塊的輸出信號
 11     output clk_ce,   //攝像頭幀數據輸出/捕獲使能信號(12Mhz),該信號的理解是最難的
 12     output de_o,     //數據有效信號
 13     output [23:0] rgb_o,  //輸出的24bit像素數據
 14     output vs_o, //輸出的場同步信號
 15     output hs_o,  //輸出的行同步信號
 16     //輸出道5640模塊的像素時鍾
 17     output cmos_xclk   
 18     );
 19  
 20  //為了保持系統穩定,需要丟棄前期一部分幀圖像,此處選擇丟棄15個,自行選擇,也有10個的
 21  parameter[3:0]CMOS_FRAME_WAITCNT=15;
 22  
 23  assign cmos_xclk=cmos_clk_i;   //xclk為5640驅動時鍾,為24/25Mhz
 24  
 25  //在米聯客的對復位信號的處理中,復位信號延遲了5個時鍾,好像不延遲也可以,可以在例程2中查看
 26  //個人認為復位信號的處理是為了使復位信號保持一個完整的信號周期
 27  reg[4:0]rst_n_reg=5'd0;
 28  always@(posedge cmos_clk_i)  //同步於FPGA輸入時鍾
 29  begin
 30   rst_n_reg<={rst_n_reg[3:0],rst_n_i};
 31  end 
 32  
 33  reg cmos_href_r=1'b0;   //將行同步信號進行緩存
 34  reg [1:0]cmos_vsync_r;   //將場同步信號進行緩存
 35  reg[7:0]cmos_data_r;   //將5640輸出到FPGA的數據進行寄存,因為是處理輸出16bit,就是將兩個周期的輸入信號進行拼接處理
 36  //進行行、場同步信號進行緩存,輸入數據進行一級緩存
 37  always@(posedge cmos_pclk_i)
 38  begin
 39   cmos_vsync_r<=cmos_vsync_i;
 40   cmos_href_r<=cmos_href_i;
 41   cmos_data_r<=cmos_data_i;
 42  end 
 43  
 44  //為了判斷一幀數據的開始&結束,同時對幀進行計數,對場同步信號進行寄存
 45  reg [1:0]cmos_vsync_d;
 46  always@(posedge cmos_pclk_i)   //同步於5640輸出時鍾
 47  begin
 48   cmos_vsync_d<={cmos_vsync_d[0],cmos_vsync_r};
 49  end 
 50  //場開始與結束信號
 51  wire vs_start;
 52  assign vs_start=(!cmos_vsync_d[1])&(cmos_vsync_d[0]);   //posedge mark the action
 53  wire vs_end;
 54  assign vs_end=(cmos_vsync_d[1])&(!cmos_vsync_d[0]); 
 55  
 56  //行同步信號緩存
 57  reg [1:0]cmos_href_d=2'd0;
 58  always@(posedge cmos_pclk_i)
 59  begin
 60   cmos_href_d<={cmos_href_d[0],cmos_href_r};
 61  end 
 62  
 63  //前期丟棄部分幀
 64  reg [4:0]frame_cnt=0;  //幀計數器
 65  reg out_en=0;   //開始正常啟動操作
 66  always@(posedge cmos_pclk_i) 
 67   if(!rst_n_reg[4])
 68   begin
 69    frame_cnt<=5'd0;
 70     out_en<=1'b0;
 71   end
 72  else begin 
 73  if(vs_start) begin
 74  frame_cnt<=frame_cnt+1;
 75  out_en<=0;
 76  end 
 77  else if(frame_cnt>=CMOS_FRAME_WAITCNT) 
 78  begin
 79   out_en<=1;
 80   frame_cnt<=CMOS_FRAME_WAITCNT;  //保持正常幀處理完畢
 81  end 
 82  end  
 83  //由於輸出的是24bit數據,是由16bit數據轉化而來,將兩個幀的RGB數據進行拼接
 84  reg href_cnt=0;
 85  reg data_en=1'b0;
 86  reg [15:0]RGBm=16'd0;   //middle RGB data
 87   
 88  always@(posedge cmos_pclk_i)begin
 89  if(!rst_n_reg[4])begin
 90   href_cnt<=0;
 91   data_en<=1'b0; 
 92   RGBm<=16'd0;  
 93  end 
 94  //兩個數據拼接完畢之后將data_en置一,第0次拼接使低8位有效,第1次使得低八位有效(位移)
 95  else begin
 96   href_cnt<=(cmos_href_r)?href_cnt+1'b1:href_cnt;
 97   data_en<=(href_cnt==1);  
 98   if(href_cnt) RGBm<={RGBm[7:0],cmos_data_r};  //此處cmos_data_r lag 2 clocks,thus later all lag 2clks 
 99  end 
100  end 
101  
102  assign rgb_o={RGBm[15:11],3'd0,RGBm[10:5],2'd0,RGBm[4:0],3'd0};
103  //模塊行同步輸出
104  assign hs_o=out_en?(cmos_href_d[0]):0;   //為了與暑促信號同步,該同步信號是滯后兩個pclk
105  //模塊場同步信號輸出
106  assign vs_o=out_en?(cmos_vsync_r):0;  //行同步結束之后開始場同步,場同步信號知乎一個pclk,覺得這個程序真的很nb,考慮的太全了
107  //模塊數據輸出同步時鍾信號,12M,
108  assign de_o=out_en?data_en:0;
109  //輸出時鍾enable signal
110  assign clk_ce=out_en?((data_en&hs_o)||!hs_o):0;  //其實好像1也行,沒有邊沿驅動
111  //在init complete的情況下,d0是經過了2個pclk延遲的,該output信號同步(更准確地說是對齊)於這個數據輸入時的時鍾,
112  //同步於12Mhz的data_en時鍾
113  //該模塊每2個pclk輸出一次rgb[23:0]的數據,需要聽過clk_ce對時鍾頻率進行同步,該處理解決了模塊接口之間的同步問題
114  /*
115    舉例說明:
116        在do==0時,clk_ce恆為高,沒有時鍾脈沖
117         在do==1時,該時鍾始終同步於12M時鍾
118  */
119 endmodule 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM