首先必查ov5640的datasheet。得知他的上电时序图
-----主要要注意的信号主要有三个。前三个信号,dvdd,d0vdd,avdd都是直接由摄像头内部配置好的,所以不用管。需要注意的是pwdn和resetb两个信号。
-----需要我们去规划的时间段有三个t2和t3和t4。
值得一说的是本人采用always模块去写,但也可以用状态机去写,下次我觉得可以尝试一下(*′艸`) 。
------------------------------------------------------------------------------代码如下------------------------------------------------------------------------------------------
module power_control(
//system signal
input sclk,//100Mhz 10ns这里是以这个时钟为标准去设计的计数器,也可以根据自己板卡的时钟去另设接下来计数器
input s_rst_n,
//ov5640
output wire ov5640_pwdn,
output wire ov5640_rst_n,
//others
output wire power_done
);
////define code,事先对需要延时的时间定义一下,方便之后修改,另外这里定义的时间都是原时间加了1ms,保证能确实完成上电
localparam delay_6ms = 60_0000;
localparam delay_2ms = 20_0000;
localparam delay_21ms = 210_0000;
reg [19:0] cnt_6ms;
reg [18:0] cnt_2ms;
reg [24:0] cnt_21ms;
////main code
///6ms这里就是t2所需要的5ms延迟的计数器啦(*′艸`)
always@(posedge sclk or negedge s_rst_n)begin
if(s_rst_n == 1‘b0)
cnt_6ms <= ‘d0;
else if (ov5640_pwdn == 1‘b1)
cnt_6ms <= cnt_6ms + 1;
end
///2ms这里是t3所需要的1ms延时的技术啦o(▼皿▼メ;)o
always@(posedge sclk or negedge s_rst_n)begin
if(s_rst_n == 1‘b0)
cnt_2ms <= ‘d0;
else if (ov5640_rst_n == 1‘b0 && ov5640_pwdn == 1‘b0)
cnt_2ms <= cnt_2ms + 1;
end
//21ms这里就是t3需要的21ms延迟的标志位的计数器啦
always@(posedge sclk or negedge s_rst_n)begin
if(s_rst_n == 1‘b0)
cnt_21ms <= ‘d0;
else if (ov5640_rst_n == 1‘b1)
cnt_21ms <= cnt_21ms + 1;
end
//信号高低
assign power_done = (cnt_21ms >= delay_21ms) ? 1‘b0:1‘b1;
assign ov5640_pwdn = (cnt_6ms >= delay_6ms) ? 1‘b0:1‘b1;
assign ov5640_rst_n = (cnt_2ms >= delay_2ms) ? 1‘b1:1‘b0;
endmodule
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
接下来就是sim代码了。我这里是给的10ns一周期也就是100Mhz的时钟去仿真的。先上波形然后再上代码吧( =①ω①=)
注意仿真时间要拉长到30ms,不然出来的仿真不完整。整个过程花费的是29ms。30ms刚好能看到完整的图。
module _sim();
reg sclk;
reg s_rst_n;
wire ov5640_pwdn;
wire ov5640_rst_n;
wire power_done;
initial begin
sclk = 1;
s_rst_n <= 0;
#100
s_rst_n <= 1;
end
always
#5 sclk=~sclk;
power_control ints(
//system signal
.sclk(sclk),
.s_rst_n(s_rst_n),
.ov5640_pwdn(ov5640_pwdn),
.ov5640_rst_n(ov5640_rst_n),
.power_done(power_done)
我自己当时时钟是这么写的 #10 sclk = ~sclk;然后出来的波形莫名其妙大了一倍,然后突然发现这里的延时只是半周期,所以为了改成10ns的周期波形还是要设5秒的延迟啦ヽ(??▽?)ノ。
上电时序就此完成,对于其他的摄像头也可以这么处理。之后还会继续学习的。
fpga中基于vivado的verilog语言——ov5640的上电时序编写
原文:https://www.cnblogs.com/wakasa030/p/13734844.html