一, 字节标志的注意点
由于摄像头的输出是 RGB56 格式, 所以需要将两帧的数据进行拼接, 之后送到上位机进行显示.
- reg byte_flag;
- always@(posedge cmos_pclk_i)
- begin
- if(!rst_n_reg[4])
- byte_flag <= 0;
- else if(cmos_href_r)
- byte_flag <= ~byte_flag;
- else
- byte_flag <= 0;
- end
上面 always 块是对拼接的两帧数据设置一个标志信号, 在 byte_flag==1 时进行拼接, 既然要进行拼接, 就需要将数据进行同步寄存, 故有
- 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 块
- 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 时候进行两帧数据拼接.
由于数据需要拼接, 拼接完毕后的数据才是有效数据, 那么必然需要一个标志作为输出有效信号, 也就是表明此时数据有效的信号, 所以存在以下代码块:
- 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 块写在一起更容易明白, 可参考小梅哥例程中的配置方式,
- //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 配置初始化过程.
来源: https://www.cnblogs.com/luxinshuo/p/11826567.html