1、字節標誌的注意點spa
因爲攝像頭的輸出是RGB56格式,因此須要將兩幀的數據進行拼接,以後送到上位機進行顯示。code
1 reg byte_flag; 2 3 always@(posedge cmos_pclk_i) 4 begin 5 if(!rst_n_reg[4]) 6 byte_flag <= 0; 7 else if(cmos_href_r) 8 byte_flag <= ~byte_flag; 9 else 10 byte_flag <= 0; 11 end
上面always塊是對拼接的兩幀數據設置一個標誌信號,在byte_flag==1時進行拼接,既然要進行拼接,就須要將數據進行同步寄存,故有blog
always@(posedge cmos_pclk_i) begin if(!rst_n_reg[4]) cmos_data_d0 <= 8'd0; else if(cmos_href_r) cmos_data_d0 <= cmos_data_r; //MSB -> LSB else if(~cmos_href_r) cmos_data_d0 <= 8'd0; end
將當前的攝像頭輸出數據cmos_data_r寄存到cmos_data_d0,至關於延遲了一個時鐘。同步
那麼,在何時進行拼接,就是在byte_flag==1時,但是須要注意第一個always塊的byte_falg賦值是在cmos_pclk_i的下一個時鐘的上升沿完成,在第一個always塊結束時byte_flag仍是0,須要等待byte_falg==1,因此第三個always塊class
reg [15:0] rgb565; always@(posedge cmos_pclk_i) begin if(!rst_n_reg[4]) rgb565 <= 16'd0; else if(cmos_href_r&byte_flag) rgb565 <= {cmos_data_d0,cmos_data_r}; //MSB -> LSB else if(~cmos_href_r) rgb565 <= 8'd0; end
上述always塊等待byte_flag變爲高電平。當byte_flag==1時候進行兩幀數據拼接。sed
因爲數據須要拼接,拼接完畢後的數據纔是有效數據,那麼必然須要一個標誌做爲輸出有效信號,也就是代表此時數據有效的信號,因此存在如下代碼塊:配置
reg byte_flag_r0; always@(posedge cmos_pclk_i) begin if(!rst_n_reg[4]) byte_flag_r0 <= 0; else byte_flag_r0 <= byte_flag; end assign clk_ce =out_en? byte_flag_r0:1'b0;
爲何須要定義byte_flag_r0將byte_flag延時一個像素時鐘呢?由於byte_flag_r0比byte_flga延時一個像素時鐘,在這個延時的時鐘過程當中,完成數據的拼接,當完成數據拼接後,正好此時的數據有效且byte_flag_r0==1,故將byte_flag_r0做爲輸出有效標誌。數據
將上面的第一個第二個always塊寫在一塊兒更容易明白,可參考小梅哥例程中的配置方式,di
//capture and sync RGB565 cmos_din reg [7:0] cmos_din_r; reg [15:0] cmos_frame_data_r; reg byte_flag; always@(posedge cmos_pclk or negedge rst_n) if(!rst_n) begin cmos_din_r <= 0; byte_flag <= 0; cmos_frame_data_r <= 0; end else if(cmos_href) begin byte_flag <= ~byte_flag; cmos_din_r <= cmos_din; if(byte_flag == 1'b1) cmos_frame_data_r <= {cmos_din_r, cmos_din}; //MSB -> LSB else cmos_frame_data_r <= cmos_frame_data_r; end else begin cmos_din_r <= 0; byte_flag <= 0; cmos_frame_data_r <= cmos_frame_data_r; end
(二)、此外,在代碼案例中,存在前n個幀數據丟棄的狀況,目前見過10幀、12幀、15幀,其做用我的理解爲預留出5640攝像頭的IIC配置初始化過程。co