当前位置:   article > 正文

基于FPGA的图像数据采集(二)_fpga图像采集

fpga图像采集

一、数据采集时序

  上一篇我们讨论了OV5640的上电时序,下面给出数据采集的时序。

b2231202388a4f34a2b19836f839f8be.png

e6758c4de5674159aacadfc10beb3ec4.png

   上一篇已经提到了VSYNC是场同步信号,每一次拉高就表示一帧图像的开始。两次拉高中间的时间对应上图中的(1),这段时间要发送一帧的完整图像。

  PCLK是像素时钟,当HREF拉高时,每一个PCLK,D传输一个字节的数据。

二、模块划分

  根据前面的相关介绍,可以将数据采集分为以下几个模块,分别编写代码:SCCB控制模块,数据发送模块,OV5640上电模块,串口发送模块。

三、SCCB控制模块代码

  1. module IIC_ctrl (
  2. input wire sys_clk ,
  3. input wire sys_rst_n ,
  4. input wire sta_flag ,//开始标志,由外部传入
  5. input wire [7:0] ins ,
  6. input wire [15:0] addr ,
  7. input wire [7:0] data ,
  8. inout wire sda ,
  9. output wire scl ,
  10. output wire sda_en ,
  11. output reg ready_flag );//结束标志,高电平时可以继续传输数据
  12. reg [6:0] current_state ;
  13. reg [6:0] next_state ;
  14. reg [3:0] bit_cnt ;//数据传输位数
  15. reg [1:0] clk_cnt ;//用于产生4分频时钟
  16. reg sda_out ;//产生sda
  17. reg stop_flag ;//停止信号
  18. reg start_flag ;//开始信号
  19. wire iic_clk ;
  20. reg write ;//写信号,有效时表示正在写
  21. reg sda_en_2 ;
  22. parameter IDLE=7'b0000001,
  23. START=7'b0000010,
  24. INS=7'b0000100,
  25. ADDR_1=7'b0001000,
  26. ADDR_2=7'b0010000,
  27. DATA_W=7'b0100000,
  28. STOP=7'b1000000;
  29. assign sda=sda_en?sda_out:1'bz;
  30. assign sda_en=((bit_cnt==4'd0)&&(current_state!=IDLE)&&(current_state!=START)&&(current_state!=STOP)&&(write==1'b1))?1'b0:1'b1;
  31. assign iic_clk=((clk_cnt>=2'd2)&&(clk_cnt<=2'd3))?1'b1:1'b0;
  32. assign scl=((current_state==IDLE)||(current_state==START)||(current_state==STOP&&sda_en_2==1'b1))?1'b1:iic_clk;
  33. always@(posedge sys_clk or negedge sys_rst_n) begin
  34. if(!sys_rst_n)
  35. sda_en_2<=1'b1;
  36. else
  37. sda_en_2<=sda_en;
  38. end
  39. always@(posedge sys_clk or negedge sys_rst_n) begin
  40. if(!sys_rst_n)
  41. write<=1'b0;
  42. else if(bit_cnt==4'd1)
  43. write<=1'b1;
  44. else if(stop_flag==1'b1)
  45. write<=1'b0;
  46. else
  47. write<=write;
  48. end
  49. always@(posedge sys_clk or negedge sys_rst_n) begin
  50. if(!sys_rst_n)
  51. start_flag<=1'b0;
  52. else if((sda==1'b0)&&(scl==1'b1))
  53. start_flag<=1'b1;
  54. else
  55. start_flag<=1'b0;
  56. end
  57. always@(posedge sys_clk or negedge sys_rst_n) begin
  58. if(!sys_rst_n)
  59. stop_flag<=1'b0;
  60. else if(scl==1'b1&&sda==1'b1&&current_state==STOP)
  61. stop_flag<=1'b1;
  62. else
  63. stop_flag<=1'b0;
  64. end
  65. always@(negedge scl or negedge sys_rst_n) begin
  66. if(!sys_rst_n)
  67. bit_cnt<=4'b0;
  68. else if(bit_cnt==4'd8)
  69. bit_cnt<=4'b0;
  70. else if(current_state!=STOP)
  71. bit_cnt<=bit_cnt+1'b1;
  72. else
  73. bit_cnt<=bit_cnt;
  74. end
  75. always@(posedge sys_clk or negedge sys_rst_n) begin
  76. if(!sys_rst_n)
  77. clk_cnt<=2'b0;
  78. else if(clk_cnt==2'b11)
  79. clk_cnt<=2'b0;
  80. else
  81. clk_cnt<=clk_cnt+1'b1;
  82. end
  83. always@(posedge sys_clk or negedge sys_rst_n) begin
  84. if(!sys_rst_n)
  85. current_state<=IDLE;
  86. else
  87. current_state<=next_state;
  88. end
  89. always@(*) begin//状态机
  90. if(!sys_rst_n)
  91. next_state<=IDLE;
  92. else
  93. begin
  94. case(current_state)
  95. IDLE: begin
  96. if(sta_flag==1'b1)
  97. next_state<=START;
  98. else
  99. next_state<=IDLE;
  100. end
  101. START: begin
  102. if(start_flag==1'b1)
  103. next_state<=INS;
  104. else
  105. next_state<=START;
  106. end
  107. INS: begin
  108. if(bit_cnt==4'd0&&clk_cnt==2'd3&&write==1'b1)
  109. next_state<=ADDR_1;
  110. else
  111. next_state<=INS;
  112. end
  113. ADDR_1: begin
  114. if(bit_cnt==4'd0&&clk_cnt==2'd3&&write==1'b1)
  115. next_state<=ADDR_2;
  116. else
  117. next_state<=ADDR_1;
  118. end
  119. ADDR_2: begin
  120. if(bit_cnt==4'd0&&clk_cnt==2'd3&&write==1'b1)
  121. next_state<=DATA_W;
  122. else
  123. next_state<=ADDR_2;
  124. end
  125. DATA_W: begin
  126. if(bit_cnt==4'd0&&clk_cnt==2'd3&&write==1'b1)
  127. next_state<=STOP;
  128. else
  129. next_state<=DATA_W;
  130. end
  131. STOP: begin
  132. if(stop_flag==1'b1)
  133. next_state<=IDLE;
  134. else
  135. next_state<=STOP;
  136. end
  137. default:next_state<=IDLE;
  138. endcase
  139. end
  140. end
  141. always@(posedge sys_clk or negedge sys_rst_n) begin
  142. if(!sys_rst_n)
  143. ready_flag<=1'b0;
  144. else if(current_state==IDLE)
  145. ready_flag<=1'b1;
  146. else
  147. ready_flag<=1'b0;
  148. end
  149. always@(posedge sys_clk or negedge sys_rst_n) begin
  150. if(!sys_rst_n)
  151. sda_out<=1'b1;
  152. else
  153. begin
  154. case(current_state)
  155. IDLE:
  156. sda_out<=1'b1;
  157. START:
  158. sda_out<=1'b0;
  159. INS:
  160. begin
  161. case(bit_cnt)
  162. 4'd0:
  163. sda_out<=1'b0;
  164. 4'd1:begin
  165. if(clk_cnt==2'd0||clk_cnt==2'd3)
  166. sda_out<=ins[7];
  167. end
  168. 4'd2:begin
  169. if(clk_cnt==2'd0||clk_cnt==2'd3)
  170. sda_out<=ins[6];
  171. end
  172. 4'd3:begin
  173. if(clk_cnt==2'd0||clk_cnt==2'd3)
  174. sda_out<=ins[5];
  175. end
  176. 4'd4:begin
  177. if(clk_cnt==2'd0||clk_cnt==2'd3)
  178. sda_out<=ins[4];
  179. end
  180. 4'd5:begin
  181. if(clk_cnt==2'd0||clk_cnt==2'd3)
  182. sda_out<=ins[3];
  183. end
  184. 4'd6:begin
  185. if(clk_cnt==2'd0||clk_cnt==2'd3)
  186. sda_out<=ins[2];
  187. end
  188. 4'd7:begin
  189. if(clk_cnt==2'd0||clk_cnt==2'd3)
  190. sda_out<=ins[1];
  191. end
  192. 4'd8:begin
  193. if(clk_cnt==2'd0||clk_cnt==2'd3)
  194. sda_out<=ins[0];
  195. end
  196. default:sda_out<=1'b1;
  197. endcase
  198. end
  199. ADDR_1:begin
  200. case(bit_cnt)
  201. 4'd0:sda_out<=1'b0;
  202. 4'd1:begin
  203. if(clk_cnt==2'd0||clk_cnt==2'd3)
  204. sda_out<=addr[15];
  205. end
  206. 4'd2:begin
  207. if(clk_cnt==2'd0||clk_cnt==2'd3)
  208. sda_out<=addr[14];
  209. end
  210. 4'd3:begin
  211. if(clk_cnt==2'd0||clk_cnt==2'd3)
  212. sda_out<=addr[13];
  213. end
  214. 4'd4:begin
  215. if(clk_cnt==2'd0||clk_cnt==2'd3)
  216. sda_out<=addr[12];
  217. end
  218. 4'd5:begin
  219. if(clk_cnt==2'd0||clk_cnt==2'd3)
  220. sda_out<=addr[11];
  221. end
  222. 4'd6:begin
  223. if(clk_cnt==2'd0||clk_cnt==2'd3)
  224. sda_out<=addr[10];
  225. end
  226. 4'd7:begin
  227. if(clk_cnt==2'd0||clk_cnt==2'd3)
  228. sda_out<=addr[9];
  229. end
  230. 4'd8:begin
  231. if(clk_cnt==2'd0||clk_cnt==2'd3)
  232. sda_out<=addr[8];
  233. end
  234. default:sda_out<=1'b1;
  235. endcase
  236. end
  237. ADDR_2:begin
  238. case(bit_cnt)
  239. 4'd0:sda_out<=1'b0;
  240. 4'd1:begin
  241. if(clk_cnt==2'd0||clk_cnt==2'd3)
  242. sda_out<=addr[7];
  243. end
  244. 4'd2:begin
  245. if(clk_cnt==2'd0||clk_cnt==2'd3)
  246. sda_out<=addr[6];
  247. end
  248. 4'd3:begin
  249. if(clk_cnt==2'd0||clk_cnt==2'd3)
  250. sda_out<=addr[5];
  251. end
  252. 4'd4:begin
  253. if(clk_cnt==2'd0||clk_cnt==2'd3)
  254. sda_out<=addr[4];
  255. end
  256. 4'd5:begin
  257. if(clk_cnt==2'd0||clk_cnt==2'd3)
  258. sda_out<=addr[3];
  259. end
  260. 4'd6:begin
  261. if(clk_cnt==2'd0||clk_cnt==2'd3)
  262. sda_out<=addr[2];
  263. end
  264. 4'd7:begin
  265. if(clk_cnt==2'd0||clk_cnt==2'd3)
  266. sda_out<=addr[1];
  267. end
  268. 4'd8:begin
  269. if(clk_cnt==2'd0||clk_cnt==2'd3)
  270. sda_out<=addr[0];
  271. end
  272. default:sda_out<=1'b1;
  273. endcase
  274. end
  275. DATA_W:begin
  276. case(bit_cnt)
  277. 4'd0:sda_out<=1'b0;
  278. 4'd1:begin
  279. if(clk_cnt==2'd0||clk_cnt==2'd3)
  280. sda_out<=data[7];
  281. end
  282. 4'd2:begin
  283. if(clk_cnt==2'd0||clk_cnt==2'd3)
  284. sda_out<=data[6];
  285. end
  286. 4'd3:begin
  287. if(clk_cnt==2'd0||clk_cnt==2'd3)
  288. sda_out<=data[5];
  289. end
  290. 4'd4:begin
  291. if(clk_cnt==2'd0||clk_cnt==2'd3)
  292. sda_out<=data[4];
  293. end
  294. 4'd5:begin
  295. if(clk_cnt==2'd0||clk_cnt==2'd3)
  296. sda_out<=data[3];
  297. end
  298. 4'd6:begin
  299. if(clk_cnt==2'd0||clk_cnt==2'd3)
  300. sda_out<=data[2];
  301. end
  302. 4'd7:begin
  303. if(clk_cnt==2'd0||clk_cnt==2'd3)
  304. sda_out<=data[1];
  305. end
  306. 4'd8:begin
  307. if(clk_cnt==2'd0||clk_cnt==2'd3)
  308. sda_out<=data[0];
  309. end
  310. default:sda_out<=1'b1;
  311. endcase
  312. end
  313. STOP:
  314. begin
  315. if(scl==1'b1)
  316. sda_out<=1'b1;
  317. else
  318. sda_out<=1'b0;
  319. end
  320. endcase
  321. end
  322. end
  323. endmodule

四、上电时序代码

  1. module power(
  2. input wire sys_clk ,
  3. input wire sys_rst_n ,
  4. output wire reset ,
  5. output wire pwdn ,
  6. output wire power_done );
  7. reg [13:0] cnt;
  8. parameter max_1=2460,
  9. max_2=3280,
  10. max_3=12296;
  11. always@(posedge sys_clk or negedge sys_rst_n) begin
  12. if(!sys_rst_n)
  13. cnt<=14'b0;
  14. else if(cnt==max_3+8'd100)
  15. cnt<=cnt;
  16. else
  17. cnt<=cnt+1'b1;
  18. end
  19. assign pwdn=(cnt>=max_1)?1'b0:1'b1;
  20. assign reset=(cnt>=max_2)?1'b1:1'b0;
  21. assign power_done=(cnt>=max_3)?1'b1:1'b0;
  22. endmodule

五、串口发送模块

  1. module data_uart(
  2. input wire clk ,
  3. input wire pclk ,
  4. input wire vsync ,
  5. input wire [7:0] rgb_din ,
  6. input wire hsync ,
  7. input wire sys_rst_n ,
  8. output wire tx );
  9. parameter bote=9600,
  10. period=50_000_000;
  11. parameter max=period/bote;
  12. wire data_valid ;
  13. reg [12:0] cnt ;
  14. reg [3:0] bit_cnt ;
  15. wire uart_clk ;
  16. Gowin_rPLL uucc(
  17. .clkout(uart_clk), //output clkout
  18. .clkin(clk) //input clkin
  19. );
  20. always@(posedge uart_clk or negedge sys_rst_n) begin
  21. if(!sys_rst_n)
  22. cnt<=13'b0;
  23. else if(cnt==max-1'b1)
  24. cnt<=13'b0;
  25. else
  26. cnt<=cnt+1'b1;
  27. end
  28. always@(posedge uart_clk or negedge sys_rst_n) begin
  29. if(!sys_rst_n)
  30. bit_cnt<=4'b0;
  31. else if (bit_cnt==4'd9&&cnt==max-1'b1)
  32. bit_cnt<=4'b0;
  33. else if(cnt==max-1'b1)
  34. bit_cnt<=bit_cnt+1'b1;
  35. else
  36. bit_cnt<=bit_cnt;
  37. end
  38. assign data_valid=(bit_cnt==4'd9&&cnt==max-1'b1&&hsync==1'b1)?1'b1:1'b0;
  39. urat_tx
  40. #(.bote(9600),
  41. .period(50_000_000))
  42. urat_tx_inst
  43. (
  44. .clk (uart_clk) ,
  45. .rst (sys_rst_n) ,
  46. .data (rgb_din) ,
  47. .data_valid (data_valid) ,
  48. .tx (tx) );
  49. endmodule
  1. module urat_tx
  2. #(parameter bote=9600,
  3. parameter period=50_000_000)
  4. (
  5. input wire clk,
  6. input wire rst,
  7. input wire [7:0] data,
  8. input wire data_valid,
  9. output reg tx);
  10. reg work_en;
  11. reg [15:0] baud_cnt;
  12. reg [3:0] bit_cnt;
  13. wire bit_flag;
  14. parameter max=period/bote;
  15. always@(posedge clk or negedge rst) begin
  16. if(!rst)
  17. work_en<=1'b0;
  18. else if((bit_cnt==4'd10)&&(baud_cnt==16'd1))
  19. work_en<=1'b0;
  20. else if(data_valid==1'b1)
  21. work_en<=1'b1;
  22. else
  23. work_en<=work_en;
  24. end
  25. always@(posedge clk or negedge rst) begin
  26. if(!rst)
  27. baud_cnt<=16'b0;
  28. else if((baud_cnt==max-1)&&(work_en==1'b1))
  29. baud_cnt<=16'b0;
  30. else if(work_en==1'b1)
  31. baud_cnt<=baud_cnt+1'b1;
  32. else
  33. baud_cnt<=16'b0;
  34. end
  35. assign bit_falg=((baud_cnt==16'b0)&&(work_en==1'b1))?1'b1:1'b0;
  36. always@(posedge clk or negedge rst) begin
  37. if(!rst)
  38. bit_cnt<=4'b0;
  39. else if((bit_cnt==4'd10)&&(baud_cnt==16'd1))
  40. bit_cnt<=4'b0;
  41. else if(bit_falg==1'b1)
  42. bit_cnt<=bit_cnt+1'b1;
  43. else
  44. bit_cnt<=bit_cnt;
  45. end
  46. always@(*) begin
  47. if(!rst)
  48. tx<=1'b1;
  49. else begin
  50. case(bit_cnt)
  51. 4'd0:tx<=1'b1;
  52. 4'd1:tx<=1'b0;
  53. 4'd2:tx<=data[0];
  54. 4'd3:tx<=data[1];
  55. 4'd4:tx<=data[2];
  56. 4'd5:tx<=data[3];
  57. 4'd6:tx<=data[4];
  58. 4'd7:tx<=data[5];
  59. 4'd8:tx<=data[6];
  60. 4'd9:tx<=data[7];
  61. default:tx<=1'b1;
  62. endcase
  63. end
  64. end
  65. endmodule

六、数据发送模块

  1. module IIC_start(
  2. input wire sys_clk ,
  3. input wire sys_rst_n ,
  4. input wire ready_flag ,
  5. output reg sta_flag ,
  6. output wire [7:0] ins ,
  7. output wire [15:0] addr ,
  8. output wire [7:0] data );
  9. always@(posedge sys_clk or negedge sys_rst_n) begin
  10. if(!sys_rst_n)
  11. sta_flag<=1'b0;
  12. else if(ready_flag==1'b1)
  13. sta_flag<=1'b1;
  14. else
  15. sta_flag<=1'b0;
  16. end
  17. reg [9:0] cnt ;
  18. reg [31:0] lut_data ;
  19. assign ins=lut_data[31:24];
  20. assign addr=lut_data[23:8];
  21. assign data=lut_data[7:0];
  22. always@(posedge sta_flag or negedge sys_rst_n) begin
  23. if(!sys_rst_n)
  24. cnt<=10'b0;
  25. else if(cnt==10'd256)
  26. cnt<=cnt;
  27. else
  28. cnt<=cnt+1'b1;
  29. end
  30. always@(*) begin
  31. case(cnt)
  32. 10'd 1: lut_data <= {8'h78 , 24'h310311};// system clock from pad, bit[1]
  33. 10'd 2: lut_data <= {8'h78 , 24'h300882};// software reset, bit[7]// delay 5ms
  34. 10'd 3: lut_data <= {8'h78 , 24'h300842};// software power down, bit[6]
  35. 10'd 4: lut_data <= {8'h78 , 24'h310303};// system clock from PLL, bit[1]
  36. 10'd 5: lut_data <= {8'h78 , 24'h3017ff};// FREX, Vsync, HREF, PCLK, D[9:6] output enable
  37. 10'd 6: lut_data <= {8'h78 , 24'h3018ff};// D[5:0], GPIO[1:0] output enable
  38. 10'd 7: lut_data <= {8'h78 , 24'h30341A};// MIPI 10-bit
  39. 10'd 8: lut_data <= {8'h78 , 24'h303713};// PLL root divider, bit[4], PLL pre-divider, bit[3:0]
  40. 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]
  41. 10'd 10: lut_data <= {8'h78 , 24'h363036};
  42. 10'd 11: lut_data <= {8'h78 , 24'h36310e};
  43. 10'd 12: lut_data <= {8'h78 , 24'h3632e2};
  44. 10'd 13: lut_data <= {8'h78 , 24'h363312};
  45. 10'd 14: lut_data <= {8'h78 , 24'h3621e0};
  46. 10'd 15: lut_data <= {8'h78 , 24'h3704a0};
  47. 10'd 16: lut_data <= {8'h78 , 24'h37035a};
  48. 10'd 17: lut_data <= {8'h78 , 24'h371578};
  49. 10'd 18: lut_data <= {8'h78 , 24'h371701};
  50. 10'd 19: lut_data <= {8'h78 , 24'h370b60};
  51. 10'd 20: lut_data <= {8'h78 , 24'h37051a};
  52. 10'd 21: lut_data <= {8'h78 , 24'h390502};
  53. 10'd 22: lut_data <= {8'h78 , 24'h390610};
  54. 10'd 23: lut_data <= {8'h78 , 24'h39010a};
  55. 10'd 24: lut_data <= {8'h78 , 24'h373112};
  56. 10'd 25: lut_data <= {8'h78 , 24'h360008};// VCM control
  57. 10'd 26: lut_data <= {8'h78 , 24'h360133};// VCM control
  58. 10'd 27: lut_data <= {8'h78 , 24'h302d60};// system control
  59. 10'd 28: lut_data <= {8'h78 , 24'h362052};
  60. 10'd 29: lut_data <= {8'h78 , 24'h371b20};
  61. 10'd 30: lut_data <= {8'h78 , 24'h471c50};
  62. 10'd 31: lut_data <= {8'h78 , 24'h3a1343};// pre-gain = 1.047x
  63. 10'd 32: lut_data <= {8'h78 , 24'h3a1800};// gain ceiling
  64. 10'd 33: lut_data <= {8'h78 , 24'h3a19f8};// gain ceiling = 15.5x
  65. 10'd 34: lut_data <= {8'h78 , 24'h363513};
  66. 10'd 35: lut_data <= {8'h78 , 24'h363603};
  67. 10'd 36: lut_data <= {8'h78 , 24'h363440};
  68. 10'd 37: lut_data <= {8'h78 , 24'h362201}; // 50/60Hz detection 50/60Hz
  69. 10'd 38: lut_data <= {8'h78 , 24'h3c0134};// Band auto, bit[7]
  70. 10'd 39: lut_data <= {8'h78 , 24'h3c0428};// threshold low sum
  71. 10'd 40: lut_data <= {8'h78 , 24'h3c0598};// threshold high sum
  72. 10'd 41: lut_data <= {8'h78 , 24'h3c0600};// light meter 1 threshold[15:8]
  73. 10'd 42: lut_data <= {8'h78 , 24'h3c0708};// light meter 1 threshold[7:0]
  74. 10'd 43: lut_data <= {8'h78 , 24'h3c0800};// light meter 2 threshold[15:8]
  75. 10'd 44: lut_data <= {8'h78 , 24'h3c091c};// light meter 2 threshold[7:0]
  76. 10'd 45: lut_data <= {8'h78 , 24'h3c0a9c};// sample number[15:8]
  77. 10'd 46: lut_data <= {8'h78 , 24'h3c0b40};// sample number[7:0]
  78. 10'd 47: lut_data <= {8'h78 , 24'h381000};// Timing Hoffset[11:8]
  79. 10'd 48: lut_data <= {8'h78 , 24'h381110};// Timing Hoffset[7:0]
  80. 10'd 49: lut_data <= {8'h78 , 24'h381200};// Timing Voffset[10:8]
  81. 10'd 50: lut_data <= {8'h78 , 24'h370864};
  82. 10'd 51: lut_data <= {8'h78 , 24'h400102};// BLC start from line 2
  83. 10'd 52: lut_data <= {8'h78 , 24'h40051a};// BLC always update
  84. 10'd 53: lut_data <= {8'h78 , 24'h300000};// enable blocks
  85. 10'd 54: lut_data <= {8'h78 , 24'h3004ff};// enable clocks
  86. 10'd 55: lut_data <= {8'h78 , 24'h300e58};// MIPI power down, DVP enable
  87. 10'd 56: lut_data <= {8'h78 , 24'h302e00};
  88. 10'd 57: lut_data <= {8'h78 , 24'h430060};// RGB565
  89. 10'd 58: lut_data <= {8'h78 , 24'h501f01};// ISP RGB
  90. 10'd 59: lut_data <= {8'h78 , 24'h440e00};
  91. 10'd 60: lut_data <= {8'h78 , 24'h5000a7}; // Lenc on, raw gamma on, BPC on, WPC on, CIP on
  92. 10'd 61: lut_data <= {8'h78 , 24'h3a0f30};// stable range in high
  93. 10'd 62: lut_data <= {8'h78 , 24'h3a1028};// stable range in low
  94. 10'd 63: lut_data <= {8'h78 , 24'h3a1b30};// stable range out high
  95. 10'd 64: lut_data <= {8'h78 , 24'h3a1e26};// stable range out low
  96. 10'd 65: lut_data <= {8'h78 , 24'h3a1160};// fast zone high
  97. 10'd 66: lut_data <= {8'h78 , 24'h3a1f14};// fast zone low// Lens correction for
  98. 10'd 67: lut_data <= {8'h78 , 24'h580023};
  99. 10'd 68: lut_data <= {8'h78 , 24'h580114};
  100. 10'd 69: lut_data <= {8'h78 , 24'h58020f};
  101. 10'd 70: lut_data <= {8'h78 , 24'h58030f};
  102. 10'd 71: lut_data <= {8'h78 , 24'h580412};
  103. 10'd 72: lut_data <= {8'h78 , 24'h580526};
  104. 10'd 73: lut_data <= {8'h78 , 24'h58060c};
  105. 10'd 74: lut_data <= {8'h78 , 24'h580708};
  106. 10'd 75: lut_data <= {8'h78 , 24'h580805};
  107. 10'd 76: lut_data <= {8'h78 , 24'h580905};
  108. 10'd 77: lut_data <= {8'h78 , 24'h580a08};
  109. 10'd 78: lut_data <= {8'h78 , 24'h580b0d};
  110. 10'd 79: lut_data <= {8'h78 , 24'h580c08};
  111. 10'd 80: lut_data <= {8'h78 , 24'h580d03};
  112. 10'd 81: lut_data <= {8'h78 , 24'h580e00};
  113. 10'd 82: lut_data <= {8'h78 , 24'h580f00};
  114. 10'd 83: lut_data <= {8'h78 , 24'h581003};
  115. 10'd 84: lut_data <= {8'h78 , 24'h581109};
  116. 10'd 85: lut_data <= {8'h78 , 24'h581207};
  117. 10'd 86: lut_data <= {8'h78 , 24'h581303};
  118. 10'd 87: lut_data <= {8'h78 , 24'h581400};
  119. 10'd 88: lut_data <= {8'h78 , 24'h581501};
  120. 10'd 89: lut_data <= {8'h78 , 24'h581603};
  121. 10'd 90: lut_data <= {8'h78 , 24'h581708};
  122. 10'd 91: lut_data <= {8'h78 , 24'h58180d};
  123. 10'd 92: lut_data <= {8'h78 , 24'h581908};
  124. 10'd 93: lut_data <= {8'h78 , 24'h581a05};
  125. 10'd 94: lut_data <= {8'h78 , 24'h581b06};
  126. 10'd 95: lut_data <= {8'h78 , 24'h581c08};
  127. 10'd 96: lut_data <= {8'h78 , 24'h581d0e};
  128. 10'd 97: lut_data <= {8'h78 , 24'h581e29};
  129. 10'd 98: lut_data <= {8'h78 , 24'h581f17};
  130. 10'd 99: lut_data <= {8'h78 , 24'h582011};
  131. 10'd100: lut_data <= {8'h78 , 24'h582111};
  132. 10'd101: lut_data <= {8'h78 , 24'h582215};
  133. 10'd102: lut_data <= {8'h78 , 24'h582328};
  134. 10'd103: lut_data <= {8'h78 , 24'h582446};
  135. 10'd104: lut_data <= {8'h78 , 24'h582526};
  136. 10'd105: lut_data <= {8'h78 , 24'h582608};
  137. 10'd106: lut_data <= {8'h78 , 24'h582726};
  138. 10'd107: lut_data <= {8'h78 , 24'h582864};
  139. 10'd108: lut_data <= {8'h78 , 24'h582926};
  140. 10'd109: lut_data <= {8'h78 , 24'h582a24};
  141. 10'd110: lut_data <= {8'h78 , 24'h582b22};
  142. 10'd111: lut_data <= {8'h78 , 24'h582c24};
  143. 10'd112: lut_data <= {8'h78 , 24'h582d24};
  144. 10'd113: lut_data <= {8'h78 , 24'h582e06};
  145. 10'd114: lut_data <= {8'h78 , 24'h582f22};
  146. 10'd115: lut_data <= {8'h78 , 24'h583040};
  147. 10'd116: lut_data <= {8'h78 , 24'h583142};
  148. 10'd117: lut_data <= {8'h78 , 24'h583224};
  149. 10'd118: lut_data <= {8'h78 , 24'h583326};
  150. 10'd119: lut_data <= {8'h78 , 24'h583424};
  151. 10'd120: lut_data <= {8'h78 , 24'h583522};
  152. 10'd121: lut_data <= {8'h78 , 24'h583622};
  153. 10'd122: lut_data <= {8'h78 , 24'h583726};
  154. 10'd123: lut_data <= {8'h78 , 24'h583844};
  155. 10'd124: lut_data <= {8'h78 , 24'h583924};
  156. 10'd125: lut_data <= {8'h78 , 24'h583a26};
  157. 10'd126: lut_data <= {8'h78 , 24'h583b28};
  158. 10'd127: lut_data <= {8'h78 , 24'h583c42};
  159. 10'd128: lut_data <= {8'h78 , 24'h583dce};// lenc BR offset
  160. 10'd129: lut_data <= {8'h78 , 24'h5180ff};// AWB B block
  161. 10'd130: lut_data <= {8'h78 , 24'h5181f2};// AWB control
  162. 10'd131: lut_data <= {8'h78 , 24'h518200};// [7:4] max local counter, [3:0] max fast counter
  163. 10'd132: lut_data <= {8'h78 , 24'h518314};// AWB advanced
  164. 10'd133: lut_data <= {8'h78 , 24'h518425};
  165. 10'd134: lut_data <= {8'h78 , 24'h518524};
  166. 10'd135: lut_data <= {8'h78 , 24'h518609};
  167. 10'd136: lut_data <= {8'h78 , 24'h518709};
  168. 10'd137: lut_data <= {8'h78 , 24'h518809};
  169. 10'd138: lut_data <= {8'h78 , 24'h518975};
  170. 10'd139: lut_data <= {8'h78 , 24'h518a54};
  171. 10'd140: lut_data <= {8'h78 , 24'h518be0};
  172. 10'd141: lut_data <= {8'h78 , 24'h518cb2};
  173. 10'd142: lut_data <= {8'h78 , 24'h518d42};
  174. 10'd143: lut_data <= {8'h78 , 24'h518e3d};
  175. 10'd144: lut_data <= {8'h78 , 24'h518f56};
  176. 10'd145: lut_data <= {8'h78 , 24'h519046};
  177. 10'd146: lut_data <= {8'h78 , 24'h5191f8};// AWB top limit
  178. 10'd147: lut_data <= {8'h78 , 24'h519204};// AWB bottom limit
  179. 10'd148: lut_data <= {8'h78 , 24'h519370};// red limit
  180. 10'd149: lut_data <= {8'h78 , 24'h5194f0};// green limit
  181. 10'd150: lut_data <= {8'h78 , 24'h5195f0};// blue limit
  182. 10'd151: lut_data <= {8'h78 , 24'h519603};// AWB control
  183. 10'd152: lut_data <= {8'h78 , 24'h519701};// local limit
  184. 10'd153: lut_data <= {8'h78 , 24'h519804};
  185. 10'd154: lut_data <= {8'h78 , 24'h519912};
  186. 10'd155: lut_data <= {8'h78 , 24'h519a04};
  187. 10'd156: lut_data <= {8'h78 , 24'h519b00};
  188. 10'd157: lut_data <= {8'h78 , 24'h519c06};
  189. 10'd158: lut_data <= {8'h78 , 24'h519d82};
  190. 10'd159: lut_data <= {8'h78 , 24'h519e38};// AWB control
  191. 10'd160: lut_data <= {8'h78 , 24'h548001};// Gamma bias plus on, bit[0]
  192. 10'd161: lut_data <= {8'h78 , 24'h548108};
  193. 10'd162: lut_data <= {8'h78 , 24'h548214};
  194. 10'd163: lut_data <= {8'h78 , 24'h548328};
  195. 10'd164: lut_data <= {8'h78 , 24'h548451};
  196. 10'd165: lut_data <= {8'h78 , 24'h548565};
  197. 10'd166: lut_data <= {8'h78 , 24'h548671};
  198. 10'd167: lut_data <= {8'h78 , 24'h54877d};
  199. 10'd168: lut_data <= {8'h78 , 24'h548887};
  200. 10'd169: lut_data <= {8'h78 , 24'h548991};
  201. 10'd170: lut_data <= {8'h78 , 24'h548a9a};
  202. 10'd171: lut_data <= {8'h78 , 24'h548baa};
  203. 10'd172: lut_data <= {8'h78 , 24'h548cb8};
  204. 10'd173: lut_data <= {8'h78 , 24'h548dcd};
  205. 10'd174: lut_data <= {8'h78 , 24'h548edd};
  206. 10'd175: lut_data <= {8'h78 , 24'h548fea};
  207. 10'd176: lut_data <= {8'h78 , 24'h54901d};// color matrix
  208. 10'd177: lut_data <= {8'h78 , 24'h53811e};// CMX1 for Y
  209. 10'd178: lut_data <= {8'h78 , 24'h53825b};// CMX2 for Y
  210. 10'd179: lut_data <= {8'h78 , 24'h538308};// CMX3 for Y
  211. 10'd180: lut_data <= {8'h78 , 24'h53840a};// CMX4 for U
  212. 10'd181: lut_data <= {8'h78 , 24'h53857e};// CMX5 for U
  213. 10'd182: lut_data <= {8'h78 , 24'h538688};// CMX6 for U
  214. 10'd183: lut_data <= {8'h78 , 24'h53877c};// CMX7 for V
  215. 10'd184: lut_data <= {8'h78 , 24'h53886c};// CMX8 for V
  216. 10'd185: lut_data <= {8'h78 , 24'h538910};// CMX9 for V
  217. 10'd186: lut_data <= {8'h78 , 24'h538a01};// sign[9]
  218. 10'd187: lut_data <= {8'h78 , 24'h538b98}; // sign[8:1] // UV adjust
  219. 10'd188: lut_data <= {8'h78 , 24'h558006};// saturation on, bit[1]
  220. 10'd189: lut_data <= {8'h78 , 24'h558340};
  221. 10'd190: lut_data <= {8'h78 , 24'h558410};
  222. 10'd191: lut_data <= {8'h78 , 24'h558910};
  223. 10'd192: lut_data <= {8'h78 , 24'h558a00};
  224. 10'd193: lut_data <= {8'h78 , 24'h558bf8};
  225. 10'd194: lut_data <= {8'h78 , 24'h501d40};// enable manual offset of contrast
  226. 10'd195: lut_data <= {8'h78 , 24'h530008};// CIP sharpen MT threshold 1
  227. 10'd196: lut_data <= {8'h78 , 24'h530130};// CIP sharpen MT threshold 2
  228. 10'd197: lut_data <= {8'h78 , 24'h530210};// CIP sharpen MT offset 1
  229. 10'd198: lut_data <= {8'h78 , 24'h530300};// CIP sharpen MT offset 2
  230. 10'd199: lut_data <= {8'h78 , 24'h530408};// CIP DNS threshold 1
  231. 10'd200: lut_data <= {8'h78 , 24'h530530};// CIP DNS threshold 2
  232. 10'd201: lut_data <= {8'h78 , 24'h530608};// CIP DNS offset 1
  233. 10'd202: lut_data <= {8'h78 , 24'h530716};// CIP DNS offset 2
  234. 10'd203: lut_data <= {8'h78 , 24'h530908};// CIP sharpen TH threshold 1
  235. 10'd204: lut_data <= {8'h78 , 24'h530a30};// CIP sharpen TH threshold 2
  236. 10'd205: lut_data <= {8'h78 , 24'h530b04};// CIP sharpen TH offset 1
  237. 10'd206: lut_data <= {8'h78 , 24'h530c06};// CIP sharpen TH offset 2
  238. 10'd207: lut_data <= {8'h78 , 24'h502500};
  239. 10'd208: lut_data <= {8'h78 , 24'h300802}; // wake up from standby, bit[6]
  240. 10'd209: lut_data <= {8'h78 , 24'h303511};// PLL
  241. 10'd210: lut_data <= {8'h78 , 24'h30368C};// PLL 46-30fps 8c-60fps
  242. 10'd211: lut_data <= {8'h78 , 24'h3c0708};// light meter 1 threshold [7:0]
  243. 10'd212: lut_data <= {8'h78 , 24'h382047};// Sensor flip off, ISP flip on
  244. 10'd213: lut_data <= {8'h78 , 24'h382101};// Sensor mirror on, ISP mirror on, H binning on
  245. 10'd214: lut_data <= {8'h78 , 24'h381431};// X INC
  246. 10'd215: lut_data <= {8'h78 , 24'h381531};// Y INC
  247. 10'd216: lut_data <= {8'h78 , 24'h380000};// HS: X address start high byte
  248. 10'd217: lut_data <= {8'h78 , 24'h380100};// HS: X address start low byte
  249. 10'd218: lut_data <= {8'h78 , 24'h380200};// VS: Y address start high byte
  250. 10'd219: lut_data <= {8'h78 , 24'h380304};// VS: Y address start high byte
  251. 10'd220: lut_data <= {8'h78 , 24'h38040a};// HW (HE)
  252. 10'd221: lut_data <= {8'h78 , 24'h38053f};// HW (HE)
  253. 10'd222: lut_data <= {8'h78 , 24'h380607};// VH (VE)
  254. 10'd223: lut_data <= {8'h78 , 24'h38079b};// VH (VE)
  255. 10'd224: lut_data <= {8'h78 , 24'h380803};// DVPHO //800
  256. 10'd225: lut_data <= {8'h78 , 24'h380920};// DVPHO
  257. 10'd226: lut_data <= {8'h78 , 24'h380a01};// DVPVO //480
  258. 10'd227: lut_data <= {8'h78 , 24'h380be0};// DVPVO
  259. 10'd228: lut_data <= {8'h78 , 24'h380c07};// HTS //Total horizontal size
  260. 10'd229: lut_data <= {8'h78 , 24'h380d68};// HTS
  261. 10'd230: lut_data <= {8'h78 , 24'h380e03};// VTS //total vertical size
  262. 10'd231: lut_data <= {8'h78 , 24'h380fd8};// VTS
  263. 10'd232: lut_data <= {8'h78 , 24'h381306};// Timing Voffset
  264. 10'd233: lut_data <= {8'h78 , 24'h361800};
  265. 10'd234: lut_data <= {8'h78 , 24'h361229};
  266. 10'd235: lut_data <= {8'h78 , 24'h370952};
  267. 10'd236: lut_data <= {8'h78 , 24'h370c03};
  268. 10'd237: lut_data <= {8'h78 , 24'h3a0217};// 60Hz max exposure, night mode 5fps
  269. 10'd238: lut_data <= {8'h78 , 24'h3a0310};// 60Hz max exposure // banding filters are calculated automatically in camera driver
  270. 10'd239: lut_data <= {8'h78 , 24'h3a1417};// 50Hz max exposure, night mode 5fps
  271. 10'd240: lut_data <= {8'h78 , 24'h3a1510};// 50Hz max exposure
  272. 10'd241: lut_data <= {8'h78 , 24'h400402};// BLC 2 lines
  273. 10'd242: lut_data <= {8'h78 , 24'h30021c};// reset JFIFO, SFIFO, JPEG
  274. 10'd243: lut_data <= {8'h78 , 24'h3006c3};// disable clock of JPEG2x, JPEG
  275. 10'd244: lut_data <= {8'h78 , 24'h471303};// JPEG mode 3
  276. 10'd245: lut_data <= {8'h78 , 24'h440704};// Quantization scale
  277. 10'd246: lut_data <= {8'h78 , 24'h460b35};
  278. 10'd247: lut_data <= {8'h78 , 24'h460c22};
  279. 10'd248: lut_data <= {8'h78 , 24'h483722}; // DVP CLK divider
  280. 10'd249: lut_data <= {8'h78 , 24'h382402}; // DVP CLK divider
  281. 10'd250: lut_data <= {8'h78 , 24'h5001a3}; // SDE on, scale on, UV average off, color matrix on, AWB on
  282. 10'd251: lut_data <= {8'h78 , 24'h350300}; // AEC/AGC on
  283. 10'd252: lut_data <= {8'h78 , 24'h301602}; //Strobe output enable
  284. 10'd253: lut_data <= {8'h78 , 24'h3b070a}; //FREX strobe mode1
  285. 10'd254: lut_data <= {8'h78 , 24'h3b0083}; //STROBE CTRL: strobe request ON, Strobe mode: LED3
  286. 10'd255: lut_data <= {8'h78 , 24'h3b0000}; //STROBE CTRL: strobe request OFF
  287. 10'd256: lut_data <= {8'hff , 24'hffffff};
  288. default:lut_data <= {8'h00,16'h0000,8'h00};
  289. endcase
  290. end
  291. endmodule

七、SCCB顶层文件

  1. module IIC_top(
  2. input wire clk ,
  3. input wire sys_rst_n ,
  4. input wire rst_n ,
  5. inout wire sda ,
  6. output wire sda_en ,
  7. output wire sys_clk ,
  8. output wire xclk ,
  9. output wire scl );
  10. reg [5:0] cnt_rs ;
  11. wire [7:0] ins ;
  12. wire [15:0] addr ;
  13. wire [7:0] data ;
  14. wire sta_flag ;
  15. wire ready_flag ;
  16. wire clk_1 ;
  17. reg [5:0] cnt_yu ;
  18. xclk_pll your_instance_name(
  19. .clkout(xclk), //output clkout
  20. .clkin(clk) //input clkin
  21. );
  22. icck_pll iic_inst(
  23. .clkout(clk_1), //output clkout
  24. .clkin(clk) //input clkin
  25. );
  26. assign sys_clk=((cnt_yu>=6'd0)&&(cnt_yu<=6'd25))?1'b1:1'b0;
  27. always@(posedge clk_1 or negedge rst_n) begin
  28. if(!rst_n)
  29. cnt_yu<=6'b0;
  30. else if(cnt_yu==6'd51)
  31. cnt_yu<=6'b0;
  32. else
  33. cnt_yu<=cnt_yu+1'b1;
  34. end
  35. IIC_start IIC_start_inst(
  36. .sys_clk (sys_clk ) ,
  37. .sys_rst_n (sys_rst_n ) ,
  38. .ready_flag (ready_flag ) ,
  39. .sta_flag (sta_flag ) ,
  40. .ins (ins ) ,
  41. .addr (addr ) ,
  42. .data (data ) );
  43. IIC_ctrl IIC_ctrl_inst (
  44. .sys_clk (sys_clk ) ,
  45. .sys_rst_n (sys_rst_n ) ,
  46. .sta_flag (sta_flag ) ,//开始标志,由外部传入
  47. .ins (ins ) ,
  48. .addr (addr ) ,
  49. .data (data ) ,
  50. .sda (sda ) ,
  51. .scl (scl ) ,
  52. .sda_en (sda_en ) ,
  53. .ready_flag (ready_flag) );
  54. endmodule

八、实验顶层代码

  1. module IIC_data_uart (
  2. input wire clk ,
  3. input wire sys_rst_n ,
  4. input wire rst_n ,
  5. input wire pclk ,
  6. input wire hsync ,
  7. input wire [7:0] rgb_din ,
  8. input wire vsync ,
  9. output wire scl ,
  10. inout wire sda ,
  11. output wire xclk ,
  12. output wire pwdn ,
  13. output wire reset ,
  14. output wire sda_en ,
  15. output wire tx );
  16. data_uart data_uart_inst(
  17. .clk (clk ) ,
  18. .pclk (pclk ) ,
  19. .vsync (vsync ) ,
  20. .rgb_din (rgb_din ) ,
  21. .hsync (hsync ) ,
  22. .sys_rst_n (sys_rst_n) ,
  23. .tx (tx ) );
  24. wire power_done ;
  25. IIC_top IIC_top_inst(
  26. .clk (clk ) ,
  27. .sys_rst_n (power_done ) ,
  28. .sda (sda ) ,
  29. .sda_en (sda_en ) ,
  30. .sys_clk (sys_clk ) ,
  31. .xclk (xclk ) ,
  32. .rst_n (rst_n ) ,
  33. .scl (scl ) );
  34. power power_inst(
  35. . sys_clk (sys_clk ) ,
  36. . sys_rst_n (sys_rst_n ) ,
  37. . reset (reset ) ,
  38. . pwdn (pwdn ) ,
  39. . power_done (power_done ) );
  40. endmodule

九、一些话

  由于SCCB协议和IIC协议几乎一摸一样,这里的模块命名都是用的IIC。数据手册这里贴不上来,兄弟们如果有需求的话评论区指出来,我到时候甩个网盘链接上去。OV5640输出数据类似于VGA和HDMI的时序,接下来会继续更新VGA和HDMI的相关时序分析和代码。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/586055
推荐阅读
相关标签
  

闽ICP备14008679号