OV5640攝像頭配置一些值得注意的關鍵點(三)

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

相關文章
相關標籤/搜索