FPGA学习之---串口+ram ip核存储数据

算是对前几天学的做了一个复习,利用串口收发模块和ram ip核进行了一个简易收发显示。资源已经上传有需要自取。

实验中遇到问题:1:创建的simple ram 双端口只有一个写请求信号,可以控制是否写入,但是会一直读出数据,ram ip配置界面没找到读请求控制信号,所以就算写入一些数据,最终会一直重复读取存储的数据。

                               2:wea信号不用一直触发,写一个数据时触发一次就好了

                                3:使用vivado+vscdoe时,如果还有文件在vscode打开,仿真和综合时会提示

必须关掉vscode才能继续。

                                4:小梅哥的crtl模块对tx_done进行了三个延时,因为ram读出数据加了两个寄存器,有3个周期延时,才能正确控制uart_tx模块的send_en信号,但是我没看他写的uart_tx模块,自己写的时候是要求一直触发send_en才能进行发送,所以不需要考虑tx_done延时,只需要发送状态为发送数据时即有按键输入时就触发,这比他的简单多了。

仿真时模拟串口依次发送:5a 11 22 33 44 55 66 5a

总共8个字节,所以addra一直加到08,dina为接收到的data_rx数据进行存储,但是想要读出数据时,addrb一直增加到所有的数据都读完再循环,但是除了写入的数据都是00,addra和addrb都是7位宽,所以应该以128个数据为一次循环,如图doutb:

上板验证:波特率设置为115200,从串口调试助手依次发送15 16 17 18 19,最终成功循环接收数据,验证确实为128个数据为一组循环。

主模块代码:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/04/25 10:21:48
// Design Name: 
// Module Name: uart_ram
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_ram_t_r(
    clk,
    rst,
    uart_tx,
    uart_rx,
    key_in,
    led1,
    led2

    );
    input clk;
    input rst;
    input uart_rx;
    output uart_tx;
    input key_in;
    output led1;//Tx_done 显示
    output led2;//Rx_done显示
   
    //tx模块参数
    wire [7:0]Data_tx;
    wire Send_en;
    wire Tx_done;

    //rx模块参数
    wire [7:0]Data_rx;
    wire Rx_done;

    //uart_ram ip 参数
    wire [6:0]addra;
    //wire [7:0]data;
    wire wea;
    wire [6:0]addrb;

    //key_filter参数
    //wire key_out;

    //消除rst亚稳态
    reg rst_reg1;
    reg rst_reg2;

    assign led1=Tx_done;
    assign led2=Rx_done;

 always @(posedge clk or negedge rst) begin
        if(~rst)
            rst_reg1<=1'b0;
        else
            rst_reg1<=1'b1;
    end
    always @(posedge clk or negedge rst) begin
        if(~rst)
            rst_reg2<=1'b0;
        else
            rst_reg2<=rst_reg1;
    end

   




uart_tx uart_tx1(
    .clk(clk),
    .rst_n(rst_reg2),
    .Data(Data_tx),
    .Send_en(Send_en),
    .Baud_set(3'b100),
 
    .uart_tx(uart_tx),
    .Tx_done(Tx_done)
    );


uart_rx uart_rx1(
    .uart_rx(uart_rx),
    .clk(clk),
    .rst_n(rst_reg2),
 
    .Data_rx(Data_rx),
    .Rx_done(Rx_done)
    );


uart_ram uart_ram1(
  .clka(clk),
  .wea(wea),
  .addra(addra),
  .dina(Data_rx),
  .clkb(clk),
  .addrb(addrb),
  .doutb(Data_tx)
);
ctrl ctrl(
    .clk(clk),
    .rst_reg2(rst_reg2),
    .key(key_in),
    .Rx_done(Rx_done),
    .Tx_done(Tx_done),

    .Send_en(Send_en),
    .wea(wea),
    .addra(addra),
    .addrb(addrb)
);
endmodule

uart_tx模块:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/03/08 20:35:22
// Design Name: 
// Module Name: uart
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
 
 
module uart_tx(
    clk,
    rst_n,
    Data,
    Send_en,
    Baud_set,
 
    uart_tx,
    Tx_done
    );
 
    input clk;
    input rst_n;
    input [7:0]Data;
    input Send_en;
    input [2:0]Baud_set;
 
    output reg uart_tx;
    output reg Tx_done;
 
    reg [19:0] count;
    reg [19:0] BPS; //set Baud
    reg [3:0]bit_count;//比特计数器
    reg [7:0]Data_reg;//数据寄存器
 
    parameter START_BIT=1'b0;
    parameter STOP_BIT=1'b1;
 
    //串口是异步收发器,保证发送的数据在时钟到来前稳定,对输入数据寄存
    always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
            Data_reg<=8'd0;
        else if(Send_en==1'b1);
            Data_reg<=Data;
    end
    
    always@(posedge clk )
    begin
            case(Baud_set)
                3'b000: BPS<=20'd5207   ;// Baud 9600
                3'b001: BPS<=20'd2603   ;// Baud 19200
                3'b010: BPS<=20'd1301   ;// Baud 38400
                3'b011: BPS<=20'd867   ;// Baud 57600
                3'b100: BPS<=20'd433   ;// Baud 115200
            // 3'b101: BPS<=20'd434   ;// Baud 115200
                default:BPS<=20'd433;
            endcase
   
    end
    always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
            count<=20'd0;
        else if(count==BPS)//波特率计数器
            count<=20'd0;
        else
            count<=count+1'b1;
    end
 
    always @(posedge clk or negedge rst_n) 
    begin
        if(~rst_n)
            bit_count<=4'd0;
        else if(bit_count==4'd11)//8位数据传输完成,并且保证停止位至少保持一个周期
            bit_count<=4'd0;
        else if(count==BPS && Send_en==1'b1)
            bit_count<=bit_count+1'b1;
    end
    always @(posedge clk )
    begin
       case (bit_count)
            4'd1:   uart_tx<=1'b0;
            4'd2:   uart_tx<=Data[0];
            4'd3:   uart_tx<=Data[1];
            4'd4:   uart_tx<=Data[2];
            4'd5:   uart_tx<=Data[3];
            4'd6:   uart_tx<=Data[4];
            4'd7:   uart_tx<=Data[5];
            4'd8:   uart_tx<=Data[6];
            4'd9:   uart_tx<=Data[7];
            4'd10:  uart_tx<=1'b1;
            //4'd11:  uart_tx<=1'b1;
            default :uart_tx=1'b1;  
       endcase 
 
 
    end
 
    always @(posedge clk or negedge rst_n) 
    begin
        if(~rst_n)
            Tx_done<=1'b0;
        else if(bit_count==4'd11)
            Tx_done<=1'b1;
        else
            Tx_done<=1'b0;
    end
 
endmodule

uart_rx模块:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/03/12 16:07:50
// Design Name: 
// Module Name: uart_rx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
 
 
module uart_rx(
    uart_rx,
    clk,
    rst_n,
 
    Data_rx,
    Rx_done
    );
 
    input uart_rx;
    input clk;
    input rst_n;
 
    output reg [7:0]Data_rx;
    output reg Rx_done;
 
    
    localparam COUNT_115200=20'd433;    //对115200波特率计数
    localparam COUNT_14=5'd30;  //把一个比特位分割成14份,每一份间隔31个COUNT_115200
    reg [19:0] count_115200;
    reg [4:0]count_14;
 
    //对uart_rx两级打拍寄存用于信号同步
    reg uart_rx_sync1;
    reg uart_rx_sync2;
 
    //对同步后的信号uart_rx_sync2两级打拍寄存用于边缘判断
    reg uart_rx_reg1;
    reg uart_rx_reg2;
 
    //定义上升沿和下降沿标志信号
    wire posedge_uart_rx;
    wire negedge_uart_rx;
 
    //计数采样位置 当count_14每次加到26时,count_sample加一,算上起始位和停止位总共分为160份
    reg [7:0]count_sample;
 
    //存储6次采样结果 
    //reg [3:0]sample_bit;
    
    //计数采样次数里面1的个数,如果1大于4就取1   反之取0
    reg [3:0]number_start;
    reg [3:0]number_stop;
    reg [3:0]number_bit[7:0];
    
    //数据接收使能 在检测到下降沿时开始有效为1,Rx_done有效即接收完成时无效为0,其余时间为无效0
    reg Rx_en;
 
    //对接收到的数据bit数进行计数
    reg [3:0]bit_count;
    
    //先对接收信号存储
    //reg [7:0]Data;
 
 
    //定义采样时钟信号 在每个count_sample的只有一个时钟有效 从而每个采样点只采样一次
    reg sample_clk;
 
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        count_14<=5'd0;
      else if(Rx_en==1'b1)
      begin
       if(count_14==COUNT_14)
          count_14<=5'd0;
       else
          count_14<=count_14+1'b1;
      end
    end
 
    //约束采样时钟
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        sample_clk<=1'b0;
      else if(count_14==5'd10)
        sample_clk<=1'b1;
      else  
        sample_clk<=1'b0;
    end
 
    //将每个比特分成16份 从1计数到17 只采样6 7 8 9 10 11
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        count_sample<=8'd0;
      else if((count_sample==8'd139) && (count_14==COUNT_14))
        count_sample<=8'd0;
      else if((count_14==COUNT_14) && (Rx_en==1'b1))
        count_sample<=count_sample+1'b1; 
    end
/*
    //进行采样
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
      begin
        sample_bit<=4'd0;
        number_1<=4'd0;
      end
      else
      else if((count_sample==5'd6) && (count_14==count_14))
      begin
        sample_bit[0]<=uart_rx_sync2;
          if(uart_rx_sync2==1'b1)
            number_1<=number_1+1'b1;    //对采样值里面1进行计数
      end
      else if((count_sample==5'd7) && (count_14==count_14))
      begin
        sample_bit[1]<=uart_rx_sync2;
         if(uart_rx_sync2==1'b1)
            number_1<=number_1+1'b1;
      end
      else if((count_sample==5'd8) && (count_14==count_14))
      begin
        sample_bit[2]<=uart_rx_sync2;
         if(uart_rx_sync2==1'b1)
            number_1<=number_1+1'b1;
      end
      else if((count_sample==5'd9) && (count_14==count_14))
      begin
        sample_bit[3]<=uart_rx_sync2;
         if(uart_rx_sync2==1'b1)
            number_1<=number_1+1'b1;
      end
      else if((count_sample==5'd10) && (count_14==count_14))
      begin
        sample_bit[4]<=uart_rx_sync2;
         if(uart_rx_sync2==1'b1)
            number_1<=number_1+1'b1;
      end
      else if((count_sample==5'd11) && (count_14==count_14))
      begin
        sample_bit[5]<=uart_rx_sync2;
         if(uart_rx_sync2==1'b1)
            number_1<=number_1+1'b1;
      end
    end
 
    always @(posedge clk)
    begin
        if(count_sample==5'd11)
          if(number_1>=3)
    end
*/
    
    //对信号进行寄存两拍
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        begin
          uart_rx_sync1<=1'b0;
          uart_rx_sync2<=1'b0;
        end
      else
        begin
          uart_rx_sync1<=uart_rx;
          uart_rx_sync2<=uart_rx_sync1;
        end
    end
    //进行波特率计数
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        count_115200<=20'd0;
      else if(Rx_en==1'b1)
      begin
        if(count_115200==COUNT_115200)
          count_115200<=20'd0;
        else  
          count_115200<=count_115200+1'b1;
      end
    end
    //对稳定后的信号进行上升沿和下降沿判断
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        begin
          uart_rx_reg1<=1'b0;
          uart_rx_reg2<=1'b0;
        end
      else
        begin
          uart_rx_reg1<=uart_rx_sync2;
          uart_rx_reg2<=uart_rx_reg1;
        end
    end
    assign posedge_uart_rx=uart_rx_reg1 & !uart_rx_reg2;
    assign negedge_uart_rx=!uart_rx_reg1 & uart_rx_reg2;
    //对Rx_done进行限制
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        Rx_done<=1'b0;
      else if(bit_count==4'd10)
        Rx_done<=1'b1;
      else  
        Rx_done<=1'b0;
    end
    //对Rx_en限制
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        Rx_en<=1'b0;
      else if(negedge_uart_rx==1'b1)
        Rx_en<=1'b1;
      else if(Rx_done==1'b1)
        Rx_en<=1'b0;
    end
 
    //对接收到的比特数进行计数
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        bit_count<=4'd0;
      else if(bit_count==4'd10)
        bit_count<=4'b0;
      else if((count_115200==COUNT_115200) && (Rx_en==1'b1))
        bit_count<=bit_count+1'b1;
    end
    /*
    always@(*)
    begin
      case(bit_count)
        4'd1: Data[0]=uart_rx_sync2;
        4'd2: Data[1]=uart_rx_sync2;
        4'd3: Data[2]=uart_rx_sync2;
        4'd4: Data[3]=uart_rx_sync2;
        4'd5: Data[4]=uart_rx_sync2;
        4'd6: Data[5]=uart_rx_sync2;
        4'd7: Data[6]=uart_rx_sync2;
        4'd8: Data[7]=uart_rx_sync2;
        
      endcase
    end
  */
    always @(posedge sample_clk or negedge rst_n) 
    begin
      if(~rst_n)
        begin
          number_start<=4'd0;
          number_stop<=4'd0;
          number_bit[0]<=4'd0;
          number_bit[1]<=4'd0;
          number_bit[2]<=4'd0;
          number_bit[3]<=4'd0;
          number_bit[4]<=4'd0;
          number_bit[5]<=4'd0;
          number_bit[6]<=4'd0;
          number_bit[7]<=4'd0;
        end
      else if(Rx_en==1'b1)
        begin
          case (count_sample)
            8'd0:
            begin
            number_start<=4'd0;
            number_stop<=4'd0;
            number_bit[0]<=4'd0;
            number_bit[1]<=4'd0;
            number_bit[2]<=4'd0;
            number_bit[3]<=4'd0;
            number_bit[4]<=4'd0;
            number_bit[5]<=4'd0;
            number_bit[6]<=4'd0;
            number_bit[7]<=4'd0;
            end
            8'd4,8'd5,8'd6,8'd7,8'd8,8'd9:number_start<=number_start+uart_rx_sync2;
            8'd18,8'd19,8'd20,8'd21,8'd22,8'd23:number_bit[0]<=number_bit[0]+uart_rx_sync2;
            8'd32,8'd33,8'd34,8'd35,8'd36,8'd37:number_bit[1]<=number_bit[1]+uart_rx_sync2;
            8'd46,8'd47,8'd48,8'd49,8'd50,8'd51:number_bit[2]<=number_bit[2]+uart_rx_sync2;
            8'd60,8'd61,8'd62,8'd63,8'd64,8'd65:number_bit[3]<=number_bit[3]+uart_rx_sync2;
            8'd74,8'd75,8'd76,8'd77,8'd78,8'd79:number_bit[4]<=number_bit[4]+uart_rx_sync2;
            8'd88,8'd89,8'd90,8'd91,8'd92,8'd93:number_bit[5]<=number_bit[5]+uart_rx_sync2;
            8'd102,8'd103,8'd104,8'd105,8'd106,8'd107:number_bit[6]<=number_bit[6]+uart_rx_sync2;
            8'd116,8'd117,8'd118,8'd119,8'd120,8'd121:number_bit[7]<=number_bit[7]+uart_rx_sync2;
            8'd130,8'd131,8'd132,8'd133,8'd134,8'd135:number_stop<=number_stop+uart_rx_sync2;
            default : 
            begin
            number_start<=number_start;
            number_stop<=number_stop;
            number_bit[0]<=number_bit[0];
            number_bit[1]<=number_bit[1];
            number_bit[2]<=number_bit[2];
            number_bit[3]<=number_bit[3];
            number_bit[4]<=number_bit[4];
            number_bit[5]<=number_bit[5];
            number_bit[6]<=number_bit[6];
            number_bit[7]<=number_bit[7];
            end
          endcase
        end  
    end
    always@(posedge clk or negedge rst_n)
    begin
      if(~rst_n)
        Data_rx<=8'd0;
      else if(count_sample==8'd139)
        begin
          if((number_start<=8'd2) &&(number_stop>=8'd4))
            begin
              Data_rx[0]<=(number_bit[0]>=8'd4) ? 1'b1 : 1'b0;
              Data_rx[1]<=(number_bit[1]>=8'd4) ? 1'b1 : 1'b0;
              Data_rx[2]<=(number_bit[2]>=8'd4) ? 1'b1 : 1'b0;
              Data_rx[3]<=(number_bit[3]>=8'd4) ? 1'b1 : 1'b0;
              Data_rx[4]<=(number_bit[4]>=8'd4) ? 1'b1 : 1'b0;
              Data_rx[5]<=(number_bit[5]>=8'd4) ? 1'b1 : 1'b0;
              Data_rx[6]<=(number_bit[6]>=8'd4) ? 1'b1 : 1'b0;
              Data_rx[7]<=(number_bit[7]>=8'd4) ? 1'b1 : 1'b0;
            end
        end
    end
endmodule

/*
//这个也能用
module uart_rx(
    Clk,
    Reset_n,
    uart_rx,
    Rx_Done,
    Rx_Data
);

    input Clk;
    input Reset_n;
    input uart_rx;
    output reg Rx_Done;
    output reg[7:0]Rx_Data;
    
    parameter CLOCK_FREQ = 50_000_000;
    parameter BAUD = 115200;
    parameter MCNT_BAUD = CLOCK_FREQ / BAUD - 1;
    
    reg [7:0]r_Rx_Data;
    
    reg [29:0]baud_div_cnt;
    reg en_baud_cnt;
    reg [3:0]bit_cnt;
    
    wire w_Rx_Done;
    wire nedge_uart_rx;
    
    reg r_uart_rx;
    
    reg dff0_uart_rx,dff1_uart_rx;
//波特率计数器逻辑
   always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        baud_div_cnt <= 0;
    else if(en_baud_cnt)begin
        if(baud_div_cnt == MCNT_BAUD)
            baud_div_cnt <= 0;
        else
            baud_div_cnt <= baud_div_cnt + 1'd1;
    end
    else
        baud_div_cnt <= 0;
  
        
//UART 信号边沿检测逻辑
    always@(posedge Clk)
        dff0_uart_rx <= uart_rx;
        
    always@(posedge Clk)
        dff1_uart_rx <= dff0_uart_rx;     
           
    always@(posedge Clk)
        r_uart_rx <= dff1_uart_rx;
        
    assign nedge_uart_rx = (dff1_uart_rx == 0) && (r_uart_rx == 1);
        
//波特率计数器使能逻辑
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        en_baud_cnt <= 0;
    else if(nedge_uart_rx)
        en_baud_cnt <= 1;
    else if((baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 0) && (dff1_uart_rx == 1))
        en_baud_cnt <= 0;
    else if((baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 9))
        en_baud_cnt <= 0;


//位计数器逻辑
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)   
        bit_cnt <= 0;
    else if((bit_cnt == 9) && (baud_div_cnt == MCNT_BAUD/2))  
        bit_cnt <= 0;
    else if(baud_div_cnt == MCNT_BAUD)
        bit_cnt <= bit_cnt + 1'd1;

//位接收逻辑

    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        r_Rx_Data <= 8'd0;
    else if(baud_div_cnt == MCNT_BAUD/2)begin
        case(bit_cnt)
            1:r_Rx_Data[0] <= dff1_uart_rx;
            2:r_Rx_Data[1] <= dff1_uart_rx;
            3:r_Rx_Data[2] <= dff1_uart_rx;
            4:r_Rx_Data[3] <= dff1_uart_rx;
            5:r_Rx_Data[4] <= dff1_uart_rx;
            6:r_Rx_Data[5] <= dff1_uart_rx;
            7:r_Rx_Data[6] <= dff1_uart_rx;
            8:r_Rx_Data[7] <= dff1_uart_rx;
            default: r_Rx_Data <= r_Rx_Data;
        endcase     
    end

//接收完成标志信号
    assign w_Rx_Done = (baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 9);
    
     always@(posedge Clk)
        Rx_Done <= w_Rx_Done;

     always@(posedge Clk)
     if(w_Rx_Done)
        Rx_Data <= r_Rx_Data;
        
        
endmodule

*/



ctrl模块代码:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/04/25 15:04:58
// Design Name: 
// Module Name: ctrl
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module ctrl(
    clk,
    rst_reg2,
    key,
    Rx_done,
    Tx_done,

    Send_en,
    wea,
    addra,
    addrb
    );

     input clk;
     input rst_reg2;
     input key;
     input Rx_done;
     input Tx_done;

     output reg Send_en;
     output wea;
     output reg [6:0]addra;
     output reg [6:0]addrb;


    //定义一个发送状态,用key来控制
    reg send_state;

    //按下按键,send_state=1 为读操作,当按下按键后连续读,再次按下按键停止读
    always @(posedge clk or negedge rst_reg2) begin
        if(~rst_reg2)
            send_state<=1'b0;
        else if(~key)
            send_state<=~send_state;
    end


     assign wea=Rx_done;

    //每次接收到一个字节数据时,ram地址加1
    always @(posedge clk or negedge rst_reg2) begin
        if(~rst_reg2)
            addra<=7'd0;
        else if(Rx_done)
            addra<=addra+1'b1;
    end
    //每次发送完一个字节数据时,ram地址减1
    always @(posedge clk or negedge rst_reg2) begin
        if(~rst_reg2)
            addrb<=1'b0;
        else if((Tx_done==1'b1) && (send_state==1'b1))
            addrb<=addrb+1'b1;
    end

    always @(posedge clk or negedge rst_reg2) begin
        if(~rst_reg2)
            Send_en<=1'b0;
        else if(send_state==1'b1)
            Send_en<=1'b1;
        else
            Send_en<=1'b0;
    end
endmodule

串口学习暂时就先告一段落了,去年用高云的开发板整百兆以太网传输没搞出来,iic都没成功调用ov5640,第一阶段目标就是学完三大低俗协议,再手敲一个千兆以太网网络传输视频显示,不知道这样刚学完算不算入门,任重而道远啊,网上一堆说这都烂大街了,老师做的是射频通信,但是貌似fpga岗位最多的是高速接口?通信这玩意我能搞明白吗。。。但是最终肯定是往zynq靠,慢慢来吧,读研自我救赎之路宛如长征。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值