赞
踩
OV5640摄像头有许多工作模式,如可以工作在1080P,720P,480P分辨率的情况下,输出的数据格式也可以是RGB,RAW格式,也可以又DVP,MIPI数据接口,那么实际中我们应该如何指定摄像头的具体工作模式,以便于我们之后的处理。所使用的方法就是SCCB协议进行配置摄像头,前面的文章中我们已经介绍了SCCB协议与IIC协议的不同点,其中写协议是完全相同的,所以这里我们将利用SCCB协议进行OV5640的配置。
这里我们前面已经讲过了IIC协议,这里将不再详细讲解SCCB协议的时序,因为他们两个几乎完全一样,不同点参考前面的文章,这里我们说明我们进行的摄像头配置是720P的分辨率,具体配置上面的哪种情况,可以查看数据手册,只需要更改特定的寄存器即可。
这里我们直接给出逻辑代码供同学们学习,大家可以学些外设寄存器配置的方法,主要分为两个.v文件,其中控制文件代码如下:
`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : nnzhang1996@foxmail.com // Website : // Module Name : ov5640_cfg.v // Create Time : 2020-02-08 15:29:43 // Editor : sublime text3, tab size (4) // CopyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module ov5640_cfg( //system signals input sclk , input rst_n , //iic interfaces output wire iic_sck , inout iic_sda , //others input power_done , output reg cfg_done ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ localparam ANUM = 304 ; //ov5640_sccb_inst reg wr_flag ; wire wr_done ; //others wire [23:0] cfg_array[ANUM-1:0] ; reg power_done_r ; wire power_pos ; reg [ 8:0] cnt_num ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ assign cfg_array[000] = {16'h3103, 8'h11}; assign cfg_array[001] = {16'h3008, 8'h82}; assign cfg_array[002] = {16'h3008, 8'h42}; assign cfg_array[003] = {16'h3103, 8'h03}; assign cfg_array[004] = {16'h3017, 8'hff}; assign cfg_array[005] = {16'h3018, 8'hff}; assign cfg_array[006] = {16'h3034, 8'h1A}; assign cfg_array[007] = {16'h3037, 8'h13}; // PLL root divider, bit[4], PLL pre-divider, bit[3:0] assign cfg_array[008] = {16'h3108, 8'h01}; // PCLK root divider, bit[5:4], SCLK2x root divider, bit[3:2] // SCLK root divider, bit[1:0] assign cfg_array[009] = {16'h3630, 8'h36}; assign cfg_array[010] = {16'h3631, 8'h0e}; assign cfg_array[011] = {16'h3632, 8'he2}; assign cfg_array[012] = {16'h3633, 8'h12}; assign cfg_array[013] = {16'h3621, 8'he0}; assign cfg_array[014] = {16'h3704, 8'ha0}; assign cfg_array[015] = {16'h3703, 8'h5a}; assign cfg_array[016] = {16'h3715, 8'h78}; assign cfg_array[017] = {16'h3717, 8'h01}; assign cfg_array[018] = {16'h370b, 8'h60}; assign cfg_array[019] = {16'h3705, 8'h1a}; assign cfg_array[020] = {16'h3905, 8'h02}; assign cfg_array[021] = {16'h3906, 8'h10}; assign cfg_array[022] = {16'h3901, 8'h0a}; assign cfg_array[023] = {16'h3731, 8'h12}; assign cfg_array[024] = {16'h3600, 8'h08}; assign cfg_array[025] = {16'h3601, 8'h33}; assign cfg_array[026] = {16'h302d, 8'h60}; assign cfg_array[027] = {16'h3620, 8'h52}; assign cfg_array[028] = {16'h371b, 8'h20}; assign cfg_array[029] = {16'h471c, 8'h50}; assign cfg_array[030] = {16'h3a13, 8'h43}; assign cfg_array[031] = {16'h3a18, 8'h00}; assign cfg_array[032] = {16'h3a19, 8'hf8}; assign cfg_array[033] = {16'h3635, 8'h13}; assign cfg_array[034] = {16'h3636, 8'h03}; assign cfg_array[035] = {16'h3634, 8'h40}; assign cfg_array[036] = {16'h3622, 8'h01}; assign cfg_array[037] = {16'h3c01, 8'h34}; assign cfg_array[038] = {16'h3c04, 8'h28}; assign cfg_array[039] = {16'h3c05, 8'h98}; assign cfg_array[040] = {16'h3c06, 8'h00}; assign cfg_array[041] = {16'h3c07, 8'h08}; assign cfg_array[042] = {16'h3c08, 8'h00}; assign cfg_array[043] = {16'h3c09, 8'h1c}; assign cfg_array[044] = {16'h3c0a, 8'h9c}; assign cfg_array[045] = {16'h3c0b, 8'h40}; assign cfg_array[046] = {16'h3810, 8'h00}; assign cfg_array[047] = {16'h3811, 8'h10}; assign cfg_array[048] = {16'h3812, 8'h00}; assign cfg_array[049] = {16'h3708, 8'h64}; assign cfg_array[050] = {16'h4001, 8'h02}; assign cfg_array[051] = {16'h4005, 8'h1a}; assign cfg_array[052] = {16'h3000, 8'h00}; assign cfg_array[053] = {16'h3004, 8'hff}; assign cfg_array[054] = {16'h300e, 8'h58}; assign cfg_array[055] = {16'h302e, 8'h00}; assign cfg_array[056] = {16'h4300, 8'h60}; assign cfg_array[057] = {16'h501f, 8'h01}; assign cfg_array[058] = {16'h440e, 8'h00}; assign cfg_array[059] = {16'h5000, 8'ha7}; assign cfg_array[060] = {16'h3a0f, 8'h30}; assign cfg_array[061] = {16'h3a10, 8'h28}; assign cfg_array[062] = {16'h3a1b, 8'h30}; assign cfg_array[063] = {16'h3a1e, 8'h26}; assign cfg_array[064] = {16'h3a11, 8'h60}; assign cfg_array[065] = {16'h3a1f, 8'h14}; assign cfg_array[066] = {16'h5800, 8'h23}; assign cfg_array[067] = {16'h5801, 8'h14}; assign cfg_array[068] = {16'h5802, 8'h0f}; assign cfg_array[069] = {16'h5803, 8'h0f}; assign cfg_array[070] = {16'h5804, 8'h12}; assign cfg_array[071] = {16'h5805, 8'h26}; assign cfg_array[072] = {16'h5806, 8'h0c}; assign cfg_array[073] = {16'h5807, 8'h08}; assign cfg_array[074] = {16'h5808, 8'h05}; assign cfg_array[075] = {16'h5809, 8'h05}; assign cfg_array[076] = {16'h580a, 8'h08}; assign cfg_array[077] = {16'h580b, 8'h0d}; assign cfg_array[078] = {16'h580c, 8'h08}; assign cfg_array[079] = {16'h580d, 8'h03}; assign cfg_array[080] = {16'h580e, 8'h00}; assign cfg_array[081] = {16'h580f, 8'h00}; assign cfg_array[082] = {16'h5810, 8'h03}; assign cfg_array[083] = {16'h5811, 8'h09}; assign cfg_array[084] = {16'h5812, 8'h07}; assign cfg_array[085] = {16'h5813, 8'h03}; assign cfg_array[086] = {16'h5814, 8'h00}; assign cfg_array[087] = {16'h5815, 8'h01}; assign cfg_array[088] = {16'h5816, 8'h03}; assign cfg_array[089] = {16'h5817, 8'h08}; assign cfg_array[090] = {16'h5818, 8'h0d}; assign cfg_array[091] = {16'h5819, 8'h08}; assign cfg_array[092] = {16'h581a, 8'h05}; assign cfg_array[093] = {16'h581b, 8'h06}; assign cfg_array[094] = {16'h581c, 8'h08}; assign cfg_array[095] = {16'h581d, 8'h0e}; assign cfg_array[096] = {16'h581e, 8'h29}; assign cfg_array[097] = {16'h581f, 8'h17}; assign cfg_array[098] = {16'h5820, 8'h11}; assign cfg_array[099] = {16'h5821, 8'h11}; assign cfg_array[100] = {16'h5822, 8'h15}; assign cfg_array[101] = {16'h5823, 8'h28}; assign cfg_array[102] = {16'h5824, 8'h46}; assign cfg_array[103] = {16'h5825, 8'h26}; assign cfg_array[104] = {16'h5826, 8'h08}; assign cfg_array[105] = {16'h5827, 8'h26}; assign cfg_array[106] = {16'h5828, 8'h64}; assign cfg_array[107] = {16'h5829, 8'h26}; assign cfg_array[108] = {16'h582a, 8'h24}; assign cfg_array[109] = {16'h582b, 8'h22}; assign cfg_array[110] = {16'h582c, 8'h24}; assign cfg_array[111] = {16'h582d, 8'h24}; assign cfg_array[112] = {16'h582e, 8'h06}; assign cfg_array[113] = {16'h582f, 8'h22}; assign cfg_array[114] = {16'h5830, 8'h40}; assign cfg_array[115] = {16'h5831, 8'h42}; assign cfg_array[116] = {16'h5832, 8'h24}; assign cfg_array[117] = {16'h5833, 8'h26}; assign cfg_array[118] = {16'h5834, 8'h24}; assign cfg_array[119] = {16'h5835, 8'h22}; assign cfg_array[120] = {16'h5836, 8'h22}; assign cfg_array[121] = {16'h5837, 8'h26}; assign cfg_array[122] = {16'h5838, 8'h44}; assign cfg_array[123] = {16'h5839, 8'h24}; assign cfg_array[124] = {16'h583a, 8'h26}; assign cfg_array[125] = {16'h583b, 8'h28}; assign cfg_array[126] = {16'h583c, 8'h42}; assign cfg_array[127] = {16'h583d, 8'hce}; assign cfg_array[128] = {16'h5180, 8'hff}; assign cfg_array[129] = {16'h5181, 8'hf2}; assign cfg_array[130] = {16'h5182, 8'h00}; assign cfg_array[131] = {16'h5183, 8'h14}; assign cfg_array[132] = {16'h5184, 8'h25}; assign cfg_array[133] = {16'h5185, 8'h24}; assign cfg_array[134] = {16'h5186, 8'h09}; assign cfg_array[135] = {16'h5187, 8'h09}; assign cfg_array[136] = {16'h5188, 8'h09}; assign cfg_array[137] = {16'h5189, 8'h75}; assign cfg_array[138] = {16'h518a, 8'h54}; assign cfg_array[139] = {16'h518b, 8'he0}; assign cfg_array[140] = {16'h518c, 8'hb2}; assign cfg_array[141] = {16'h518d, 8'h42}; assign cfg_array[142] = {16'h518e, 8'h3d}; assign cfg_array[143] = {16'h518f, 8'h56}; assign cfg_array[144] = {16'h5190, 8'h46}; assign cfg_array[145] = {16'h5191, 8'hf8}; assign cfg_array[146] = {16'h5192, 8'h04}; assign cfg_array[147] = {16'h5193, 8'h70}; assign cfg_array[148] = {16'h5194, 8'hf0}; assign cfg_array[149] = {16'h5195, 8'hf0}; assign cfg_array[150] = {16'h5196, 8'h03}; assign cfg_array[151] = {16'h5197, 8'h01}; assign cfg_array[152] = {16'h5198, 8'h04}; assign cfg_array[153] = {16'h5199, 8'h12}; assign cfg_array[154] = {16'h519a, 8'h04}; assign cfg_array[155] = {16'h519b, 8'h00}; assign cfg_array[156] = {16'h519c, 8'h06}; assign cfg_array[157] = {16'h519d, 8'h82}; assign cfg_array[158] = {16'h519e, 8'h38}; assign cfg_array[159] = {16'h5480, 8'h01}; assign cfg_array[160] = {16'h5481, 8'h08}; assign cfg_array[161] = {16'h5482, 8'h14}; assign cfg_array[162] = {16'h5483, 8'h28}; assign cfg_array[163] = {16'h5484, 8'h51}; assign cfg_array[164] = {16'h5485, 8'h65}; assign cfg_array[165] = {16'h5486, 8'h71}; assign cfg_array[166] = {16'h5487, 8'h7d}; assign cfg_array[167] = {16'h5488, 8'h87}; assign cfg_array[168] = {16'h5489, 8'h91}; assign cfg_array[169] = {16'h548a, 8'h9a}; assign cfg_array[170] = {16'h548b, 8'haa}; assign cfg_array[171] = {16'h548c, 8'hb8}; assign cfg_array[172] = {16'h548d, 8'hcd}; assign cfg_array[173] = {16'h548e, 8'hdd}; assign cfg_array[174] = {16'h548f, 8'hea}; assign cfg_array[175] = {16'h5490, 8'h1d}; assign cfg_array[176] = {16'h5381, 8'h1e}; assign cfg_array[177] = {16'h5382, 8'h5b}; assign cfg_array[178] = {16'h5383, 8'h08}; assign cfg_array[179] = {16'h5384, 8'h0a}; assign cfg_array[180] = {16'h5385, 8'h7e}; assign cfg_array[181] = {16'h5386, 8'h88}; assign cfg_array[182] = {16'h5387, 8'h7c}; assign cfg_array[183] = {16'h5388, 8'h6c}; assign cfg_array[184] = {16'h5389, 8'h10}; assign cfg_array[185] = {16'h538a, 8'h01}; assign cfg_array[186] = {16'h538b, 8'h98}; assign cfg_array[187] = {16'h5580, 8'h06}; assign cfg_array[188] = {16'h5583, 8'h40}; assign cfg_array[189] = {16'h5584, 8'h10}; assign cfg_array[190] = {16'h5589, 8'h10}; assign cfg_array[191] = {16'h558a, 8'h00}; assign cfg_array[192] = {16'h558b, 8'hf8}; assign cfg_array[193] = {16'h501d, 8'h40}; assign cfg_array[194] = {16'h5300, 8'h08}; assign cfg_array[195] = {16'h5301, 8'h30}; assign cfg_array[196] = {16'h5302, 8'h10}; assign cfg_array[197] = {16'h5303, 8'h00}; assign cfg_array[198] = {16'h5304, 8'h08}; assign cfg_array[199] = {16'h5305, 8'h30}; assign cfg_array[200] = {16'h5306, 8'h08}; assign cfg_array[201] = {16'h5307, 8'h16}; assign cfg_array[202] = {16'h5309, 8'h08}; assign cfg_array[203] = {16'h530a, 8'h30}; assign cfg_array[204] = {16'h530b, 8'h04}; assign cfg_array[205] = {16'h530c, 8'h06}; assign cfg_array[206] = {16'h5025, 8'h00}; assign cfg_array[207] = {16'h3008, 8'h02}; assign cfg_array[208] = {16'h3035, 8'h11}; assign cfg_array[209] = {16'h3036, 8'h46}; assign cfg_array[210] = {16'h3c07, 8'h08}; assign cfg_array[211] = {16'h3820, 8'h41}; assign cfg_array[212] = {16'h3821, 8'h07}; assign cfg_array[213] = {16'h3814, 8'h31}; assign cfg_array[214] = {16'h3815, 8'h31}; assign cfg_array[215] = {16'h3800, 8'h00}; assign cfg_array[216] = {16'h3801, 8'h00}; assign cfg_array[217] = {16'h3802, 8'h00}; assign cfg_array[218] = {16'h3803, 8'h04}; assign cfg_array[219] = {16'h3804, 8'h0a}; assign cfg_array[220] = {16'h3805, 8'h3f}; assign cfg_array[221] = {16'h3806, 8'h07}; assign cfg_array[222] = {16'h3807, 8'h9b}; assign cfg_array[223] = {16'h3808, 8'h03}; assign cfg_array[224] = {16'h3809, 8'h20}; assign cfg_array[225] = {16'h380a, 8'h02}; assign cfg_array[226] = {16'h380b, 8'h58}; assign cfg_array[227] = {16'h380c, 8'h07}; assign cfg_array[228] = {16'h380d, 8'h68}; assign cfg_array[229] = {16'h380e, 8'h03}; assign cfg_array[230] = {16'h380f, 8'hd8}; assign cfg_array[231] = {16'h3813, 8'h06}; assign cfg_array[232] = {16'h3618, 8'h00}; assign cfg_array[233] = {16'h3612, 8'h29}; assign cfg_array[234] = {16'h3709, 8'h52}; assign cfg_array[235] = {16'h370c, 8'h03}; assign cfg_array[236] = {16'h3a02, 8'h17}; assign cfg_array[237] = {16'h3a03, 8'h10}; assign cfg_array[238] = {16'h3a14, 8'h17}; assign cfg_array[239] = {16'h3a15, 8'h10}; assign cfg_array[240] = {16'h4004, 8'h02}; assign cfg_array[241] = {16'h3002, 8'h1c}; assign cfg_array[242] = {16'h3006, 8'hc3}; assign cfg_array[243] = {16'h4713, 8'h03}; assign cfg_array[244] = {16'h4407, 8'h04}; assign cfg_array[245] = {16'h460b, 8'h35}; assign cfg_array[246] = {16'h460c, 8'h22}; assign cfg_array[247] = {16'h4837, 8'h22}; assign cfg_array[248] = {16'h3824, 8'h02}; assign cfg_array[249] = {16'h5001, 8'ha3}; assign cfg_array[250] = {16'h3503, 8'h00}; assign cfg_array[251] = {16'h3035, 8'h21}; // PLL input clock =24Mhz, PCLK =84Mhz assign cfg_array[252] = {16'h3036, 8'h69}; assign cfg_array[253] = {16'h3c07, 8'h07}; assign cfg_array[254] = {16'h3820, 8'h47}; assign cfg_array[255] = {16'h3821, 8'h07}; assign cfg_array[256] = {16'h3814, 8'h31}; assign cfg_array[257] = {16'h3815, 8'h31}; assign cfg_array[258] = {16'h3800, 8'h00}; // HS assign cfg_array[259] = {16'h3801, 8'h00}; // HS assign cfg_array[260] = {16'h3802, 8'h00}; // VS assign cfg_array[261] = {16'h3803, 8'hfa}; // VS assign cfg_array[262] = {16'h3804, 8'h0a}; // HW (HE) assign cfg_array[263] = {16'h3805, 8'h3f}; // HW (HE) assign cfg_array[264] = {16'h3806, 8'h06}; // VH (VE) assign cfg_array[265] = {16'h3807, 8'ha9}; // VH (VE) assign cfg_array[266] = {16'h3808, 8'h04}; // DVPHO (1024) assign cfg_array[267] = {16'h3809, 8'h00}; // DVPHO (1024) assign cfg_array[268] = {16'h380a, 8'h02}; // DVPVO (720) assign cfg_array[269] = {16'h380b, 8'hd0}; // DVPVO (720) assign cfg_array[270] = {16'h380c, 8'h07}; // HTS (1892) 1892*740*65 = 95334200 / 90994176 assign cfg_array[271] = {16'h380d, 8'h64}; // HTS assign cfg_array[272] = {16'h380e, 8'h02}; // VTS (740) assign cfg_array[273] = {16'h380f, 8'he4}; // VTS assign cfg_array[274] = {16'h3813, 8'h04}; // timing V offset assign cfg_array[275] = {16'h3618, 8'h00}; assign cfg_array[276] = {16'h3612, 8'h29}; assign cfg_array[277] = {16'h3709, 8'h52}; assign cfg_array[278] = {16'h370c, 8'h03}; assign cfg_array[279] = {16'h3a02, 8'h02}; assign cfg_array[280] = {16'h3a03, 8'he0}; assign cfg_array[281] = {16'h3a08, 8'h00}; assign cfg_array[282] = {16'h3a09, 8'h6f}; assign cfg_array[283] = {16'h3a0a, 8'h00}; assign cfg_array[284] = {16'h3a0b, 8'h5c}; assign cfg_array[285] = {16'h3a0e, 8'h06}; assign cfg_array[286] = {16'h3a0d, 8'h08}; assign cfg_array[287] = {16'h3a14, 8'h02}; assign cfg_array[288] = {16'h3a15, 8'he0}; assign cfg_array[289] = {16'h4004, 8'h02}; assign cfg_array[290] = {16'h3002, 8'h1c}; assign cfg_array[291] = {16'h3006, 8'hc3}; assign cfg_array[292] = {16'h4713, 8'h03}; assign cfg_array[293] = {16'h4407, 8'h04}; assign cfg_array[294] = {16'h460b, 8'h37}; assign cfg_array[295] = {16'h460c, 8'h20}; assign cfg_array[296] = {16'h4837, 8'h16}; assign cfg_array[297] = {16'h3824, 8'h04}; // PCLK manual divider assign cfg_array[298] = {16'h5001, 8'h83}; assign cfg_array[299] = {16'h3503, 8'h00}; assign cfg_array[300] = {16'h3016, 8'h02}; assign cfg_array[301] = {16'h3b07, 8'h0a}; assign cfg_array[302] = {16'h3b00, 8'h83}; assign cfg_array[303] = {16'h3b00, 8'h00}; assign power_pos = power_done && ~power_done_r; always @(posedge sclk) power_done_r <= power_done; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) wr_flag <= 1'b0; else if(power_pos == 1'b1 || (wr_done == 1'b1 && cnt_num < ANUM - 1'b1)) wr_flag <= 1'b1; else wr_flag <= 1'b0; always @(posedge sclk) if(rst_n == 1'b0) cnt_num <= 9'd0; else if(cnt_num == ANUM - 1'b1 && wr_done == 1'b1) cnt_num <= 9'd0; else if(wr_done == 1'b1) cnt_num <= cnt_num + 1'b1; else cnt_num <= cnt_num; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) cfg_done <= 1'b0; else if(cnt_num == ANUM - 1'b1 && wr_done == 1'b1) cfg_done <= 1'b1; else cfg_done <= cfg_done; ov5640_sccb ov5640_sccb_inst( .sclk (sclk ), .rst_n (rst_n ), .wr_flag (wr_flag ), .wr_data (cfg_array[cnt_num][7:0] ), .addr (cfg_array[cnt_num][23:8] ), .wr_done (wr_done ), .iic_sck (iic_sck ), .iic_sda (iic_sda ) ); endmodule
底层驱动代码如下:
`timescale 1ns / 1ps // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : nnzhang1996@foxmail.com // Website : // Module Name : ov5640_sccb.v // Create Time : 2020-02-08 15:24:58 // Editor : sublime text3, tab size (4) // CopyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module ov5640_sccb( input sclk , input rst_n , input wr_flag , input [ 7:0] wr_data , input [15:0] addr , output reg wr_done , output reg iic_sck , inout iic_sda ); //========================================================================================\ //**************Define Parameter and Internal Signals********************************** //========================================================================================/ parameter DIV_CNT = 499 ; parameter DEVICE_ADDR = 8'h78 ; reg wr_busy ; reg [ 8:0] cnt_500 ; reg [ 5:0] cnt_bit ; reg sda_oe ; reg iic_sda_r ; //========================================================================================\ //************** Main Code ********************************** //========================================================================================/ assign iic_sda = (sda_oe && !iic_sda_r) ? 1'b0:1'bz; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) wr_busy <= 1'b0; else if(wr_flag == 1'b1) wr_busy <= 1'b1; else if(wr_done == 1'b1) wr_busy <= 1'b0; always @(posedge sclk) if(rst_n == 1'b0) cnt_500 <= 8'd0; else if(cnt_500 == DIV_CNT || wr_done == 1'b1) cnt_500 <= 8'd0; else if(wr_busy == 1'b1) cnt_500 <= cnt_500 + 1'b1; else cnt_500 <= cnt_500; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) cnt_bit <= 5'd0; else if(wr_done == 1'b1) cnt_bit <= 5'd0; else if(cnt_500 == DIV_CNT) cnt_bit <= cnt_bit + 1'b1; else cnt_bit <= cnt_bit; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) iic_sck <= 1'b1; else if(cnt_bit != 'd37 && cnt_500 == DIV_CNT/2) iic_sck <= 1'b0; else if(cnt_500 == 'd0) iic_sck <= 1'b1; else iic_sck <= iic_sck; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) sda_oe <= 1'b1; else if((cnt_bit == 8 || cnt_bit == 17 || cnt_bit == 26 || cnt_bit == 35) && cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) sda_oe <= 1'b0; else if((cnt_bit == 9 || cnt_bit == 18 || cnt_bit == 27|| cnt_bit == 36) && cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) sda_oe <= 1'b1; else sda_oe <= sda_oe; always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) iic_sda_r <= 1'b1; else case(cnt_bit) 0 : if(cnt_500 == (DIV_CNT/4)) iic_sda_r <= 1'b0; else if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= DEVICE_ADDR[7-cnt_bit]; else iic_sda_r <= iic_sda_r; 1,2,3,4,5,6 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= DEVICE_ADDR[7-cnt_bit]; else iic_sda_r <= iic_sda_r; 7 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= 1'b0; else iic_sda_r <= iic_sda_r; 8 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= 1'b0; else iic_sda_r <= iic_sda_r; 9,10,11,12,13,14,15,16 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= addr[24-cnt_bit]; else iic_sda_r <= iic_sda_r; 17 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= 1'b0; else iic_sda_r <= iic_sda_r; 18,19,20,21,22,23,24,25 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= addr[25-cnt_bit]; else iic_sda_r <= iic_sda_r; 26 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= 1'b0; else iic_sda_r <= iic_sda_r; 27,28,29,30,31,32,33,34 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= wr_data[34-cnt_bit]; else iic_sda_r <= iic_sda_r; 35 : if(cnt_500 == (DIV_CNT/2 + DIV_CNT/4)) iic_sda_r <= 1'b0; else iic_sda_r <= iic_sda_r; 36 : iic_sda_r <= iic_sda_r; 37 : if(cnt_500 == (DIV_CNT/4)) iic_sda_r <= 1'b1; default : iic_sda_r <= 1'b1; endcase always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0) wr_done <= 1'b0; else if(cnt_bit == 'd37 && cnt_500 == (DIV_CNT/2)) wr_done <= 1'b1; else wr_done <= 1'b0; endmodule
大家经过上面的代码学习,相信可以学会FPGA配置OV5640摄像头。
经常看我文章的童鞋应该知道我的套路了,一般情况下一定会给出测试代码方便大家学习,这里我们也给出测试代码如下:
`timescale 1ns / 1ps `define CLOCK 20 // ********************************************************************************* // Project Name : OSXXXX // Author : zhangningning // Email : nnzhang1996@foxmail.com // Website : // Module Name : ov5640_cfg_tb.v // Create Time : 2020-02-08 16:08:57 // Editor : sublime text3, tab size (4) // CopyRight(c) : All Rights Reserved // // ********************************************************************************* // Modification History: // Date By Version Change Description // ----------------------------------------------------------------------- // XXXX zhangningning 1.0 Original // // ********************************************************************************* module ov5640_cfg_tb; reg sclk ; reg rst_n ; wire iic_sck ; wire iic_sda ; reg power_done ; wire cfg_done ; initial begin sclk = 1'b0; rst_n <= 1'b0; power_done <= 1'b0; #(100*`CLOCK); rst_n <= 1'b1; #(10*`CLOCK); power_done <= 1'b1; end always #(`CLOCK/2) sclk = ~sclk; ov5640_cfg ov5640_cfg_inst( //system signals .sclk (sclk ), .rst_n (rst_n ), //iic interfaces .iic_sck (iic_sck ), .iic_sda (iic_sda ), //others .power_done (power_done ), .cfg_done (cfg_done ) ); endmodule
创作不易,认为文章有帮助的同学们可以关注点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。