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 : [email protected]
// 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 : [email protected]
// 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 : [email protected]
// 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
创作不易,认为文章有帮助的同学们可以关注点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: