当前位置:   article > 正文

ZYNQ图像处理_帧差法运动目标检测实现(开源)_zynq图像处理帧间差分法

zynq图像处理帧间差分法

实验的基本原理

所谓帧差法,就是比较相邻两帧图像的像素数据有没有差异,并对差异的大小做一个规定阈值,若超出规定阈值,即判定有运动物体经过,并且通过算法绘制矩形框对运动物体进行标定,借此来实现运动目标的检测,该实验缺点就是只能对单个目标进行框定。

实验的总体框图

帧差法运动目标检测模块框图

BD设计图

在这里插入图片描述

实验的重点部分

整个实验大致包含如下几个注意点:

1、选取单个分量进行前一帧与当前帧的差异比较,在本实验中选取的是Y分量(亮度分量)进行比较,因此需要对传输的RGB数据做RGB转YCbCr的转换,这一块在我的另一篇文章《FPGA图像处理_色彩空间转换(含源码)》中讲到过,只不过那一篇里是用vsync和hsync作为同步信号,而在这一篇里是用AXI4-Stream的tuser信号作为同步信号,稍作修改即可,至于为什么可以用tuser信号作为同步信号,可以去查看我的另一篇文章《【ZYNQ】IP核_关于视频IP核的详细介绍》有讲到。

2、帧差法运动目标检测模块是以自定义IP核的形式添加打到摄像头+LCD屏幕显示的实验中,这样简化了操作,关于如何封装自定义IP核,在我的另一篇文章《【ZYNQ】自定义IP核的封装》有讲到。

3、时序问题,做这个实验的关键就是一定要注意延时的问题,既然是做图像的差异对比,那么对比的对象一定要一致,比如通过FIFO对前一帧数据进行缓冲,当当前帧的第一个像素到来时,读取前一帧图像的第一个像素数据,这样就保证了二者的一致性。

4、检测边框该如何绘制,这个只能通过代码去琢磨其中奥妙,代码我就放这:

`timescale 1ns / 1ps

module ip_movings(
//    input   clk                         ,
//    input   rst_n                       ,
    
    //AXI4_Stream Slave接口0,来自摄像头,获取当前帧数据
    input               s0_axis_aclk    ,
    input               s0_axis_aresetn ,
    input [23:0]        s0_axis_tdata   ,
    input               s0_axis_tvalid  ,
    output              s0_axis_tready  ,
    input               s0_axis_tuser   ,   //tuser == start of frame(SOF) 
    input               s0_axis_tlast   ,   //tlast == end of line(EOL)
    
     //AXI4_Stream Slave接口1,来自VDMA_0,获取前一帧数据
    input               s1_axis_aclk    ,
    input               s1_axis_aresetn ,
    input [23:0]        s1_axis_tdata   ,
    input               s1_axis_tvalid  ,
    output              s1_axis_tready  ,
    input               s1_axis_tuser   ,
    input               s1_axis_tlast   ,
    
    //AXIS4_Stream Master接口,输出到VDMA_1
    input               m_axis_aclk    ,
    input               m_axis_aresetn ,
    output  reg[23:0]   m_axis_tdata    ,
    output  reg         m_axis_tvalid   ,
    input               m_axis_tready   ,
    output  reg         m_axis_tuser    ,
    output  reg         m_axis_tlast    

    );
    
localparam  [7:0]   Diff_Threshold    =   8'd100;   //帧差阈值
localparam  [10:0]  IMG_HDISP         =   11'd1920; //图像分辨率
localparam  [10:0]  IMG_VDISP         =   11'd1080;
    
//*************************************************************************
//将VDMA的图像保存到FIFO中

reg [23:0]  fifo_data   ;
reg         fifo_wr     ;
reg         fifo_wr_en  ;
wire        fifo_full   ;

reg         fifo_rd     ;
reg         fifo_rd_en  ;
wire [23:0] fifo_q      ;

//FIFO不满时,持续从VDMA读取data
assign  s1_axis_tready = ~fifo_full; 

//写状态机
localparam W_IDLE = 2'b01   ;
localparam W_FIFO = 2'b10   ;
reg [1:0] write_state       ;
reg [1:0] next_write_state  ;
reg [3:0]   wcnt            ;

always @ (posedge s1_axis_aclk or negedge s1_axis_aresetn) begin
    if(!s1_axis_aresetn) 
        write_state <=  W_IDLE              ;
    else
        write_state <=  next_write_state    ;
end

always @ (*) begin
    case(write_state)
        W_IDLE: begin
            if(wcnt == 4'd8)
                next_write_state    <=  W_FIFO;
            else
                next_write_state    <=  W_IDLE;
        end
        
        W_FIFO:
            next_write_state    <=  W_FIFO;
        
        default:
            next_write_state    <=  W_IDLE;
     endcase
end

always @ (posedge s1_axis_aclk or negedge s1_axis_aresetn) begin
    if(!s1_axis_aresetn)
        wcnt    <=  4'd0    ;
    else if(write_state ==  W_IDLE)
        wcnt    <=  wcnt + 1'b1;
    else
        wcnt    <=  4'd0    ;
end
   
always @ (posedge s1_axis_aclk or negedge s1_axis_aresetn)begin
    if(!s1_axis_aresetn) begin
        fifo_wr_en  <=  1'b0    ;
        fifo_wr     <=  1'b0    ;
        fifo_data   <=  24'b0   ;      
    end
    else begin
        if(write_state ==  W_FIFO) begin
            //检测到SOF(tuser)信号拉高后才打开写FIFO使能,保证FIFO中写入的第一个数据为SOF
            if(s1_axis_tvalid & s1_axis_tready & s1_axis_tuser) 
                fifo_wr_en  <=  1'b1            ;   //确保前一帧的数据第一个像素点与当前帧的第一个像素点数据对齐
            if(s1_axis_tvalid & s1_axis_tready) begin
                fifo_wr     <=  1'b1            ;
                fifo_data   <=  s1_axis_tdata   ;
            end
            else begin
                fifo_wr     <=  1'b0            ;
                fifo_data   <=  fifo_data       ;
            end
        end
        else begin
            fifo_wr_en  <=  1'b0        ;
            fifo_wr     <=  1'b0        ;
            fifo_data   <=  fifo_data   ;
        end
    end
end

fifo_generator_0 fifo_generator_inst (
  .clk(s1_axis_aclk),                  // input wire clk
  .rst(~s1_axis_aresetn),                  // input wire rst
  .din(fifo_data),                  // input wire [23 : 0] din
  .wr_en(fifo_wr_en & fifo_wr),              // input wire wr_en
  .rd_en(fifo_rd_en & fifo_rd),              // input wire rd_en
  .dout(fifo_q),                // output wire [23 : 0] dout
  .full(),                // output wire full
  .almost_full(fifo_full),  // output wire almost_full
  .empty()              // output wire empty
);

//读状态机
reg [1:0]   read_state          ;
reg [1:0]   next_read_state     ;
reg [3:0]   rcnt                ;
localparam  R_IDLE   =   2'b01  ;
localparam  R_FIFO   =   2'b10  ;

always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn)
        read_state <=  R_IDLE              ;
    else 
        read_state <=  next_read_state    ;
end

always @(*) begin
    case(read_state)
        R_IDLE: begin
            if(rcnt == 8'd8)
                next_read_state    <=  R_FIFO;
            else
                next_read_state    <=  R_IDLE;
        end
        
        R_FIFO: 
            next_read_state    <=  R_FIFO; //一直处于读的状态
        default:  
            next_read_state    <=  R_IDLE;    
    endcase
end

always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn)
        rcnt    <=  4'd0    ;
    else if(read_state == R_IDLE)
        rcnt    <=  rcnt+ 1'b1;
    else
        rcnt    <=  4'd0    ;
end

//************************************************************************
//摄像头输入像素的同时,从FIFO中读出VDMA像素,以进行运算
//需要注意的是FIFO的read mode有两种模式:Standard FIFO,数据会落后于读信号一个周期;还有一种是FWFT模式,预先取出一个数据,读信号有效时,相应的数据也有效
always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        fifo_rd_en  <=  1'b0   ;
        fifo_rd     <=  1'b0   ;  
    end
    else begin
        if(read_state == R_FIFO) begin
            //等待FIFO中缓存一定量的数据之后,检测摄像头输入SOF之后才打开读FIFO使能,使得与FIFO中读取的VDMA视频数据同步
            if(s0_axis_tvalid & s0_axis_tready & s0_axis_tuser & fifo_full)
                fifo_rd_en  <=  1'b1    ;   
            //此处FIFO读信号相对于摄像头输入视频延迟了一个时钟周期
            if(s0_axis_tvalid & s0_axis_tready) //当握手信号在上升沿完成时,当前帧的数据开始传输,而FIFO的读使能落后一个时钟,数据读出来又落后读使能一个时钟,所以
                fifo_rd     <=  1'b1    ;       //前一帧的数据落后于当前帧2个时钟周期
            else
                fifo_rd     <=  1'b0    ;
        end
        else begin
            fifo_rd_en  <=  1'b0   ;
            fifo_rd     <=  1'b0   ;
        end
   end
end

//*******************************************消耗掉两个时钟周期
//为了与FIFO钟读出的数据同步,将摄像头输入视频也延迟两个时钟周期(简单通过两个寄存器级联)
reg [23:0]  s0_axis_tdata_delay1;
reg [23:0]  s0_axis_tdata_delay2;

always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        s0_axis_tdata_delay1    <=  24'd0   ;
        s0_axis_tdata_delay2    <=  24'd0   ;
    end
    else begin
        s0_axis_tdata_delay1    <=  s0_axis_tdata           ;
        s0_axis_tdata_delay2    <=  s0_axis_tdata_delay1    ;
    end   
end

//*******************************************消耗掉三个时钟周期
//将RGB格式数据转化成YCbCr数据,但是只取Y分量,因此是灰度图像
wire    [7:0]   s0_img_y    ;//来自摄像头
wire    [7:0]   s1_img_y    ;//来自VDMA
rgb_ycbcr   s0_rgb_ycbcr(
     .clk(s0_axis_aclk)                                  ,
     .rst_n(s0_axis_aresetn)                              ,
     .in_img_red(s0_axis_tdata_delay2[23:16])   ,
     .in_img_green(s0_axis_tdata_delay2[15:8])  ,
     .in_img_blue(s0_axis_tdata_delay2[7:0])    ,
     .out_img_Y(s0_img_y)                       ,
     .out_img_Cb()                              ,
     .out_img_Cr()
    );
    
rgb_ycbcr   s1_rgb_ycbcr(
     .clk(s1_axis_aclk)                                  ,
     .rst_n(s1_axis_aresetn)                              ,
     .in_img_red(fifo_q[23:16])                 ,
     .in_img_green(fifo_q[15:8])                ,
     .in_img_blue(fifo_q[7:0])                  ,
     .out_img_Y(s1_img_y)                       ,
     .out_img_Cb()                              ,
     .out_img_Cr()
    );

//******************************************消耗一个时钟周期
//帧差运算
//帧差标志位,为1表示两帧数据差别超过阈值
reg frame_difference_flag   ;

always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        frame_difference_flag   <=  1'b0    ;
    end
    else begin
        if(s0_img_y > s1_img_y) begin
            if(s0_img_y - s1_img_y  > Diff_Threshold)   //灰度大于阈值
                frame_difference_flag   <=  1'b1    ;
            else
                frame_difference_flag   <=  1'b0    ;
        end
        else begin
            if(s1_img_y - s0_img_y  > Diff_Threshold)   //灰度大于阈值
                frame_difference_flag   <=  1'b1    ;
            else
                frame_difference_flag   <=  1'b0    ;
        end
    end
end

//*****************************************************延迟六个时钟周期
//将摄像头的输入的同步信号延迟六个时钟周期,与数据同步

wire    s0_axis_tuser_dly       ;
wire    s0_axis_tlast_dly       ;
wire    s0_axis_tvalid_dly      ;

reg [5:0]   s0_axis_tuser_reg   ;
reg [5:0]   s0_axis_tlast_reg   ;
reg [5:0]   s0_axis_tvalid_reg  ;

always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        s0_axis_tuser_reg   <=  6'd0    ;
        s0_axis_tlast_reg   <=  6'd0    ;
        s0_axis_tvalid_reg  <=  6'd0    ;    
    end
    else begin
        s0_axis_tuser_reg   <=  {s0_axis_tuser_reg[4:0],s0_axis_tvalid  &   s0_axis_tready  &   s0_axis_tuser};
        s0_axis_tlast_reg   <=  {s0_axis_tlast_reg[4:0],s0_axis_tvalid  &   s0_axis_tready  &   s0_axis_tlast};
        s0_axis_tvalid_reg  <=  {s0_axis_tvalid_reg[4:0],s0_axis_tvalid  &   s0_axis_tready}                  ;
    end
end

assign  s0_axis_tuser_dly   =   s0_axis_tuser_reg[5] ;
assign  s0_axis_tlast_dly   =   s0_axis_tlast_reg[5] ;
assign  s0_axis_tvalid_dly  =   s0_axis_tvalid_reg[5];

//*****************************************************************
//计算帧差后的像素坐标
reg [10:0]   x_cnt;
reg [10:0]   y_cnt;

always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        x_cnt   <=  11'd0   ;
        y_cnt   <=  11'd0   ;
    end
    else if(s0_axis_tvalid_dly) begin
        if(s0_axis_tlast_dly) begin
            x_cnt   <=  11'd0   ;
            y_cnt   <=  y_cnt+1'b1;
        end
        else if(s0_axis_tuser_dly) begin
            x_cnt   <=  11'd0;
            y_cnt   <=  11'd0;
        end
        else begin
            x_cnt   <=  x_cnt   +   1'b1;
        end
    end
end

//******************************************************
//求出运动目标的最大矩形边框
/**********************
                       down_reg
起始点 -》-----------------------------------
          \                                  \
          \                                  \
          \                                  \
right_reg \                                  \    left_reg
          \                                  \
          \                                  \
          ------------------------------------
                       up_reg
**********************/
reg [10:0]  up_reg  ;
reg [10:0]  down_reg;
reg [10:0]  left_reg;
reg [10:0]  right_reg;
reg         flag_reg;

always @(posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        up_reg  <=  IMG_VDISP;
        down_reg<=  11'd0    ;
        left_reg<=  IMG_HDISP;
        right_reg<= 11'd0    ;
    end
    else if(s0_axis_tuser_dly) begin
        up_reg  <=  IMG_VDISP;
        down_reg<=  11'd0    ;
        left_reg<=  IMG_HDISP;
        right_reg<= 11'd0    ;
    end
    else if(s0_axis_tvalid_dly & frame_difference_flag) begin
        flag_reg    <=  1'b1        ;
        
        if(x_cnt<left_reg)
            left_reg<=  x_cnt       ;
        else
            left_reg<=  left_reg    ;
            
        if(x_cnt>right_reg)
            right_reg<=  x_cnt      ;
        else
            right_reg<=  right_reg  ;  
            
        if(y_cnt<up_reg)
            up_reg  <=  y_cnt       ;
        else
            up_reg  <=  up_reg      ;
            
        if(y_cnt>down_reg) 
            down_reg <= y_cnt       ;
        else
            down_reg <= down_reg    ;
    end
end

reg [10:0]  rectangular_up      ;
reg [10:0]  rectangular_down    ;
reg [10:0]  rectangular_left    ;
reg [10:0]  rectangular_right   ;
reg         rectangular_flag    ;

always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        rectangular_up  <=  11'd0   ;
        rectangular_down<=  11'd0   ;
        rectangular_left<=  11'd0   ;
        rectangular_right<= 11'd0   ;
        rectangular_flag <= 1'b0    ;
    end
    else if((x_cnt == IMG_HDISP-1) && (y_cnt == IMG_VDISP-1)) begin
        rectangular_up  <=  up_reg  ;
        rectangular_down<=  down_reg;
        rectangular_left<=  left_reg;
        rectangular_right<= right_reg;
        rectangular_flag <= flag_reg;
    end
end

//**********************************************************
//绘制矩形框

//计算摄像头输入图像的像素坐标
reg [10:0]  s0_x_cnt;
reg [10:0]  s0_y_cnt;

always @ (posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        s0_x_cnt    <=  11'd0   ;
        s0_y_cnt    <=  11'd0   ;
    end
    else if(s0_axis_tvalid) begin
        if(s0_axis_tlast) begin
            s0_x_cnt    <=  11'd0       ;
            s0_y_cnt    <=  y_cnt+1'b1  ;
        end
        else if(s0_axis_tuser) begin
            s0_x_cnt    <=  11'd0       ;
            s0_y_cnt    <=  11'd0       ;
        end
        else begin
            s0_x_cnt    <=  s0_x_cnt +   1'b1;
        end    
    end
end


reg boarder_flag;   //标志着像素点位于方框上

always @(posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        boarder_flag    <=  1'b0   ;    
    end
    else begin
        if(rectangular_flag) begin   //检测到运动目标
            if((s0_x_cnt>rectangular_left) && (s0_x_cnt<rectangular_right) && ((s0_y_cnt == rectangular_up) || (s0_y_cnt == rectangular_down))) begin
                boarder_flag    <=  1'b1   ;
            end
            else if((s0_y_cnt>rectangular_up) && (s0_y_cnt<rectangular_down) && ((s0_x_cnt == rectangular_left) || (s0_x_cnt == rectangular_right))) begin
                boarder_flag    <=  1'b1   ;
            end
            else begin
                boarder_flag    <=  1'b0   ;
            end
        end
        else begin
            boarder_flag    <=  1'b0   ;
        end
     end
end

//输出给摄像头输入的Ready信号
assign s0_axis_tready = m_axis_tready;

//给AXI4_Stream Master接口赋值
always @(posedge s0_axis_aclk or negedge s0_axis_aresetn) begin
    if(!s0_axis_aresetn) begin
        m_axis_tvalid   <=  1'd0    ;
        m_axis_tuser    <=  1'd0    ;
        m_axis_tlast    <=  1'd0    ;
        m_axis_tdata    <=  24'd0   ;
     end
     else begin
        m_axis_tvalid   <=  s0_axis_tvalid    ;
        m_axis_tuser    <=  s0_axis_tuser    ;
        m_axis_tlast    <=  s0_axis_tlast    ;
        m_axis_tdata    <=  boarder_flag ? 24'hff_00_00: s0_axis_tdata   ;
     end
end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472

实验的结果展示

整个实验是参照的B站视频博主大磊FPGA的视频,这里就不放链接了,感兴趣的同学去B站搜一下。 最后我把整个工程打包发给大家,仅供参考。 链接:https://pan.baidu.com/s/1ZI18ad8un_Jua4rZIf_W9g 提取码:cduy
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/739196
推荐阅读
相关标签
  

闽ICP备14008679号