基于FPGA的OV5640摄像头驱动



<1>OV5640 的控制寄存器,它根据这些寄存器配置的参数来运行,而这些参数是由外部控制器通过 SIO_C 和 SIO_D 引脚写入的, SIO_C与 SIO_D 使用的通讯协议跟 I2C十分类似。
<2>OV5640的通信、控制信号及外部时钟,其中 PCLK、 HREF 及VSYNC分别是像素同步时钟、行同步信号以及帧同步信号,这与液晶屏控制中的信号是很类似的。 RESETB引脚为低电平时,用于复位整个传感器芯片,PWDN 用于控制芯片进入低功耗模式。注意最后的一个 XCLK引脚,它跟 PCLK
是完全不同的, XCLK 是用于驱动整个传感器芯片的时钟信号,是外部输入到OV5640的信号;而 PCLK是 OV5640输出数据时的同步信号,它是由 OV5640 输出的信号。 XCLK可以外接晶振或由外部控制器提供。
<3>感光矩阵,光信号在这里转化成电信号,经过各种处理,这些信号存储成由一个个像素点表示的数字图像。
<4>包含了 DSP 处理单元,它会根据控制寄存器的配置做一些基本的图像处理运算。这部分还包含了图像格式转换单元及压缩单元,转换出的数据最终通过Y0-Y9引脚输出,一般来说我们使用 8根据数据线来传输,这时仅使用 Y2-Y9 引脚。

<5>VCM 处理单元,他会通过图像分析来实现图像的自动对焦功能。要实现自动对焦还需要下载自动对焦固件到模组,后面摄像头实验详细介绍这个功能。




注意:当主机向从机进行指令或数据的写入时,串行数据线SDA上的数据在串行时钟SCL
为高电平时写入从机设备,每次只写入一位数据;串行数据线SDA中的数据在串行时钟
SCL为低电平时进行数据更新,以保证在SCL为高电平时采集到SDA数据的稳定状态。


module Power_ctrl
#(
parameter CNT_5MS = 20'd250_000,
parameter CNT_1MS = 20'd50_000,
parameter CNT_20MS = 20'd1000_000
)
(
input wire sys_clk,
input wire rst,
output wire pwdn,
output wire resetb,
output wire sccb_en,
output wire clk_en
);
reg [20:0] cnt;
assign pwdn = (cnt >= CNT_5MS - 1'd1)?1'd0:1'd1;
assign resetb = (cnt >= CNT_5MS + CNT_1MS - 1'd1)?1'd1:1'd0;
assign sccb_en = (cnt >= (CNT_5MS + CNT_1MS + CNT_20MS - 1'd1))?1'd1:1'd0;
assign clk_en = (cnt >= CNT_5MS - 1'd1)?1'd1:1'd0;
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt <= 1'd0;
else if(cnt == (CNT_5MS + CNT_1MS + CNT_20MS - 1'd1))
cnt <= cnt;
else
cnt <= cnt + 1'd1;
endmodule
IIC:

SSCB:

读程序验证以读ID来实现:

时序图:

Start:是用来启动读的标志位,为1时有效
statue:一共13个状态
cnt:这是一个用来统计scl周期个数的变量
cnt_stop_flag:在STOP状态下,需要先用到2个周期来完成STOP的操作,这时cnt_stop_flag为0,当完成后cnt_stop_flag置1
cnt_stop:用来对STOP状态下的计时
I2C_CLK_x:这是一个用来仿真验证的波形,它与scl相差135°的相位,在它的下降沿sda发生改变
cnt_clkx:统计I2C_CLK_x一个周期所需的计数值
cnt_clkx_flag:在cnt_clkx下降沿的前一个周期置一,下降沿处置零
I2C_SDA:sda信号线
Data:{ID,ADD},24位
I2C_CLK:就是SCL
data_flag:DATA状态下,在数据稳定的地方置1一个周期,用来判断什么时候读数据
data:读出的数据
cnt_clk:统计I2C_CLK一个周期所需的计数值
cnt_clkx_flag:在I2C_CLK下降沿的前一个周期置一,下降沿处置零
read_en:结束一次读操作的标志
由于在SSCB时序开始时是sda先产生下降沿,且sda的数据需在scl高电平时保持稳定,所以采用135°相位差的方法来完成,135不是固定的,可以进行一定的修改,sda数据在每个I2C_CLK_x下降沿处改变,在数据发送和接收状态时,每次发8个数据,然后就就进入下一状态,在这里有个问题就是ID号的第八位是省去的,实际的ID就是七位,因为之前没注意,导致第一次仿真无误后上板时出错,查阅资料发现IIC的应答阶段与SSCB不太一样,其实也差不多,就是SSCB的应答处理你可以不用判断是否应答成功,因为SSCB不一定为返回给你正确的应答值,本程序的x表示为应答状态,即不关心状态,在STOP状态时,先利用好两个周期的时间来完成STOP的操作,然后又是和开头的操作一样,重新开始,然后发读的ID,本程序中,sda在所有的x状态和DATA状态都为1’dz,接着开始读数据即可,然后进行NO ACK操作,sda主动置为高电平,完成后就再进行一次STOP操作,结束整个读操作。(注意:SSCB没有IIC的连续读和连续写)
开始位:

停止位:

上面两图第一个信号是scl,第二个是sda
module SSCB_ID
(
input wire sys_clk,
input wire rst,
input wire read_en,
input wire [15:0] addr,
input wire [7:0] ID,
input wire sda_rd,
output reg sda,
output reg scl,
output reg read_end,
output reg [7:0] Data_reg,
output reg [12:0] statue,
output wire [23:0] Cmd
);
localparam
IDLE = 13'b0_0000_0000_0001,
START_ID1 = 13'b0_0000_0000_0010,
x_ack1 = 13'b0_0000_0000_0100,
ADD_H = 13'b0_0000_0000_1000,
x_ack2 = 13'b0_0000_0001_0000,
ADD_L = 13'b0_0000_0010_0000,
x_ack3 = 13'b0_0000_0100_0000,
STOP = 13'b0_0000_1000_0000,
START_ID2 = 13'b0_0001_0000_0000,
x_ack4 = 13'b0_0010_0000_0000,
DATA = 13'b0_0100_0000_0000,
NO = 13'b0_1000_0000_0000,
END = 13'b1_0000_0000_0000;
localparam
CLOCK = 30'd50_000_000,
I2C_CLK = 30'd400_000,
START_MAX = (CLOCK/I2C_CLK)*3/4 - 1'd1,
MAX = CLOCK/I2C_CLK - 1'd1,
MAX_2 = (CLOCK/I2C_CLK)/2 - 1'd1;
//wire [23:0] Cmd;
//reg sda;
assign Cmd = {ID,addr};
//reg sda;
reg [20:0] cnt;
reg [20:0] cnt_stop;
reg cnt_stop_flag;
reg I2C_CLK_x;
reg [20:0] cnt_CLKx;
reg cnt_clkx_flag;
reg data_flag;
reg [20:0] cnt_clk;
reg cnt_clk_flag;
//结束标志
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
read_end <= 1'd0;
else if(statue == END && cnt_clk == MAX - 1'd1)
read_end <= 1'd1;
else
read_end <= 1'd0;
//相移135°的I2C信号计数
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_CLKx <= 1'd0;
else if(cnt_CLKx == MAX)
cnt_CLKx <= 1'd0;
else if(read_en == 1'd1 && (statue == STOP) && cnt_stop_flag == 1'd1)
cnt_CLKx <= cnt_CLKx + 1'd1;
else if(read_en == 1'd1
&& (statue !=STOP)
&& statue != NO && statue != END)
cnt_CLKx <= cnt_CLKx + 1'd1;
else
cnt_CLKx <= 1'd0;
//相移135°的I2C信号周期更替标志
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_clkx_flag <= 1'd0;
else if(cnt_CLKx == MAX - 1'd1)
cnt_clkx_flag <= 1'd1;
else
cnt_clkx_flag <= 1'd0;
//相移135°的I2C信号产生
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
I2C_CLK_x <= 1'd1;
else if((statue == STOP && cnt_stop_flag != 1'd1)
|| (statue == x_ack3 && cnt_clkx_flag == 1'd1)
|| (statue == DATA && cnt == 6'd8 && cnt_clkx_flag == 1'd1)
|| (statue == NO && statue == END))
I2C_CLK_x <= 1'd1;
else if(cnt_CLKx <= MAX_2 -1'd1 && read_en == 1'd1)
I2C_CLK_x <= 1'd0;
else if(cnt_CLKx <= MAX - 1'd1 && read_en == 1'd1)
I2C_CLK_x <= 1'd1;
else if(read_en != 1'd1)
I2C_CLK_x <= 1'd1;
//STOP状态时的计数停
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_stop_flag <= 1'd0;
else if(statue == STOP && cnt == 2'd2 && cnt_stop == MAX)
cnt_stop_flag <= 1'd1;
else if(statue == START_ID2)
cnt_stop_flag <= 1'd0;
//STOP状态下让I2C总线停止两个周期的计
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_stop <= 1'd0;
else if(statue == STOP && cnt_stop == MAX)
cnt_stop <= 1'd0;
else if(statue == STOP && cnt_stop_flag != 1'd1)
cnt_stop <= cnt_stop + 1'd1;
else
cnt_stop <= 1'd0;
//SCL时钟生成
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_clk <= 1'd0;
else if(statue == STOP || statue == IDLE)
cnt_clk <= 1'd0;
else if(cnt_clk == MAX)
cnt_clk <= 1'd0;
else
cnt_clk <= cnt_clk + 1'd1;
//SCL时钟生成
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
scl <= 1'd1;
else if(statue == END && cnt_clk_flag == 1'd1)
scl <= 1'd1;
else if(statue == STOP || (statue == x_ack3 && cnt_clkx_flag == 1'd1))
scl <= 1'd1;
else if(statue == STOP && cnt_stop_flag == 1'd1 && cnt_clkx_flag == 1'd1)
scl <= 1'd0;
else if(statue == IDLE && cnt_CLKx == START_MAX)
scl <= 1'd0;
else if(cnt_clk <= MAX_2 && read_en == 1'd1 && statue != IDLE)
scl <= 1'd0;
else if(cnt_clk < MAX && read_en == 1'd1 && statue != IDLE)
scl <= 1'd1;
else if(cnt_clk == MAX && read_en == 1'd1 && statue != IDLE)
scl <= 1'd0;
else if(read_en != 1'd1)
scl <= 1'd1;
//全局计数
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt <= 1'd0;
else if(statue == STOP)
begin
if(cnt_stop == MAX && cnt == 2'd2)
cnt <= 1'd0;
else if(cnt_stop == MAX)
cnt <= cnt + 1'd1;
else
cnt <= cnt;
end
else if(statue == NO && statue == END)
cnt <= 1'd0;
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
cnt <= 1'd0;
else if(cnt_clkx_flag == 1'd1)
cnt <= cnt + 1'd1;
else
cnt <= cnt;
//I2C信号周期更替标志
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_clk_flag <= 1'd0;
else if(cnt_clk == MAX - 1'd1)
cnt_clk_flag <= 1'd1;
else
cnt_clk_flag <= 1'd0;
//data数据记录标志
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
data_flag <= 1'd0;
else if(statue == DATA && cnt_clk == START_MAX)
data_flag <= 1'd1;
else
data_flag <= 1'd0;
//数据存储
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
Data_reg <= 1'd0;
else if(statue == DATA && data_flag == 1'd1)
Data_reg <= {Data_reg[6:0],sda_rd};
else
Data_reg <= Data_reg;
//状态机跳转
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
statue <= IDLE;
else case(statue)
IDLE:
if(read_en == 1'd1 && cnt_CLKx == START_MAX)
statue <= START_ID1;
START_ID1:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= x_ack1;
x_ack1:
if(cnt_clkx_flag == 1'd1)
statue <= ADD_H;
ADD_H:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= x_ack2;
x_ack2:
if(cnt_clkx_flag == 1'd1)
statue <= ADD_L;
ADD_L:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= x_ack3;
x_ack3:
if(cnt_clkx_flag == 1'd1)
statue <= STOP;
STOP:
if(cnt_stop_flag == 1'd1 && cnt_CLKx == START_MAX)
statue <= START_ID2;
START_ID2:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= x_ack4;
x_ack4:
if(cnt_clkx_flag == 1'd1)
statue <= DATA;
DATA:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= NO;
NO:
if(cnt_clk_flag == 1'd1)
statue <= END;
END:
if(cnt_clk_flag == 1'd1)
statue <= IDLE;
default:statue <= IDLE;
endcase
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
sda <= 1'd1;
else case(statue)
IDLE:
if(read_en == 1'd1)
sda <= 1'd0;
else
sda <= 1'd1;
START_ID1:
if(cnt_clkx_flag == 1'd1 && cnt < 6'd7)
sda <= Cmd[22 - cnt];
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd7)
sda <= 1'd0;
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd0;
x_ack1:
if(cnt_clkx_flag == 1'd1)
sda <= Cmd[15 - cnt];
ADD_H:
if(cnt_clkx_flag == 1'd1 && cnt <= 6'd7)
sda <= Cmd[15 - cnt];
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd0;
x_ack2:
if(cnt_clkx_flag == 1'd1)
sda <= Cmd[7 - cnt];
ADD_L:
if(cnt_clkx_flag == 1'd1 && cnt <= 6'd7)
sda <= Cmd[7 - cnt];
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd0;
x_ack3:
if(cnt_clkx_flag == 1'd1)
sda <= 1'd0;
STOP:
if(cnt_stop_flag != 1'd1 && cnt == 1'd0)
sda <= 1'd0;
else if(cnt_stop_flag == 1'd1)
sda <= 1'd0;
else
sda <= 1'd1;
START_ID2:
if(cnt_clkx_flag == 1'd1 && cnt < 6'd7)
sda <= Cmd[22 - cnt];
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd7)
sda <= 1'd1;
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd0;
x_ack4:
sda <= 1'd0;
DATA:
if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd1;
else
sda <= 1'd0;
NO:
if(cnt_clk_flag == 1'd1)
sda <= 1'd0;
else
sda <= 1'd1;
END:
if(cnt_clk_flag == 1'd1)
sda <= 1'd1;
default:sda <= 1'd1;
endcase
/*
assign sda_x = (statue == x_ack1 || statue == x_ack2 || statue == x_ack3
|| statue == x_ack4 || (statue == DATA))?1'dz:sda;
*/
endmodule
结果演示:

IIC与SSCB通用
设置寄存器时会用到

module SSCB_WR
(
input wire sys_clk,
input wire rst,
input wire WR_en,
input wire [15:0] addr,
input wire [7:0] ID,
input wire [7:0] data,
output reg sda,
output reg scl,
output reg WR_end,
output reg [9:0] statue
);
localparam
IDLE = 10'b0000000001,
START_ID1 = 10'b0000000010,
x_ack1 = 10'b0000000100,
ADD_H = 10'b0000001000,
x_ack2 = 10'b0000010000,
ADD_L = 10'b0000100000,
x_ack3 = 10'b0001000000,
DATA = 10'b0010000000,
x_ack4 = 10'b0100000000,
END = 10'b1000000000;
localparam
CLOCK = 30'd50_000_000,
I2C_CLK = 30'd400_000,
START_MAX = (CLOCK/I2C_CLK)*3/4 - 1'd1,
MAX = CLOCK/I2C_CLK - 1'd1,
MAX_2 = (CLOCK/I2C_CLK)/2 - 1'd1;
wire [23:0] Cmd;
//reg sda;
assign Cmd = {ID,addr};
reg [20:0] cnt;
reg I2C_CLK_x;
reg [20:0] cnt_CLKx;
reg cnt_clkx_flag;
reg [20:0] cnt_clk;
reg cnt_clk_flag;
//结束标志
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
WR_end <= 1'd0;
else if(statue == END && cnt_clk == MAX - 1'd1)
WR_end <= 1'd1;
else
WR_end <= 1'd0;
//相移135°的I2C信号计数
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_CLKx <= 1'd0;
else if(cnt_CLKx == MAX)
cnt_CLKx <= 1'd0;
else if(WR_en == 1'd1 && statue != x_ack4 && statue != END)
cnt_CLKx <= cnt_CLKx + 1'd1;
else
cnt_CLKx <= 1'd0;
//相移135°的I2C信号周期更替标志
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_clkx_flag <= 1'd0;
else if(cnt_CLKx == MAX - 1'd1)
cnt_clkx_flag <= 1'd1;
else
cnt_clkx_flag <= 1'd0;
//相移135°的I2C信号产生
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
I2C_CLK_x <= 1'd1;
else if((statue == DATA && cnt == 6'd8 && cnt_clkx_flag == 1'd1)
|| (statue == x_ack4 && statue == END))
I2C_CLK_x <= 1'd1;
else if(cnt_CLKx <= MAX_2 -1'd1 && WR_en == 1'd1)
I2C_CLK_x <= 1'd0;
else if(cnt_CLKx <= MAX - 1'd1 && WR_en == 1'd1)
I2C_CLK_x <= 1'd1;
else if(WR_en != 1'd1)
I2C_CLK_x <= 1'd1;
//SCL时钟生成
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_clk <= 1'd0;
else if(statue == IDLE)
cnt_clk <= 1'd0;
else if(cnt_clk == MAX)
cnt_clk <= 1'd0;
else
cnt_clk <= cnt_clk + 1'd1;
//SCL时钟生成
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
scl <= 1'd1;
else if(statue == END && cnt_clk_flag == 1'd1)
scl <= 1'd1;
else if(statue == IDLE && cnt_CLKx == START_MAX)
scl <= 1'd0;
else if(cnt_clk <= MAX_2 && WR_en == 1'd1 && statue != IDLE)
scl <= 1'd0;
else if(cnt_clk < MAX && WR_en == 1'd1 && statue != IDLE)
scl <= 1'd1;
else if(cnt_clk == MAX && WR_en == 1'd1 && statue != IDLE)
scl <= 1'd0;
else if(WR_en != 1'd1)
scl <= 1'd1;
//全局计数
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt <= 1'd0;
else if(statue == x_ack4 && statue == END)
cnt <= 1'd0;
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
cnt <= 1'd0;
else if(cnt_clkx_flag == 1'd1)
cnt <= cnt + 1'd1;
else
cnt <= cnt;
//I2C信号周期更替标志
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_clk_flag <= 1'd0;
else if(cnt_clk == MAX - 1'd1)
cnt_clk_flag <= 1'd1;
else
cnt_clk_flag <= 1'd0;
//状态机跳转
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
statue <= IDLE;
else case(statue)
IDLE:
if(WR_en == 1'd1 && cnt_CLKx == START_MAX)
statue <= START_ID1;
START_ID1:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= x_ack1;
x_ack1:
if(cnt_clkx_flag == 1'd1)
statue <= ADD_H;
ADD_H:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= x_ack2;
x_ack2:
if(cnt_clkx_flag == 1'd1)
statue <= ADD_L;
ADD_L:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= x_ack3;
x_ack3:
if(cnt_clkx_flag == 1'd1)
statue <= DATA;
DATA:
if(cnt == 8'd8 && cnt_clkx_flag == 1'd1)
statue <= x_ack4;
x_ack4:
if(cnt_clk_flag == 1'd1)
statue <= END;
END:
if(cnt_clk_flag == 1'd1)
statue <= IDLE;
default:statue <= IDLE;
endcase
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
sda <= 1'd1;
else case(statue)
IDLE:
if(WR_en == 1'd1)
sda <= 1'd0;
else
sda <= 1'd1;
START_ID1:
if(cnt_clkx_flag == 1'd1 && cnt < 6'd7)
sda <= Cmd[22 - cnt];
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd7)
sda <= 1'd0;
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd0;
x_ack1:
if(cnt_clkx_flag == 1'd1)
sda <= Cmd[15 - cnt];
ADD_H:
if(cnt_clkx_flag == 1'd1 && cnt <= 6'd7)
sda <= Cmd[15 - cnt];
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd0;
x_ack2:
if(cnt_clkx_flag == 1'd1)
sda <= Cmd[7 - cnt];
ADD_L:
if(cnt_clkx_flag == 1'd1 && cnt <= 6'd7)
sda <= Cmd[7 - cnt];
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd0;
x_ack3:
if(cnt_clkx_flag == 1'd1)
sda <= data[7 - cnt];
DATA:
if(cnt_clkx_flag == 1'd1 && cnt <= 6'd7)
sda <= data[7 - cnt];
else if(cnt_clkx_flag == 1'd1 && cnt == 6'd8)
sda <= 1'd0;
x_ack4:
if(cnt_clk_flag == 1'd1)
sda <= 1'd0;
else
sda <= 1'd0;
END:
if(cnt_clk_flag == 1'd1)
sda <= 1'd1;
default:sda <= 1'd1;
endcase
/*
assign sda_x = (statue == x_ack1 || statue == x_ack2 || statue == x_ack3
|| statue == x_ack4 || (statue == DATA))?1'dz:sda;
*/
endmodule
module OV5640_cfg
(
input wire sys_clk,
input wire rst,
input wire start,
input wire write_end,
output wire [23:0] cfg_data,
output reg WR_en,
output reg init_end
);
parameter REG_NUM = 8'd251 ;
wire [23:0] cfg_data_reg[REG_NUM-1:0] ;
reg [15:0] cnt;
reg [8:0] number;
reg cnt_en;
parameter delay = 16'd9999;
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt_en <= 1'd0;
else if(write_end == 1'd1 && init_end != 1'd1)
cnt_en <= 1'd1;
else if(cnt == delay)
cnt_en <= 1'd0;
else
cnt_en <= cnt_en;
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
init_end <= 1'd0;
else if(number == REG_NUM && cnt == delay)
init_end <= 1'd1;
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
cnt <= 1'd0;
else if(cnt == delay)
cnt <= 1'd0;
else if(WR_en != 1'd1 && start == 1'd1 && init_end != 1'd1 && cnt_en == 1'd1)
cnt <= cnt + 1'd1;
else
cnt <= 1'd0;
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
number <= 1'd0;
else if(write_end == 1'd1 && number != REG_NUM)
number <= number + 1'd1;
else
number <= number;
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
WR_en <= 1'd0;
else if(write_end == 1'd1)
WR_en <= 1'd0;
else if(number != REG_NUM && cnt == delay)
WR_en <= 1'd1;
else if(number == 1'd0 && start == 1'd1)
WR_en <= 1'd1;
assign cfg_data = (number != REG_NUM)?cfg_data_reg[number]:1'd0;
//cfg_data_reg:寄存器配置数据暂存 ID REG_ADDR REG_VAL
assign cfg_data_reg[000] = {16'h3103, 8'h11};
assign cfg_data_reg[001] = {16'h3008, 8'h82};
assign cfg_data_reg[002] = {16'h3008, 8'h42};
assign cfg_data_reg[003] = {16'h3103, 8'h03};
assign cfg_data_reg[004] = {16'h3017, 8'hff};
assign cfg_data_reg[005] = {16'h3018, 8'hff};
assign cfg_data_reg[006] = {16'h3034, 8'h1A};
assign cfg_data_reg[007] = {16'h3037, 8'h13};
assign cfg_data_reg[008] = {16'h3108, 8'h01};
assign cfg_data_reg[009] = {16'h3630, 8'h36};
assign cfg_data_reg[010] = {16'h3631, 8'h0e};
assign cfg_data_reg[011] = {16'h3632, 8'he2};
assign cfg_data_reg[012] = {16'h3633, 8'h12};
assign cfg_data_reg[013] = {16'h3621, 8'he0};
assign cfg_data_reg[014] = {16'h3704, 8'ha0};
assign cfg_data_reg[015] = {16'h3703, 8'h5a};
assign cfg_data_reg[016] = {16'h3715, 8'h78};
assign cfg_data_reg[017] = {16'h3717, 8'h01};
assign cfg_data_reg[018] = {16'h370b, 8'h60};
assign cfg_data_reg[019] = {16'h3705, 8'h1a};
assign cfg_data_reg[020] = {16'h3905, 8'h02};
assign cfg_data_reg[021] = {16'h3906, 8'h10};
assign cfg_data_reg[022] = {16'h3901, 8'h0a};
assign cfg_data_reg[023] = {16'h3731, 8'h12};
assign cfg_data_reg[024] = {16'h3600, 8'h08};
assign cfg_data_reg[025] = {16'h3601, 8'h33};
assign cfg_data_reg[026] = {16'h302d, 8'h60};
assign cfg_data_reg[027] = {16'h3620, 8'h52};
assign cfg_data_reg[028] = {16'h371b, 8'h20};
assign cfg_data_reg[029] = {16'h471c, 8'h50};
assign cfg_data_reg[030] = {16'h3a13, 8'h43};
assign cfg_data_reg[031] = {16'h3a18, 8'h00};
assign cfg_data_reg[032] = {16'h3a19, 8'hf8};
assign cfg_data_reg[033] = {16'h3635, 8'h13};
assign cfg_data_reg[034] = {16'h3636, 8'h03};
assign cfg_data_reg[035] = {16'h3634, 8'h40};
assign cfg_data_reg[036] = {16'h3622, 8'h01};
assign cfg_data_reg[037] = {16'h3c01, 8'h34};
assign cfg_data_reg[038] = {16'h3c04, 8'h28};
assign cfg_data_reg[039] = {16'h3c05, 8'h98};
assign cfg_data_reg[040] = {16'h3c06, 8'h00};
assign cfg_data_reg[041] = {16'h3c07, 8'h08};
assign cfg_data_reg[042] = {16'h3c08, 8'h00};
assign cfg_data_reg[043] = {16'h3c09, 8'h1c};
assign cfg_data_reg[044] = {16'h3c0a, 8'h9c};
assign cfg_data_reg[045] = {16'h3c0b, 8'h40};
assign cfg_data_reg[046] = {16'h3810, 8'h00};
assign cfg_data_reg[047] = {16'h3811, 8'h10};
assign cfg_data_reg[048] = {16'h3812, 8'h00};
assign cfg_data_reg[049] = {16'h3708, 8'h64};
assign cfg_data_reg[050] = {16'h4001, 8'h02};
assign cfg_data_reg[051] = {16'h4005, 8'h1a};
assign cfg_data_reg[052] = {16'h3000, 8'h00};
assign cfg_data_reg[053] = {16'h3004, 8'hff};
assign cfg_data_reg[054] = {16'h300e, 8'h58};
assign cfg_data_reg[055] = {16'h302e, 8'h00};
assign cfg_data_reg[056] = {16'h4300, 8'h61};
assign cfg_data_reg[057] = {16'h501f, 8'h01};
assign cfg_data_reg[058] = {16'h440e, 8'h00};
assign cfg_data_reg[059] = {16'h5000, 8'ha7};
assign cfg_data_reg[060] = {16'h3a0f, 8'h30};
assign cfg_data_reg[061] = {16'h3a10, 8'h28};
assign cfg_data_reg[062] = {16'h3a1b, 8'h30};
assign cfg_data_reg[063] = {16'h3a1e, 8'h26};
assign cfg_data_reg[064] = {16'h3a11, 8'h60};
assign cfg_data_reg[065] = {16'h3a1f, 8'h14};
assign cfg_data_reg[066] = {16'h5800, 8'h23};
assign cfg_data_reg[067] = {16'h5801, 8'h14};
assign cfg_data_reg[068] = {16'h5802, 8'h0f};
assign cfg_data_reg[069] = {16'h5803, 8'h0f};
assign cfg_data_reg[070] = {16'h5804, 8'h12};
assign cfg_data_reg[071] = {16'h5805, 8'h26};
assign cfg_data_reg[072] = {16'h5806, 8'h0c};
assign cfg_data_reg[073] = {16'h5807, 8'h08};
assign cfg_data_reg[074] = {16'h5808, 8'h05};
assign cfg_data_reg[075] = {16'h5809, 8'h05};
assign cfg_data_reg[076] = {16'h580a, 8'h08};
assign cfg_data_reg[077] = {16'h580b, 8'h0d};
assign cfg_data_reg[078] = {16'h580c, 8'h08};
assign cfg_data_reg[079] = {16'h580d, 8'h03};
assign cfg_data_reg[080] = {16'h580e, 8'h00};
assign cfg_data_reg[081] = {16'h580f, 8'h00};
assign cfg_data_reg[082] = {16'h5810, 8'h03};
assign cfg_data_reg[083] = {16'h5811, 8'h09};
assign cfg_data_reg[084] = {16'h5812, 8'h07};
assign cfg_data_reg[085] = {16'h5813, 8'h03};
assign cfg_data_reg[086] = {16'h5814, 8'h00};
assign cfg_data_reg[087] = {16'h5815, 8'h01};
assign cfg_data_reg[088] = {16'h5816, 8'h03};
assign cfg_data_reg[089] = {16'h5817, 8'h08};
assign cfg_data_reg[090] = {16'h5818, 8'h0d};
assign cfg_data_reg[091] = {16'h5819, 8'h08};
assign cfg_data_reg[092] = {16'h581a, 8'h05};
assign cfg_data_reg[093] = {16'h581b, 8'h06};
assign cfg_data_reg[094] = {16'h581c, 8'h08};
assign cfg_data_reg[095] = {16'h581d, 8'h0e};
assign cfg_data_reg[096] = {16'h581e, 8'h29};
assign cfg_data_reg[097] = {16'h581f, 8'h17};
assign cfg_data_reg[098] = {16'h5820, 8'h11};
assign cfg_data_reg[099] = {16'h5821, 8'h11};
assign cfg_data_reg[100] = {16'h5822, 8'h15};
assign cfg_data_reg[101] = {16'h5823, 8'h28};
assign cfg_data_reg[102] = {16'h5824, 8'h46};
assign cfg_data_reg[103] = {16'h5825, 8'h26};
assign cfg_data_reg[104] = {16'h5826, 8'h08};
assign cfg_data_reg[105] = {16'h5827, 8'h26};
assign cfg_data_reg[106] = {16'h5828, 8'h64};
assign cfg_data_reg[107] = {16'h5829, 8'h26};
assign cfg_data_reg[108] = {16'h582a, 8'h24};
assign cfg_data_reg[109] = {16'h582b, 8'h22};
assign cfg_data_reg[110] = {16'h582c, 8'h24};
assign cfg_data_reg[111] = {16'h582d, 8'h24};
assign cfg_data_reg[112] = {16'h582e, 8'h06};
assign cfg_data_reg[113] = {16'h582f, 8'h22};
assign cfg_data_reg[114] = {16'h5830, 8'h40};
assign cfg_data_reg[115] = {16'h5831, 8'h42};
assign cfg_data_reg[116] = {16'h5832, 8'h24};
assign cfg_data_reg[117] = {16'h5833, 8'h26};
assign cfg_data_reg[118] = {16'h5834, 8'h24};
assign cfg_data_reg[119] = {16'h5835, 8'h22};
assign cfg_data_reg[120] = {16'h5836, 8'h22};
assign cfg_data_reg[121] = {16'h5837, 8'h26};
assign cfg_data_reg[122] = {16'h5838, 8'h44};
assign cfg_data_reg[123] = {16'h5839, 8'h24};
assign cfg_data_reg[124] = {16'h583a, 8'h26};
assign cfg_data_reg[125] = {16'h583b, 8'h28};
assign cfg_data_reg[126] = {16'h583c, 8'h42};
assign cfg_data_reg[127] = {16'h583d, 8'hce};
assign cfg_data_reg[128] = {16'h5180, 8'hff};
assign cfg_data_reg[129] = {16'h5181, 8'hf2};
assign cfg_data_reg[130] = {16'h5182, 8'h00};
assign cfg_data_reg[131] = {16'h5183, 8'h14};
assign cfg_data_reg[132] = {16'h5184, 8'h25};
assign cfg_data_reg[133] = {16'h5185, 8'h24};
assign cfg_data_reg[134] = {16'h5186, 8'h09};
assign cfg_data_reg[135] = {16'h5187, 8'h09};
assign cfg_data_reg[136] = {16'h5188, 8'h09};
assign cfg_data_reg[137] = {16'h5189, 8'h75};
assign cfg_data_reg[138] = {16'h518a, 8'h54};
assign cfg_data_reg[139] = {16'h518b, 8'he0};
assign cfg_data_reg[140] = {16'h518c, 8'hb2};
assign cfg_data_reg[141] = {16'h518d, 8'h42};
assign cfg_data_reg[142] = {16'h518e, 8'h3d};
assign cfg_data_reg[143] = {16'h518f, 8'h56};
assign cfg_data_reg[144] = {16'h5190, 8'h46};
assign cfg_data_reg[145] = {16'h5191, 8'hf8};
assign cfg_data_reg[146] = {16'h5192, 8'h04};
assign cfg_data_reg[147] = {16'h5193, 8'h70};
assign cfg_data_reg[148] = {16'h5194, 8'hf0};
assign cfg_data_reg[149] = {16'h5195, 8'hf0};
assign cfg_data_reg[150] = {16'h5196, 8'h03};
assign cfg_data_reg[151] = {16'h5197, 8'h01};
assign cfg_data_reg[152] = {16'h5198, 8'h04};
assign cfg_data_reg[153] = {16'h5199, 8'h12};
assign cfg_data_reg[154] = {16'h519a, 8'h04};
assign cfg_data_reg[155] = {16'h519b, 8'h00};
assign cfg_data_reg[156] = {16'h519c, 8'h06};
assign cfg_data_reg[157] = {16'h519d, 8'h82};
assign cfg_data_reg[158] = {16'h519e, 8'h38};
assign cfg_data_reg[159] = {16'h5480, 8'h01};
assign cfg_data_reg[160] = {16'h5481, 8'h08};
assign cfg_data_reg[161] = {16'h5482, 8'h14};
assign cfg_data_reg[162] = {16'h5483, 8'h28};
assign cfg_data_reg[163] = {16'h5484, 8'h51};
assign cfg_data_reg[164] = {16'h5485, 8'h65};
assign cfg_data_reg[165] = {16'h5486, 8'h71};
assign cfg_data_reg[166] = {16'h5487, 8'h7d};
assign cfg_data_reg[167] = {16'h5488, 8'h87};
assign cfg_data_reg[168] = {16'h5489, 8'h91};
assign cfg_data_reg[169] = {16'h548a, 8'h9a};
assign cfg_data_reg[170] = {16'h548b, 8'haa};
assign cfg_data_reg[171] = {16'h548c, 8'hb8};
assign cfg_data_reg[172] = {16'h548d, 8'hcd};
assign cfg_data_reg[173] = {16'h548e, 8'hdd};
assign cfg_data_reg[174] = {16'h548f, 8'hea};
assign cfg_data_reg[175] = {16'h5490, 8'h1d};
assign cfg_data_reg[176] = {16'h5381, 8'h1e};
assign cfg_data_reg[177] = {16'h5382, 8'h5b};
assign cfg_data_reg[178] = {16'h5383, 8'h08};
assign cfg_data_reg[179] = {16'h5384, 8'h0a};
assign cfg_data_reg[180] = {16'h5385, 8'h7e};
assign cfg_data_reg[181] = {16'h5386, 8'h88};
assign cfg_data_reg[182] = {16'h5387, 8'h7c};
assign cfg_data_reg[183] = {16'h5388, 8'h6c};
assign cfg_data_reg[184] = {16'h5389, 8'h10};
assign cfg_data_reg[185] = {16'h538a, 8'h01};
assign cfg_data_reg[186] = {16'h538b, 8'h98};
assign cfg_data_reg[187] = {16'h5580, 8'h06};
assign cfg_data_reg[188] = {16'h5583, 8'h40};
assign cfg_data_reg[189] = {16'h5584, 8'h10};
assign cfg_data_reg[190] = {16'h5589, 8'h10};
assign cfg_data_reg[191] = {16'h558a, 8'h00};
assign cfg_data_reg[192] = {16'h558b, 8'hf8};
assign cfg_data_reg[193] = {16'h501d, 8'h40};
assign cfg_data_reg[194] = {16'h5300, 8'h08};
assign cfg_data_reg[195] = {16'h5301, 8'h30};
assign cfg_data_reg[196] = {16'h5302, 8'h10};
assign cfg_data_reg[197] = {16'h5303, 8'h00};
assign cfg_data_reg[198] = {16'h5304, 8'h08};
assign cfg_data_reg[199] = {16'h5305, 8'h30};
assign cfg_data_reg[200] = {16'h5306, 8'h08};
assign cfg_data_reg[201] = {16'h5307, 8'h16};
assign cfg_data_reg[202] = {16'h5309, 8'h08};
assign cfg_data_reg[203] = {16'h530a, 8'h30};
assign cfg_data_reg[204] = {16'h530b, 8'h04};
assign cfg_data_reg[205] = {16'h530c, 8'h06};
assign cfg_data_reg[206] = {16'h5025, 8'h00};
assign cfg_data_reg[207] = {16'h3008, 8'h02};
assign cfg_data_reg[208] = {16'h3035, 8'h11};
assign cfg_data_reg[209] = {16'h3036, 8'h46};
assign cfg_data_reg[210] = {16'h3c07, 8'h08};
assign cfg_data_reg[211] = {16'h3820, 8'h47};
assign cfg_data_reg[212] = {16'h3821, 8'h07};
assign cfg_data_reg[213] = {16'h3814, 8'h31};
assign cfg_data_reg[214] = {16'h3815, 8'h31};
assign cfg_data_reg[215] = {16'h3800, 8'h00};
assign cfg_data_reg[216] = {16'h3801, 8'h00};
assign cfg_data_reg[217] = {16'h3802, 8'h00};
assign cfg_data_reg[218] = {16'h3803, 8'hfa};//Y起始地址
assign cfg_data_reg[219] = {16'h3804, 8'h0a};
assign cfg_data_reg[220] = {16'h3805, 8'h3f};
assign cfg_data_reg[221] = {16'h3806, 8'h06};//Y结束地址
assign cfg_data_reg[222] = {16'h3807, 8'ha9};
assign cfg_data_reg[223] = {16'h3808, 8'h03};//水平输出宽度
assign cfg_data_reg[224] = {16'h3809, 8'h20};
assign cfg_data_reg[225] = {16'h380a, 8'h01};//垂直输出宽度
assign cfg_data_reg[226] = {16'h380b, 8'he0};
assign cfg_data_reg[227] = {16'h380c, 8'h07};//总水平大小
assign cfg_data_reg[228] = {16'h380d, 8'h64};
assign cfg_data_reg[229] = {16'h380e, 8'h02};//总垂直大小
assign cfg_data_reg[230] = {16'h380f, 8'he4};
assign cfg_data_reg[231] = {16'h3813, 8'h04};//垂直偏移
assign cfg_data_reg[232] = {16'h3618, 8'h00};
assign cfg_data_reg[233] = {16'h3612, 8'h29};
assign cfg_data_reg[234] = {16'h3709, 8'h52};
assign cfg_data_reg[235] = {16'h370c, 8'h03};
assign cfg_data_reg[236] = {16'h3a02, 8'h17};
assign cfg_data_reg[237] = {16'h3a03, 8'h10};
assign cfg_data_reg[238] = {16'h3a14, 8'h17};
assign cfg_data_reg[239] = {16'h3a15, 8'h10};
assign cfg_data_reg[240] = {16'h4004, 8'h02};
assign cfg_data_reg[241] = {16'h3002, 8'h1c};
assign cfg_data_reg[242] = {16'h3006, 8'hc3};
assign cfg_data_reg[243] = {16'h4713, 8'h03};
assign cfg_data_reg[244] = {16'h4407, 8'h04};
assign cfg_data_reg[245] = {16'h460b, 8'h35};
assign cfg_data_reg[246] = {16'h460c, 8'h22};
assign cfg_data_reg[247] = {16'h4837, 8'h22};
assign cfg_data_reg[248] = {16'h3824, 8'h02};
assign cfg_data_reg[249] = {16'h5001, 8'ha3};
assign cfg_data_reg[250] = {16'h3503, 8'h00};
endmodule

module OV5640_Top
(
input wire sys_clk,
input wire rst,
inout wire sda,
output wire scl,
output wire pwdn,
output wire resetb,
output wire [9:0] statue_WR,
output wire [12:0] statue_RD
);
reg read_en;
wire [15:0] addr;
wire read_end;
wire sccb_en;
wire clk_en;
wire start;
wire [7:0] Data_reg;
wire [23:0] cfg_data;
wire init_end;
wire write_end;
wire WR_en;
wire scl_rd;
wire scl_wr;
wire sda_rd;
wire sda_wr;
reg number;
/*
wire [9:0] statue_WR;
wire [12:0] statue_RD;
*/
wire [7:0] ID = 8'h3C;
wire [15:0] rd_add = 16'h3808;
wire [23:0] Cmd;
assign start = (sccb_en == 1'd1 && clk_en == 1'd1)?1'd1:1'd0;
assign sda = (init_end == 1'd1)?((statue_RD == 13'b0_0000_0000_0100
|| statue_RD == 13'b0_0000_0001_0000
|| statue_RD == 13'b0_0000_0100_0000
|| statue_RD == 13'b0_0010_0000_0000
|| statue_RD == 13'b0_0100_0000_0000)?1'dz:sda_rd)
:sda_wr;
assign scl = (init_end == 1'd1)?scl_rd:scl_wr;
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
number <= 1'd1;
else if(number == 1'd1 && read_end == 1'd1 && init_end == 1'd1)
number <= 1'd0;
always@(posedge sys_clk or negedge rst)
if(rst == 1'd0)
read_en <= 1'd0;
else if(read_end == 1'd1)
read_en <= 1'd0;
else if(init_end == 1'd1 && number == 1'd1)
read_en <= 1'd1;
Power_ctrl
#(
.CNT_5MS(20'd250_000),
.CNT_1MS(20'd50_000),
.CNT_20MS(20'd1000_000)
)
Power_ctrl_inst
(
.sys_clk(sys_clk),
.rst(rst),
.pwdn(pwdn),
.resetb(resetb),
.sccb_en(sccb_en),
.clk_en(clk_en)
);
OV5640_cfg OV5640_cfg_inst
(
.sys_clk(sys_clk),
.rst(rst),
.start(start),
.write_end(write_end),
.cfg_data(cfg_data),
.WR_en(WR_en),
.init_end(init_end)
);
SSCB_WR SSCB_WR_inst
(
.sys_clk(sys_clk),
.rst(rst),
.WR_en(WR_en),
.addr(cfg_data[23:8]),
.ID(ID),
.data(cfg_data[7:0]),
.sda(sda_wr),
.scl(scl_wr),
.WR_end(write_end),
.statue(statue_WR)
);
SSCB_ID SSCB_ID_inst
(
.sys_clk(sys_clk),
.rst(rst),
.read_en(read_en),
.addr(rd_add),
.ID(ID),
.sda_rd(sda),
.sda(sda_rd),
.scl(scl_rd),
.read_end(read_end),
.Data_reg(Data_reg),
.statue(statue_RD),
.Cmd(Cmd)
);
endmodule

该测试是将刚才写于的寄存器数据读出来判断是否一致(该寄存器地址为16‘h3808)
<1>inout只能用wire来赋值
<2>inout在赋值时,要使用三态逻辑门来赋值(也有其他的方法,但最好还是用这个),且赋值的内容必须包含高阻态。
<3>尽量不要在底层使用inout,不然会有一些警告。
<4>底层不要数据赋值为z
<5>规范使用inout,不然可能导致电路短路
以上几点,如果不遵循,可能编译通过了,但生成的电路会不满足你的设计要求。
数据输出时序:

按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道rubyonrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n
我想要像“嘿那里”这样的东西变成,例如,#316583。我希望将任意长度的字符串“归结”为十六进制颜色。我不知道从哪里开始。我在想,每个字符串的MD5散列都是不同的-但如何将该散列转换为十六进制颜色数字? 最佳答案 你可以只取几位前几位:require'digest/md5'color=Digest::MD5.hexdigest('Mytext')[0..5] 关于ruby-如何使用Ruby基于字母数字字符串生成颜色?,我们在StackOverflow上找到一个类似的问题:
文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3
我使用的是最新版本的Chrome(32.0.1700.107)和Chrome驱动程序(V2.8)。但是当我在Ruby中使用以下代码运行示例测试时:require'selenium-webdriver'WAIT=Selenium::WebDriver::Wait.new(timeout:100)$driver=Selenium::WebDriver.for:chrome$driver.manage.window.maximize$driver.navigate.to'https://www.google.co.in'defapps_hoverele_hover=$driver.find_