赞
踩
一、数据采集时序
上一篇我们讨论了OV5640的上电时序,下面给出数据采集的时序。
上一篇已经提到了VSYNC是场同步信号,每一次拉高就表示一帧图像的开始。两次拉高中间的时间对应上图中的(1),这段时间要发送一帧的完整图像。
PCLK是像素时钟,当HREF拉高时,每一个PCLK,D传输一个字节的数据。
二、模块划分
根据前面的相关介绍,可以将数据采集分为以下几个模块,分别编写代码:SCCB控制模块,数据发送模块,OV5640上电模块,串口发送模块。
三、SCCB控制模块代码
- module IIC_ctrl (
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire sta_flag ,//开始标志,由外部传入
- input wire [7:0] ins ,
- input wire [15:0] addr ,
- input wire [7:0] data ,
- inout wire sda ,
- output wire scl ,
- output wire sda_en ,
- output reg ready_flag );//结束标志,高电平时可以继续传输数据
-
-
- reg [6:0] current_state ;
- reg [6:0] next_state ;
- reg [3:0] bit_cnt ;//数据传输位数
- reg [1:0] clk_cnt ;//用于产生4分频时钟
- reg sda_out ;//产生sda
- reg stop_flag ;//停止信号
- reg start_flag ;//开始信号
- wire iic_clk ;
- reg write ;//写信号,有效时表示正在写
- reg sda_en_2 ;
-
- parameter IDLE=7'b0000001,
- START=7'b0000010,
- INS=7'b0000100,
- ADDR_1=7'b0001000,
- ADDR_2=7'b0010000,
- DATA_W=7'b0100000,
- STOP=7'b1000000;
-
-
- assign sda=sda_en?sda_out:1'bz;
- assign sda_en=((bit_cnt==4'd0)&&(current_state!=IDLE)&&(current_state!=START)&&(current_state!=STOP)&&(write==1'b1))?1'b0:1'b1;
- assign iic_clk=((clk_cnt>=2'd2)&&(clk_cnt<=2'd3))?1'b1:1'b0;
- assign scl=((current_state==IDLE)||(current_state==START)||(current_state==STOP&&sda_en_2==1'b1))?1'b1:iic_clk;
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- sda_en_2<=1'b1;
- else
- sda_en_2<=sda_en;
- end
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- write<=1'b0;
- else if(bit_cnt==4'd1)
- write<=1'b1;
- else if(stop_flag==1'b1)
- write<=1'b0;
- else
- write<=write;
- end
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- start_flag<=1'b0;
- else if((sda==1'b0)&&(scl==1'b1))
- start_flag<=1'b1;
- else
- start_flag<=1'b0;
- end
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- stop_flag<=1'b0;
- else if(scl==1'b1&&sda==1'b1&¤t_state==STOP)
- stop_flag<=1'b1;
- else
- stop_flag<=1'b0;
- end
-
-
-
-
-
- always@(negedge scl or negedge sys_rst_n) begin
- if(!sys_rst_n)
- bit_cnt<=4'b0;
- else if(bit_cnt==4'd8)
- bit_cnt<=4'b0;
- else if(current_state!=STOP)
- bit_cnt<=bit_cnt+1'b1;
- else
- bit_cnt<=bit_cnt;
- end
-
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- clk_cnt<=2'b0;
- else if(clk_cnt==2'b11)
- clk_cnt<=2'b0;
- else
- clk_cnt<=clk_cnt+1'b1;
- end
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- current_state<=IDLE;
- else
- current_state<=next_state;
- end
-
-
-
-
- always@(*) begin//状态机
- if(!sys_rst_n)
- next_state<=IDLE;
-
- else
- begin
- case(current_state)
-
- IDLE: begin
- if(sta_flag==1'b1)
- next_state<=START;
- else
- next_state<=IDLE;
- end
-
- START: begin
- if(start_flag==1'b1)
- next_state<=INS;
- else
- next_state<=START;
- end
-
-
- INS: begin
- if(bit_cnt==4'd0&&clk_cnt==2'd3&&write==1'b1)
- next_state<=ADDR_1;
- else
- next_state<=INS;
- end
-
- ADDR_1: begin
- if(bit_cnt==4'd0&&clk_cnt==2'd3&&write==1'b1)
- next_state<=ADDR_2;
- else
- next_state<=ADDR_1;
- end
-
-
- ADDR_2: begin
- if(bit_cnt==4'd0&&clk_cnt==2'd3&&write==1'b1)
- next_state<=DATA_W;
- else
- next_state<=ADDR_2;
- end
-
- DATA_W: begin
- if(bit_cnt==4'd0&&clk_cnt==2'd3&&write==1'b1)
- next_state<=STOP;
- else
- next_state<=DATA_W;
- end
-
- STOP: begin
- if(stop_flag==1'b1)
- next_state<=IDLE;
- else
- next_state<=STOP;
- end
-
- default:next_state<=IDLE;
-
- endcase
- end
- end
-
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- ready_flag<=1'b0;
- else if(current_state==IDLE)
- ready_flag<=1'b1;
- else
- ready_flag<=1'b0;
- end
-
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- sda_out<=1'b1;
- else
- begin
- case(current_state)
-
-
- IDLE:
- sda_out<=1'b1;
-
-
- START:
- sda_out<=1'b0;
-
-
- INS:
- begin
- case(bit_cnt)
- 4'd0:
- sda_out<=1'b0;
- 4'd1:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=ins[7];
- end
- 4'd2:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=ins[6];
- end
- 4'd3:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=ins[5];
- end
- 4'd4:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=ins[4];
- end
- 4'd5:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=ins[3];
- end
- 4'd6:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=ins[2];
- end
- 4'd7:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=ins[1];
- end
- 4'd8:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=ins[0];
- end
- default:sda_out<=1'b1;
-
- endcase
- end
-
- ADDR_1:begin
- case(bit_cnt)
- 4'd0:sda_out<=1'b0;
- 4'd1:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[15];
- end
- 4'd2:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[14];
- end
- 4'd3:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[13];
- end
- 4'd4:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[12];
- end
- 4'd5:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[11];
- end
- 4'd6:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[10];
- end
- 4'd7:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[9];
- end
- 4'd8:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[8];
- end
- default:sda_out<=1'b1;
- endcase
- end
-
-
- ADDR_2:begin
- case(bit_cnt)
- 4'd0:sda_out<=1'b0;
- 4'd1:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[7];
- end
- 4'd2:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[6];
- end
- 4'd3:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[5];
- end
- 4'd4:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[4];
- end
- 4'd5:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[3];
- end
- 4'd6:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[2];
- end
- 4'd7:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[1];
- end
- 4'd8:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=addr[0];
- end
- default:sda_out<=1'b1;
- endcase
- end
-
- DATA_W:begin
- case(bit_cnt)
- 4'd0:sda_out<=1'b0;
- 4'd1:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=data[7];
- end
- 4'd2:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=data[6];
- end
- 4'd3:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=data[5];
- end
- 4'd4:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=data[4];
- end
- 4'd5:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=data[3];
- end
- 4'd6:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=data[2];
- end
- 4'd7:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=data[1];
- end
- 4'd8:begin
- if(clk_cnt==2'd0||clk_cnt==2'd3)
- sda_out<=data[0];
- end
- default:sda_out<=1'b1;
- endcase
- end
-
- STOP:
- begin
- if(scl==1'b1)
- sda_out<=1'b1;
- else
- sda_out<=1'b0;
- end
-
-
- endcase
- end
- end
-
- endmodule
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
四、上电时序代码
- module power(
- input wire sys_clk ,
- input wire sys_rst_n ,
- output wire reset ,
- output wire pwdn ,
- output wire power_done );
-
-
- reg [13:0] cnt;
-
- parameter max_1=2460,
- max_2=3280,
- max_3=12296;
-
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- cnt<=14'b0;
- else if(cnt==max_3+8'd100)
- cnt<=cnt;
- else
- cnt<=cnt+1'b1;
- end
-
-
- assign pwdn=(cnt>=max_1)?1'b0:1'b1;
- assign reset=(cnt>=max_2)?1'b1:1'b0;
- assign power_done=(cnt>=max_3)?1'b1:1'b0;
-
-
- endmodule
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
五、串口发送模块
- module data_uart(
- input wire clk ,
- input wire pclk ,
- input wire vsync ,
- input wire [7:0] rgb_din ,
- input wire hsync ,
- input wire sys_rst_n ,
- output wire tx );
-
- parameter bote=9600,
- period=50_000_000;
-
- parameter max=period/bote;
-
-
-
-
- wire data_valid ;
- reg [12:0] cnt ;
- reg [3:0] bit_cnt ;
- wire uart_clk ;
-
-
-
- Gowin_rPLL uucc(
- .clkout(uart_clk), //output clkout
- .clkin(clk) //input clkin
- );
-
- always@(posedge uart_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- cnt<=13'b0;
- else if(cnt==max-1'b1)
- cnt<=13'b0;
- else
- cnt<=cnt+1'b1;
- end
-
-
- always@(posedge uart_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- bit_cnt<=4'b0;
- else if (bit_cnt==4'd9&&cnt==max-1'b1)
- bit_cnt<=4'b0;
- else if(cnt==max-1'b1)
- bit_cnt<=bit_cnt+1'b1;
- else
- bit_cnt<=bit_cnt;
- end
-
- assign data_valid=(bit_cnt==4'd9&&cnt==max-1'b1&&hsync==1'b1)?1'b1:1'b0;
-
- urat_tx
- #(.bote(9600),
- .period(50_000_000))
- urat_tx_inst
- (
- .clk (uart_clk) ,
- .rst (sys_rst_n) ,
- .data (rgb_din) ,
- .data_valid (data_valid) ,
- .tx (tx) );
-
-
- endmodule
-
-
-
-
-
-
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- module urat_tx
- #(parameter bote=9600,
- parameter period=50_000_000)
- (
- input wire clk,
- input wire rst,
- input wire [7:0] data,
- input wire data_valid,
- output reg tx);
-
-
- reg work_en;
- reg [15:0] baud_cnt;
- reg [3:0] bit_cnt;
- wire bit_flag;
-
- parameter max=period/bote;
-
- always@(posedge clk or negedge rst) begin
- if(!rst)
- work_en<=1'b0;
- else if((bit_cnt==4'd10)&&(baud_cnt==16'd1))
- work_en<=1'b0;
- else if(data_valid==1'b1)
- work_en<=1'b1;
- else
- work_en<=work_en;
- end
-
-
- always@(posedge clk or negedge rst) begin
- if(!rst)
- baud_cnt<=16'b0;
- else if((baud_cnt==max-1)&&(work_en==1'b1))
- baud_cnt<=16'b0;
- else if(work_en==1'b1)
- baud_cnt<=baud_cnt+1'b1;
- else
- baud_cnt<=16'b0;
- end
-
- assign bit_falg=((baud_cnt==16'b0)&&(work_en==1'b1))?1'b1:1'b0;
-
- always@(posedge clk or negedge rst) begin
- if(!rst)
- bit_cnt<=4'b0;
- else if((bit_cnt==4'd10)&&(baud_cnt==16'd1))
- bit_cnt<=4'b0;
- else if(bit_falg==1'b1)
- bit_cnt<=bit_cnt+1'b1;
- else
- bit_cnt<=bit_cnt;
- end
-
-
- always@(*) begin
- if(!rst)
- tx<=1'b1;
- else begin
- case(bit_cnt)
- 4'd0:tx<=1'b1;
- 4'd1:tx<=1'b0;
- 4'd2:tx<=data[0];
- 4'd3:tx<=data[1];
- 4'd4:tx<=data[2];
- 4'd5:tx<=data[3];
- 4'd6:tx<=data[4];
- 4'd7:tx<=data[5];
- 4'd8:tx<=data[6];
- 4'd9:tx<=data[7];
- default:tx<=1'b1;
- endcase
- end
- end
-
- endmodule
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
六、数据发送模块
- module IIC_start(
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire ready_flag ,
- output reg sta_flag ,
- output wire [7:0] ins ,
- output wire [15:0] addr ,
- output wire [7:0] data );
-
-
- always@(posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n)
- sta_flag<=1'b0;
- else if(ready_flag==1'b1)
- sta_flag<=1'b1;
- else
- sta_flag<=1'b0;
- end
-
-
- reg [9:0] cnt ;
- reg [31:0] lut_data ;
-
- assign ins=lut_data[31:24];
- assign addr=lut_data[23:8];
- assign data=lut_data[7:0];
-
-
- always@(posedge sta_flag or negedge sys_rst_n) begin
- if(!sys_rst_n)
- cnt<=10'b0;
- else if(cnt==10'd256)
- cnt<=cnt;
- else
- cnt<=cnt+1'b1;
- end
-
-
- always@(*) begin
- case(cnt)
- 10'd 1: lut_data <= {8'h78 , 24'h310311};// system clock from pad, bit[1]
- 10'd 2: lut_data <= {8'h78 , 24'h300882};// software reset, bit[7]// delay 5ms
- 10'd 3: lut_data <= {8'h78 , 24'h300842};// software power down, bit[6]
- 10'd 4: lut_data <= {8'h78 , 24'h310303};// system clock from PLL, bit[1]
- 10'd 5: lut_data <= {8'h78 , 24'h3017ff};// FREX, Vsync, HREF, PCLK, D[9:6] output enable
- 10'd 6: lut_data <= {8'h78 , 24'h3018ff};// D[5:0], GPIO[1:0] output enable
- 10'd 7: lut_data <= {8'h78 , 24'h30341A};// MIPI 10-bit
- 10'd 8: lut_data <= {8'h78 , 24'h303713};// PLL root divider, bit[4], PLL pre-divider, bit[3:0]
- 10'd 9: lut_data <= {8'h78 , 24'h310801};// PCLK root divider, bit[5:4], SCLK2x root divider, bit[3:2] // SCLK root divider, bit[1:0]
- 10'd 10: lut_data <= {8'h78 , 24'h363036};
- 10'd 11: lut_data <= {8'h78 , 24'h36310e};
- 10'd 12: lut_data <= {8'h78 , 24'h3632e2};
- 10'd 13: lut_data <= {8'h78 , 24'h363312};
- 10'd 14: lut_data <= {8'h78 , 24'h3621e0};
- 10'd 15: lut_data <= {8'h78 , 24'h3704a0};
- 10'd 16: lut_data <= {8'h78 , 24'h37035a};
- 10'd 17: lut_data <= {8'h78 , 24'h371578};
- 10'd 18: lut_data <= {8'h78 , 24'h371701};
- 10'd 19: lut_data <= {8'h78 , 24'h370b60};
- 10'd 20: lut_data <= {8'h78 , 24'h37051a};
- 10'd 21: lut_data <= {8'h78 , 24'h390502};
- 10'd 22: lut_data <= {8'h78 , 24'h390610};
- 10'd 23: lut_data <= {8'h78 , 24'h39010a};
- 10'd 24: lut_data <= {8'h78 , 24'h373112};
- 10'd 25: lut_data <= {8'h78 , 24'h360008};// VCM control
- 10'd 26: lut_data <= {8'h78 , 24'h360133};// VCM control
- 10'd 27: lut_data <= {8'h78 , 24'h302d60};// system control
- 10'd 28: lut_data <= {8'h78 , 24'h362052};
- 10'd 29: lut_data <= {8'h78 , 24'h371b20};
- 10'd 30: lut_data <= {8'h78 , 24'h471c50};
- 10'd 31: lut_data <= {8'h78 , 24'h3a1343};// pre-gain = 1.047x
- 10'd 32: lut_data <= {8'h78 , 24'h3a1800};// gain ceiling
- 10'd 33: lut_data <= {8'h78 , 24'h3a19f8};// gain ceiling = 15.5x
- 10'd 34: lut_data <= {8'h78 , 24'h363513};
- 10'd 35: lut_data <= {8'h78 , 24'h363603};
- 10'd 36: lut_data <= {8'h78 , 24'h363440};
- 10'd 37: lut_data <= {8'h78 , 24'h362201}; // 50/60Hz detection 50/60Hz
- 10'd 38: lut_data <= {8'h78 , 24'h3c0134};// Band auto, bit[7]
- 10'd 39: lut_data <= {8'h78 , 24'h3c0428};// threshold low sum
- 10'd 40: lut_data <= {8'h78 , 24'h3c0598};// threshold high sum
- 10'd 41: lut_data <= {8'h78 , 24'h3c0600};// light meter 1 threshold[15:8]
- 10'd 42: lut_data <= {8'h78 , 24'h3c0708};// light meter 1 threshold[7:0]
- 10'd 43: lut_data <= {8'h78 , 24'h3c0800};// light meter 2 threshold[15:8]
- 10'd 44: lut_data <= {8'h78 , 24'h3c091c};// light meter 2 threshold[7:0]
- 10'd 45: lut_data <= {8'h78 , 24'h3c0a9c};// sample number[15:8]
- 10'd 46: lut_data <= {8'h78 , 24'h3c0b40};// sample number[7:0]
- 10'd 47: lut_data <= {8'h78 , 24'h381000};// Timing Hoffset[11:8]
- 10'd 48: lut_data <= {8'h78 , 24'h381110};// Timing Hoffset[7:0]
- 10'd 49: lut_data <= {8'h78 , 24'h381200};// Timing Voffset[10:8]
- 10'd 50: lut_data <= {8'h78 , 24'h370864};
- 10'd 51: lut_data <= {8'h78 , 24'h400102};// BLC start from line 2
- 10'd 52: lut_data <= {8'h78 , 24'h40051a};// BLC always update
- 10'd 53: lut_data <= {8'h78 , 24'h300000};// enable blocks
- 10'd 54: lut_data <= {8'h78 , 24'h3004ff};// enable clocks
- 10'd 55: lut_data <= {8'h78 , 24'h300e58};// MIPI power down, DVP enable
- 10'd 56: lut_data <= {8'h78 , 24'h302e00};
- 10'd 57: lut_data <= {8'h78 , 24'h430060};// RGB565
- 10'd 58: lut_data <= {8'h78 , 24'h501f01};// ISP RGB
- 10'd 59: lut_data <= {8'h78 , 24'h440e00};
- 10'd 60: lut_data <= {8'h78 , 24'h5000a7}; // Lenc on, raw gamma on, BPC on, WPC on, CIP on
- 10'd 61: lut_data <= {8'h78 , 24'h3a0f30};// stable range in high
- 10'd 62: lut_data <= {8'h78 , 24'h3a1028};// stable range in low
- 10'd 63: lut_data <= {8'h78 , 24'h3a1b30};// stable range out high
- 10'd 64: lut_data <= {8'h78 , 24'h3a1e26};// stable range out low
- 10'd 65: lut_data <= {8'h78 , 24'h3a1160};// fast zone high
- 10'd 66: lut_data <= {8'h78 , 24'h3a1f14};// fast zone low// Lens correction for
- 10'd 67: lut_data <= {8'h78 , 24'h580023};
- 10'd 68: lut_data <= {8'h78 , 24'h580114};
- 10'd 69: lut_data <= {8'h78 , 24'h58020f};
- 10'd 70: lut_data <= {8'h78 , 24'h58030f};
- 10'd 71: lut_data <= {8'h78 , 24'h580412};
- 10'd 72: lut_data <= {8'h78 , 24'h580526};
- 10'd 73: lut_data <= {8'h78 , 24'h58060c};
- 10'd 74: lut_data <= {8'h78 , 24'h580708};
- 10'd 75: lut_data <= {8'h78 , 24'h580805};
- 10'd 76: lut_data <= {8'h78 , 24'h580905};
- 10'd 77: lut_data <= {8'h78 , 24'h580a08};
- 10'd 78: lut_data <= {8'h78 , 24'h580b0d};
- 10'd 79: lut_data <= {8'h78 , 24'h580c08};
- 10'd 80: lut_data <= {8'h78 , 24'h580d03};
- 10'd 81: lut_data <= {8'h78 , 24'h580e00};
- 10'd 82: lut_data <= {8'h78 , 24'h580f00};
- 10'd 83: lut_data <= {8'h78 , 24'h581003};
- 10'd 84: lut_data <= {8'h78 , 24'h581109};
- 10'd 85: lut_data <= {8'h78 , 24'h581207};
- 10'd 86: lut_data <= {8'h78 , 24'h581303};
- 10'd 87: lut_data <= {8'h78 , 24'h581400};
- 10'd 88: lut_data <= {8'h78 , 24'h581501};
- 10'd 89: lut_data <= {8'h78 , 24'h581603};
- 10'd 90: lut_data <= {8'h78 , 24'h581708};
- 10'd 91: lut_data <= {8'h78 , 24'h58180d};
- 10'd 92: lut_data <= {8'h78 , 24'h581908};
- 10'd 93: lut_data <= {8'h78 , 24'h581a05};
- 10'd 94: lut_data <= {8'h78 , 24'h581b06};
- 10'd 95: lut_data <= {8'h78 , 24'h581c08};
- 10'd 96: lut_data <= {8'h78 , 24'h581d0e};
- 10'd 97: lut_data <= {8'h78 , 24'h581e29};
- 10'd 98: lut_data <= {8'h78 , 24'h581f17};
- 10'd 99: lut_data <= {8'h78 , 24'h582011};
- 10'd100: lut_data <= {8'h78 , 24'h582111};
- 10'd101: lut_data <= {8'h78 , 24'h582215};
- 10'd102: lut_data <= {8'h78 , 24'h582328};
- 10'd103: lut_data <= {8'h78 , 24'h582446};
- 10'd104: lut_data <= {8'h78 , 24'h582526};
- 10'd105: lut_data <= {8'h78 , 24'h582608};
- 10'd106: lut_data <= {8'h78 , 24'h582726};
- 10'd107: lut_data <= {8'h78 , 24'h582864};
- 10'd108: lut_data <= {8'h78 , 24'h582926};
- 10'd109: lut_data <= {8'h78 , 24'h582a24};
- 10'd110: lut_data <= {8'h78 , 24'h582b22};
- 10'd111: lut_data <= {8'h78 , 24'h582c24};
- 10'd112: lut_data <= {8'h78 , 24'h582d24};
- 10'd113: lut_data <= {8'h78 , 24'h582e06};
- 10'd114: lut_data <= {8'h78 , 24'h582f22};
- 10'd115: lut_data <= {8'h78 , 24'h583040};
- 10'd116: lut_data <= {8'h78 , 24'h583142};
- 10'd117: lut_data <= {8'h78 , 24'h583224};
- 10'd118: lut_data <= {8'h78 , 24'h583326};
- 10'd119: lut_data <= {8'h78 , 24'h583424};
- 10'd120: lut_data <= {8'h78 , 24'h583522};
- 10'd121: lut_data <= {8'h78 , 24'h583622};
- 10'd122: lut_data <= {8'h78 , 24'h583726};
- 10'd123: lut_data <= {8'h78 , 24'h583844};
- 10'd124: lut_data <= {8'h78 , 24'h583924};
- 10'd125: lut_data <= {8'h78 , 24'h583a26};
- 10'd126: lut_data <= {8'h78 , 24'h583b28};
- 10'd127: lut_data <= {8'h78 , 24'h583c42};
- 10'd128: lut_data <= {8'h78 , 24'h583dce};// lenc BR offset
- 10'd129: lut_data <= {8'h78 , 24'h5180ff};// AWB B block
- 10'd130: lut_data <= {8'h78 , 24'h5181f2};// AWB control
- 10'd131: lut_data <= {8'h78 , 24'h518200};// [7:4] max local counter, [3:0] max fast counter
- 10'd132: lut_data <= {8'h78 , 24'h518314};// AWB advanced
- 10'd133: lut_data <= {8'h78 , 24'h518425};
- 10'd134: lut_data <= {8'h78 , 24'h518524};
- 10'd135: lut_data <= {8'h78 , 24'h518609};
- 10'd136: lut_data <= {8'h78 , 24'h518709};
- 10'd137: lut_data <= {8'h78 , 24'h518809};
- 10'd138: lut_data <= {8'h78 , 24'h518975};
- 10'd139: lut_data <= {8'h78 , 24'h518a54};
- 10'd140: lut_data <= {8'h78 , 24'h518be0};
- 10'd141: lut_data <= {8'h78 , 24'h518cb2};
- 10'd142: lut_data <= {8'h78 , 24'h518d42};
- 10'd143: lut_data <= {8'h78 , 24'h518e3d};
- 10'd144: lut_data <= {8'h78 , 24'h518f56};
- 10'd145: lut_data <= {8'h78 , 24'h519046};
- 10'd146: lut_data <= {8'h78 , 24'h5191f8};// AWB top limit
- 10'd147: lut_data <= {8'h78 , 24'h519204};// AWB bottom limit
- 10'd148: lut_data <= {8'h78 , 24'h519370};// red limit
- 10'd149: lut_data <= {8'h78 , 24'h5194f0};// green limit
- 10'd150: lut_data <= {8'h78 , 24'h5195f0};// blue limit
- 10'd151: lut_data <= {8'h78 , 24'h519603};// AWB control
- 10'd152: lut_data <= {8'h78 , 24'h519701};// local limit
- 10'd153: lut_data <= {8'h78 , 24'h519804};
- 10'd154: lut_data <= {8'h78 , 24'h519912};
- 10'd155: lut_data <= {8'h78 , 24'h519a04};
- 10'd156: lut_data <= {8'h78 , 24'h519b00};
- 10'd157: lut_data <= {8'h78 , 24'h519c06};
- 10'd158: lut_data <= {8'h78 , 24'h519d82};
- 10'd159: lut_data <= {8'h78 , 24'h519e38};// AWB control
- 10'd160: lut_data <= {8'h78 , 24'h548001};// Gamma bias plus on, bit[0]
- 10'd161: lut_data <= {8'h78 , 24'h548108};
- 10'd162: lut_data <= {8'h78 , 24'h548214};
- 10'd163: lut_data <= {8'h78 , 24'h548328};
- 10'd164: lut_data <= {8'h78 , 24'h548451};
- 10'd165: lut_data <= {8'h78 , 24'h548565};
- 10'd166: lut_data <= {8'h78 , 24'h548671};
- 10'd167: lut_data <= {8'h78 , 24'h54877d};
- 10'd168: lut_data <= {8'h78 , 24'h548887};
- 10'd169: lut_data <= {8'h78 , 24'h548991};
- 10'd170: lut_data <= {8'h78 , 24'h548a9a};
- 10'd171: lut_data <= {8'h78 , 24'h548baa};
- 10'd172: lut_data <= {8'h78 , 24'h548cb8};
- 10'd173: lut_data <= {8'h78 , 24'h548dcd};
- 10'd174: lut_data <= {8'h78 , 24'h548edd};
- 10'd175: lut_data <= {8'h78 , 24'h548fea};
- 10'd176: lut_data <= {8'h78 , 24'h54901d};// color matrix
- 10'd177: lut_data <= {8'h78 , 24'h53811e};// CMX1 for Y
- 10'd178: lut_data <= {8'h78 , 24'h53825b};// CMX2 for Y
- 10'd179: lut_data <= {8'h78 , 24'h538308};// CMX3 for Y
- 10'd180: lut_data <= {8'h78 , 24'h53840a};// CMX4 for U
- 10'd181: lut_data <= {8'h78 , 24'h53857e};// CMX5 for U
- 10'd182: lut_data <= {8'h78 , 24'h538688};// CMX6 for U
- 10'd183: lut_data <= {8'h78 , 24'h53877c};// CMX7 for V
- 10'd184: lut_data <= {8'h78 , 24'h53886c};// CMX8 for V
- 10'd185: lut_data <= {8'h78 , 24'h538910};// CMX9 for V
- 10'd186: lut_data <= {8'h78 , 24'h538a01};// sign[9]
- 10'd187: lut_data <= {8'h78 , 24'h538b98}; // sign[8:1] // UV adjust
- 10'd188: lut_data <= {8'h78 , 24'h558006};// saturation on, bit[1]
- 10'd189: lut_data <= {8'h78 , 24'h558340};
- 10'd190: lut_data <= {8'h78 , 24'h558410};
- 10'd191: lut_data <= {8'h78 , 24'h558910};
- 10'd192: lut_data <= {8'h78 , 24'h558a00};
- 10'd193: lut_data <= {8'h78 , 24'h558bf8};
- 10'd194: lut_data <= {8'h78 , 24'h501d40};// enable manual offset of contrast
- 10'd195: lut_data <= {8'h78 , 24'h530008};// CIP sharpen MT threshold 1
- 10'd196: lut_data <= {8'h78 , 24'h530130};// CIP sharpen MT threshold 2
- 10'd197: lut_data <= {8'h78 , 24'h530210};// CIP sharpen MT offset 1
- 10'd198: lut_data <= {8'h78 , 24'h530300};// CIP sharpen MT offset 2
- 10'd199: lut_data <= {8'h78 , 24'h530408};// CIP DNS threshold 1
- 10'd200: lut_data <= {8'h78 , 24'h530530};// CIP DNS threshold 2
- 10'd201: lut_data <= {8'h78 , 24'h530608};// CIP DNS offset 1
- 10'd202: lut_data <= {8'h78 , 24'h530716};// CIP DNS offset 2
- 10'd203: lut_data <= {8'h78 , 24'h530908};// CIP sharpen TH threshold 1
- 10'd204: lut_data <= {8'h78 , 24'h530a30};// CIP sharpen TH threshold 2
- 10'd205: lut_data <= {8'h78 , 24'h530b04};// CIP sharpen TH offset 1
- 10'd206: lut_data <= {8'h78 , 24'h530c06};// CIP sharpen TH offset 2
- 10'd207: lut_data <= {8'h78 , 24'h502500};
- 10'd208: lut_data <= {8'h78 , 24'h300802}; // wake up from standby, bit[6]
- 10'd209: lut_data <= {8'h78 , 24'h303511};// PLL
- 10'd210: lut_data <= {8'h78 , 24'h30368C};// PLL 46-30fps 8c-60fps
- 10'd211: lut_data <= {8'h78 , 24'h3c0708};// light meter 1 threshold [7:0]
- 10'd212: lut_data <= {8'h78 , 24'h382047};// Sensor flip off, ISP flip on
- 10'd213: lut_data <= {8'h78 , 24'h382101};// Sensor mirror on, ISP mirror on, H binning on
- 10'd214: lut_data <= {8'h78 , 24'h381431};// X INC
- 10'd215: lut_data <= {8'h78 , 24'h381531};// Y INC
- 10'd216: lut_data <= {8'h78 , 24'h380000};// HS: X address start high byte
- 10'd217: lut_data <= {8'h78 , 24'h380100};// HS: X address start low byte
- 10'd218: lut_data <= {8'h78 , 24'h380200};// VS: Y address start high byte
- 10'd219: lut_data <= {8'h78 , 24'h380304};// VS: Y address start high byte
- 10'd220: lut_data <= {8'h78 , 24'h38040a};// HW (HE)
- 10'd221: lut_data <= {8'h78 , 24'h38053f};// HW (HE)
- 10'd222: lut_data <= {8'h78 , 24'h380607};// VH (VE)
- 10'd223: lut_data <= {8'h78 , 24'h38079b};// VH (VE)
- 10'd224: lut_data <= {8'h78 , 24'h380803};// DVPHO //800
- 10'd225: lut_data <= {8'h78 , 24'h380920};// DVPHO
- 10'd226: lut_data <= {8'h78 , 24'h380a01};// DVPVO //480
- 10'd227: lut_data <= {8'h78 , 24'h380be0};// DVPVO
- 10'd228: lut_data <= {8'h78 , 24'h380c07};// HTS //Total horizontal size
- 10'd229: lut_data <= {8'h78 , 24'h380d68};// HTS
- 10'd230: lut_data <= {8'h78 , 24'h380e03};// VTS //total vertical size
- 10'd231: lut_data <= {8'h78 , 24'h380fd8};// VTS
- 10'd232: lut_data <= {8'h78 , 24'h381306};// Timing Voffset
- 10'd233: lut_data <= {8'h78 , 24'h361800};
- 10'd234: lut_data <= {8'h78 , 24'h361229};
- 10'd235: lut_data <= {8'h78 , 24'h370952};
- 10'd236: lut_data <= {8'h78 , 24'h370c03};
- 10'd237: lut_data <= {8'h78 , 24'h3a0217};// 60Hz max exposure, night mode 5fps
- 10'd238: lut_data <= {8'h78 , 24'h3a0310};// 60Hz max exposure // banding filters are calculated automatically in camera driver
- 10'd239: lut_data <= {8'h78 , 24'h3a1417};// 50Hz max exposure, night mode 5fps
- 10'd240: lut_data <= {8'h78 , 24'h3a1510};// 50Hz max exposure
- 10'd241: lut_data <= {8'h78 , 24'h400402};// BLC 2 lines
- 10'd242: lut_data <= {8'h78 , 24'h30021c};// reset JFIFO, SFIFO, JPEG
- 10'd243: lut_data <= {8'h78 , 24'h3006c3};// disable clock of JPEG2x, JPEG
- 10'd244: lut_data <= {8'h78 , 24'h471303};// JPEG mode 3
- 10'd245: lut_data <= {8'h78 , 24'h440704};// Quantization scale
- 10'd246: lut_data <= {8'h78 , 24'h460b35};
- 10'd247: lut_data <= {8'h78 , 24'h460c22};
- 10'd248: lut_data <= {8'h78 , 24'h483722}; // DVP CLK divider
- 10'd249: lut_data <= {8'h78 , 24'h382402}; // DVP CLK divider
- 10'd250: lut_data <= {8'h78 , 24'h5001a3}; // SDE on, scale on, UV average off, color matrix on, AWB on
- 10'd251: lut_data <= {8'h78 , 24'h350300}; // AEC/AGC on
- 10'd252: lut_data <= {8'h78 , 24'h301602}; //Strobe output enable
- 10'd253: lut_data <= {8'h78 , 24'h3b070a}; //FREX strobe mode1
- 10'd254: lut_data <= {8'h78 , 24'h3b0083}; //STROBE CTRL: strobe request ON, Strobe mode: LED3
- 10'd255: lut_data <= {8'h78 , 24'h3b0000}; //STROBE CTRL: strobe request OFF
- 10'd256: lut_data <= {8'hff , 24'hffffff};
- default:lut_data <= {8'h00,16'h0000,8'h00};
- endcase
- end
-
- endmodule
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
七、SCCB顶层文件
- module IIC_top(
- input wire clk ,
- input wire sys_rst_n ,
- input wire rst_n ,
- inout wire sda ,
- output wire sda_en ,
- output wire sys_clk ,
- output wire xclk ,
- output wire scl );
-
- reg [5:0] cnt_rs ;
- wire [7:0] ins ;
- wire [15:0] addr ;
- wire [7:0] data ;
- wire sta_flag ;
- wire ready_flag ;
- wire clk_1 ;
- reg [5:0] cnt_yu ;
-
- xclk_pll your_instance_name(
- .clkout(xclk), //output clkout
- .clkin(clk) //input clkin
- );
-
-
-
-
- icck_pll iic_inst(
- .clkout(clk_1), //output clkout
- .clkin(clk) //input clkin
- );
-
-
- assign sys_clk=((cnt_yu>=6'd0)&&(cnt_yu<=6'd25))?1'b1:1'b0;
-
-
- always@(posedge clk_1 or negedge rst_n) begin
- if(!rst_n)
- cnt_yu<=6'b0;
- else if(cnt_yu==6'd51)
- cnt_yu<=6'b0;
- else
- cnt_yu<=cnt_yu+1'b1;
- end
-
-
- IIC_start IIC_start_inst(
- .sys_clk (sys_clk ) ,
- .sys_rst_n (sys_rst_n ) ,
- .ready_flag (ready_flag ) ,
- .sta_flag (sta_flag ) ,
- .ins (ins ) ,
- .addr (addr ) ,
- .data (data ) );
-
-
- IIC_ctrl IIC_ctrl_inst (
- .sys_clk (sys_clk ) ,
- .sys_rst_n (sys_rst_n ) ,
- .sta_flag (sta_flag ) ,//开始标志,由外部传入
- .ins (ins ) ,
- .addr (addr ) ,
- .data (data ) ,
- .sda (sda ) ,
- .scl (scl ) ,
- .sda_en (sda_en ) ,
- .ready_flag (ready_flag) );
-
-
- endmodule
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
八、实验顶层代码
- module IIC_data_uart (
- input wire clk ,
- input wire sys_rst_n ,
- input wire rst_n ,
- input wire pclk ,
- input wire hsync ,
- input wire [7:0] rgb_din ,
- input wire vsync ,
- output wire scl ,
- inout wire sda ,
- output wire xclk ,
- output wire pwdn ,
- output wire reset ,
- output wire sda_en ,
- output wire tx );
-
-
- data_uart data_uart_inst(
- .clk (clk ) ,
- .pclk (pclk ) ,
- .vsync (vsync ) ,
- .rgb_din (rgb_din ) ,
- .hsync (hsync ) ,
- .sys_rst_n (sys_rst_n) ,
- .tx (tx ) );
-
-
- wire power_done ;
-
-
- IIC_top IIC_top_inst(
- .clk (clk ) ,
- .sys_rst_n (power_done ) ,
- .sda (sda ) ,
- .sda_en (sda_en ) ,
- .sys_clk (sys_clk ) ,
- .xclk (xclk ) ,
- .rst_n (rst_n ) ,
- .scl (scl ) );
-
-
- power power_inst(
- . sys_clk (sys_clk ) ,
- . sys_rst_n (sys_rst_n ) ,
- . reset (reset ) ,
- . pwdn (pwdn ) ,
- . power_done (power_done ) );
-
-
- endmodule
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
九、一些话
由于SCCB协议和IIC协议几乎一摸一样,这里的模块命名都是用的IIC。数据手册这里贴不上来,兄弟们如果有需求的话评论区指出来,我到时候甩个网盘链接上去。OV5640输出数据类似于VGA和HDMI的时序,接下来会继续更新VGA和HDMI的相关时序分析和代码。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。