HDMI FPGA

听了正点原子的详细讲解后,一段时间不看容易忘记,这里自己记录点笔记,以后回忆快一点,

思路,代码都是学习的正点原子开发,移植源码建议去正点原子官网下载,这里主要思路分析和代码解析。

1.端口解析+硬件流程

总的输入端口:(主要分为 视频输入和音频控制输入)

         视频输入:

        R[7:0],G[7:0],B[7:0],3*8一共24位,用来色彩数据并行输入

        VSYNC:行同步信号,解析见原理解析部分

        HSYNC:场同步信号,解析见原理解析部分

        VDE:在行同步时序中使用

(此历程简化暂时忽略  音频数据输入【HDMI Audio/Aux data】)

 |

                到达模块一()

        对输入信号编码, R[7:0],G[7:0],B[7:0] +VSYNC+HSYNC+VDE   -》R[9:0],G[9:0],B[9:0]

|   

到达OSERDESE2模块(并->串)

输入:

R[9:0],G[9:0],B[9:0]    (并)    

CLK 

CLK*5(PLL倍频后的5倍时钟用在并转串(OSESRDESE2模块)的上升沿和下降沿采集中)

Serializer[9:0](时钟编码通道输入,10bit,与CLK  CLK*5区分,前者是转化为串口所需要的数据,后者是为模块提供的时钟)

输出:

R (串口)

G (串口)

B (串口)

CLK          (串口Serializer时钟编码通道转化来的)

|   

到达OBUFDS模块(单端转差分)

  

2.原理详细解析

2.1 使用5倍CLK的原因

2.2OSERDESE2模块

实现功能:并->串   R[9:0],G[9:0],B[9:0]Serializer[9:0]    (并) ->R G B CLK (串)

双数据采集MODE:SDR(单数据沿处理)  DDR(双数据沿处理,上升沿+下降沿)

主从模式:主(master)  和  从(Slave)如上图    在下面会举例子

注意从Slave的D1 D2不能使用(数据手册写的),所以这里用D3 D4

SHIFIN/SHIFOUT:从OSERDESE2发送收到的数据给主OSERDESE2

其中一个OSERDESE2模块可以实现8并:1串的转化,但我们9:0有10个口,显然一个OSERDESE2模块不够用,所以用多个OSERDESE2模块的位宽拓展来实现10:1的转化,而两个OSERDESE2模块的连接就需要1个主和一个从连接,如下图

        2.2差分线data传输过程:

 场同步信号(HSYNC)和行同步信号(VSYNC)

时序解析:当开始传输各式各样的数据时,总需要一些特定时序规律,来辅助数据传输,以保持信号数据的正确传输,此处的时序解析按照时间顺序先后顺序解析

行同步时序(HSYNC)用在显示器每一行的数据传输时序中

场同步时序(VSYNC)用在显示器每一帧的数据传输时序中

行同步时域可以说包含在场同步时域中

场同步循环:

开始场同步(一帧画面开始),VSYNC拉低,延时 o (欧)时间,后拉高->显示后延 p 时间后开始行同步时序部分

        行同步循环:(有多少行就循环此过程多烧次)

        ->拉低HSYNC,延时a后拉高HSYNC->延时显示后沿(b)->拉高DE,data差分先开始传输画面数据,用时(c)->发送完成data数据后,拉低DE->延时显示前沿(d)[原这段时间可以传输其他音频数据等,这里简化历程]     到此本行的数据传输完成 ->下一行的HSYNC拉低,延时a后拉高HSYNC.......(开始行行同步循环循环)

-> 行数据过程传输完毕,总用时q,然后延时显示前沿 r时间    到此本帧的数据传输完成 ->开始下一帧场同步(一帧画面开始),VSYNC拉低,延时 o (欧)时间,后拉高......(开始行场同步循环循环)

3.代码解析

仍然是正点原子代码参考

模块化思维图参考

3.1顶层模块分析在hdmi_colorbar_top.v中

3.1.1定义顶层端口

(输入:时钟 + 复位 )

(输出 1bit的tmds_clk_p和tmds_clk_n  + [2:0]的tmds_data_p和tmds_data_n)

module  hdmi_colorbar_top(
    input        sys_clk,
    input        sys_rst_n,
    
    output       tmds_clk_p,    // TMDS 时钟通道
    output       tmds_clk_n,
    output [2:0] tmds_data_p,   // TMDS 数据通道
    output [2:0] tmds_data_n
);

3.1.2wire类型声明

wire          pixel_clk;
wire          pixel_clk_5x;
wire          clk_locked;

wire  [10:0]  pixel_xpos_w;
wire  [10:0]  pixel_ypos_w;
wire  [23:0]  pixel_data_w;

wire          video_hs;
wire          video_vs;
wire          video_de;
wire  [23:0]  video_rgb;

3.1.3MMCM/PLL IP核例化

完成功能:输出1倍原时钟和5倍时钟(用来并转串模块)。


clk_wiz_0  clk_wiz_0(
    .clk_in1        (sys_clk),
    .clk_out1       (pixel_clk),        //像素时钟
    .clk_out2       (pixel_clk_5x),     //5倍像素时钟
    
    .reset          (~sys_rst_n), 
    .locked         (clk_locked)
);

MMCM(不是PLL) ip核设置

主要看下面  clk_in 1(板子晶振提供)输入时钟50Mhz

输出

clk_out1  74.25Mhz用于后面的并行时钟(为啥是74.25M勒,这是因为在这个1280*720分辨率下要求的频率是这么多)

clk_out2  74.25*5=371.25Mhz用于后面的并转串行模块的串行时钟

3.1.4 video_driver例化

实现功能:使输出的行同步信号  ,场同步信号 de端口                    [23:0]RGB888颜色数据                         像素点横坐标纵坐标符合行同步序号和场同步信号的时序要求

输入:pixel_clk 时钟 sys_rst_n 复位   [23:0]pixel_data//像素点数据

输出:video_hs      video_vs        video_de       

[23:0]video_rgb     

data_req(未使用)

pixel_xpos像素点横坐标

pixel_ypos像素点纵坐标

这里使用wire连线

//例化视频显示驱动模块
video_driver  u_video_driver(
    .pixel_clk      ( pixel_clk ),
    .sys_rst_n      ( sys_rst_n ),

    .video_hs       ( video_hs ),
    .video_vs       ( video_vs ),
    .video_de       ( video_de ),
    .video_rgb      ( video_rgb ),
	.data_req		(),

    .pixel_xpos     ( pixel_xpos_w ),
    .pixel_ypos     ( pixel_ypos_w ),
	.pixel_data     ( pixel_data_w )
);

3.1.5 video_display例化

实现功能:在1280*720的屏幕分辨率下

输入的像素点坐标在判断在哪个对应范围

则【23:0】pixel_data输出对应的颜色  实现最后输出彩条

输入:clk 复位信号

11位的x坐标 ,y坐标(来表示屏幕上的那一个像素点)

输出:

【23:0】 pixel_data :该坐标像素点的色彩数据

//例化视频显示模块
video_display  u_video_display(
    .pixel_clk      (pixel_clk),
    .sys_rst_n      (sys_rst_n),

    .pixel_xpos     (pixel_xpos_w),
    .pixel_ypos     (pixel_ypos_w),
    .pixel_data     (pixel_data_w)
    );

3.1.6 vi_transmitter_top例化

输入:

pixel_clk 一倍时钟  

pixel_clk_5x 5倍时钟 

sys_rst_n复位信号

clk_locked类似于clk的开关吧

video_rgb[23:0] rgb输入24位并行输入

video_hs  场同步信号(HSYNC)

video_vs 行同步信号(VSYNC)

video_de 行同步信号中用到的de端口 详细见行同步时序

输出

tmds_clk_p tmds_clk_n          clk(不是前面的pixel_clk ,两个用途的时钟)的差分输出

tmds_data_p tmds_data_n     数据的差分输出

//例化HDMI驱动模块
dvi_transmitter_top u_rgb2dvi_0(
    .pclk           (pixel_clk),
    .pclk_x5        (pixel_clk_5x),
    .reset_n        (sys_rst_n & clk_locked),
                
    .video_din      (video_rgb),
    .video_hsync    (video_hs), 
    .video_vsync    (video_vs),
    .video_de       (video_de),
                
    .tmds_clk_p     (tmds_clk_p),
    .tmds_clk_n     (tmds_clk_n),
    .tmds_data_p    (tmds_data_p),
    .tmds_data_n    (tmds_data_n), 
    .tmds_oen       ()                        //预留的端口,本次实验未用到
    );

3.2分析video_driver moudle在video_driver.v中

实现功能:使输出的行同步信号  ,场同步信号 de端口                    [23:0]RGB888颜色数据                         像素点横坐标纵坐标符合行同步序号和场同步信号的时序要求

输入:pixel_clk 时钟 sys_rst_n 复位   [23:0]pixel_data//像素点数据

输出:video_hs      video_vs        video_de        [23:0]video_rgb      data_req

pixel_xpos像素点横坐标

pixel_ypos像素点纵坐标

module video_driver(
    input           	pixel_clk	,
    input           	sys_rst_n	,
		
    //RGB接口	
    output          	video_hs	,     //行同步信号
    output          	video_vs	,     //场同步信号
    output          	video_de	,     //数据使能
    output  	[23:0]  video_rgb	,    //RGB888颜色数据
    output	reg			data_req 	,
	
    input   	[23:0]  pixel_data	,   //像素点数据
    output  reg	[10:0]  pixel_xpos	,   //像素点横坐标
    output  reg	[10:0]  pixel_ypos    //像素点纵坐标
);
//1280*720 分辨率时序参数
parameter  H_SYNC   =  11'd40;   //行同步
parameter  H_BACK   =  11'd220;  //行显示后沿
parameter  H_DISP   =  11'd1280; //行有效数据
parameter  H_FRONT  =  11'd110;  //行显示前沿
parameter  H_TOTAL  =  11'd1650; //行扫描周期

parameter  V_SYNC   =  11'd5;    //场同步
parameter  V_BACK   =  11'd20;   //场显示后沿
parameter  V_DISP   =  11'd720;  //场有效数据
parameter  V_FRONT  =  11'd5;    //场显示前沿
parameter  V_TOTAL  =  11'd750;  //场扫描周期
//reg define
reg  [11:0] cnt_h;
reg  [11:0] cnt_v;
reg       	video_en;

定时器编写

一个定时器用于记录 

行进度(一共是行扫描周期如上图的(e),也是H_TOTAL  =  11'd1650; //行扫描周期           -1)

(已经加入了各个前沿,后沿等时间,所以是d1650,不是1280,来消影等处理)

每当一个行周期扫描完毕清一次0,这一时刻正是达到了这一行最后一个像素点

一个定时器用于记录 

场进度记录(一共是行扫描周期如上图的(s),也是V_TOTAL  = 11'd750; //行扫描周期           -1)

每当一个行周期扫描完毕,开始记录场 周期进度+1,当场周期时间达到场周期上限,说明达到了这最后一行最后一个像素点(已经加入了各个前沿,后沿等时间,所以是750,不是720,来消影等处理),清0

//行计数器对像素时钟计数
always @(posedge pixel_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        cnt_h <= 11'd0;
    else begin
        if(cnt_h < H_TOTAL - 1'b1)
            cnt_h <= cnt_h + 1'b1;
        else 
            cnt_h <= 11'd0;
    end
end

//场计数器对行计数
always @(posedge pixel_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        cnt_v <= 11'd0;
    else if(cnt_h == H_TOTAL - 1'b1) begin
        if(cnt_v < V_TOTAL - 1'b1)
            cnt_v <= cnt_v + 1'b1;
        else 
            cnt_v <= 11'd0;
    end
end

 行同步信号(图中HSYNC),和场同步信号(图中VSYNC)用assign组合逻辑来实现

设计思路:

video_de        video_en就是图中应该发送有效data的标志位

利用计时器记录当前的行进度和场进度,当进度时>设定的H_SYNC(图中的a) 值时赋值为1  (已经度过行同步时间a,图中HSYNC=1),否则为0(没有度过行同步时间a,图中HSYNC=0)

利用计时器记录当前的行进度和场进度,当进度时>设定的V_SYNC(图中的o) 值时赋值为1  (已经度过场同步时间o,图中VSYNC=1),否则为0(没有度过场同步时间o图中VSYNC=0)

assign video_de  = video_en;
assign video_hs  = ( cnt_h < H_SYNC ) ? 1'b0 : 1'b1;  //行同步信号赋值
assign video_vs  = ( cnt_v < V_SYNC ) ? 1'b0 : 1'b1;  //场同步信号赋值

到此的图中VSYNC和图中HSYNC已经实现。

当video_de=1应该发生有效数据时,rgb数据=输入的[23:0]pixel_data数据否则为0

//RGB888数据输出
assign video_rgb = video_de ? pixel_data : 24'd0;




这段是对data_req的操作,简化一下就是在有效数据发送的前2段时间,输出1告诉其他模块,要发送有效data了

//请求像素点颜色数据输入
always @(posedge pixel_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		data_req <= 1'b0;
	else if(((cnt_h >= H_SYNC + H_BACK - 2'd2) && (cnt_h < H_SYNC + H_BACK + H_DISP - 2'd2))
                  && ((cnt_v >= V_SYNC + V_BACK) && (cnt_v < V_SYNC + V_BACK+V_DISP)))
		data_req <= 1'b1;
	else
		data_req <= 1'b0;
end

在每个时刻输出正确的x,y点数据

//像素点x坐标
always@ (posedge pixel_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        pixel_xpos <= 11'd0;
    else if(data_req)
        pixel_xpos <= cnt_h + 2'd2 - H_SYNC - H_BACK ;
    else 
        pixel_xpos <= 11'd0;
end
    
//像素点y坐标	
a       pixel_ypos <= 11'd0;
    else if((cnt_v >= (V_SYNC + V_BACK)) && (cnt_v < (V_SYNC + V_BACK + V_DISP)))
        pixel_ypos <= cnt_v + 1'b1 - (V_SYNC + V_BACK) ;
    else 
        pixel_ypos <= 11'd0;
endlways@ (posedge pixel_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
 

3.3分析video_displaymoudle在video_display.v中

实现功能:在1280*720的屏幕分辨率下

输入的像素点坐标  判断在哪个对应范围

则【23:0】pixel_data输出对应的颜色  实现最后输出彩条

输入:clk 复位信号

11位的x坐标 ,y坐标(来表示屏幕上的那一个像素点)

输出:

【23:0】 pixel_data :该坐标像素点的色彩数据

module  video_display(
    input                pixel_clk,
    input                sys_rst_n,
    
    input        [10:0]  pixel_xpos,  //像素点横坐标
    input        [10:0]  pixel_ypos,  //像素点纵坐标
    output  reg  [23:0]  pixel_data   //像素点数据
);

 0到1/5的x坐标输出白色   1/5屏幕的x坐标到 2/5屏幕的x坐标输出黑色 。。。。。。。。

//parameter define
parameter  H_DISP = 11'd1280;                       //分辨率——行
parameter  V_DISP = 11'd720;                        //分辨率——列

localparam WHITE  = 24'b11111111_11111111_11111111;  //RGB888 白色
localparam BLACK  = 24'b00000000_00000000_00000000;  //RGB888 黑色
localparam RED    = 24'b11111111_00000000_00000000;  //RGB888 红色
localparam GREEN  = 24'b00000000_11111111_00000000;  //RGB888 绿色
localparam BLUE   = 24'b00000000_00000000_11111111;  //RGB888 蓝色
    
//*****************************************************
//**                    main code
//*****************************************************

//根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条
always @(posedge pixel_clk ) begin
    if (!sys_rst_n)
        pixel_data <= 16'd0;
    else begin
        if((pixel_xpos >= 0) && (pixel_xpos < (H_DISP/5)*1))
            pixel_data <= WHITE;
        else if((pixel_xpos >= (H_DISP/5)*1) && (pixel_xpos < (H_DISP/5)*2))
            pixel_data <= BLACK;  
        else if((pixel_xpos >= (H_DISP/5)*2) && (pixel_xpos < (H_DISP/5)*3))
            pixel_data <= RED;  
        else if((pixel_xpos >= (H_DISP/5)*3) && (pixel_xpos < (H_DISP/5)*4))
            pixel_data <= GREEN;
        else 
            pixel_data <= BLUE;
    end
end

endmodule

更详细的代码请自我查看,博主简化了一下大意,精力有限码不了一点了

3.4分析dvi_transmitter_top在dvi_transmitter_top.v中

实现功能:

输入:

clk                       5倍时钟               复位                   

【23:0】RGB并行输入   场同步信号  行同步信号   de端口(行同步信号中使用)

输出:

差分时钟信号      差分data信号3(R G B 3对的串行差分信号,一共3*2 =6根线输出)   

 输出使能位

module dvi_transmitter_top(
    input        pclk,           // pixel clock
    input        pclk_x5,        // pixel clock x5
    input        reset_n,        // reset
    
    input [23:0] video_din,      // RGB888 video in
    input        video_hsync,    // hsync data
    input        video_vsync,    // vsync data
    input        video_de,       // data enable
    
    output       tmds_clk_p,    // TMDS 时钟通道
    output       tmds_clk_n,
    output [2:0] tmds_data_p,   // TMDS 数据通道
    output [2:0] tmds_data_n,
    output       tmds_oen       // TMDS 输出使能
    );

wire类型定义

//wire define    
wire        reset;
    
//并行数据
wire [9:0]  red_10bit;
wire [9:0]  green_10bit;
wire [9:0]  blue_10bit;
wire [9:0]  clk_10bit;  
  
//串行数据
wire [2:0]  tmds_data_serial;
wire        tmds_clk_serial;

 手动赋值                     后面差分输出的clk10bit编码

assign tmds_oen = 1'b1;  
assign clk_10bit = 10'b1111100000;

异步复位,同步释放

asyn_rst_syn reset_syn(
    .reset_n    (reset_n),
    .clk        (pclk),
    
    .syn_reset  (reset)    //高有效
    );

dvi_encoder encoder_b           dvi_encoder encoder_g         dvi_encoder encoder_r 

完成功能:对三个颜色通道进行TMDS编码成       每个8位输入编码成10bit输出   一共30bit输出

输入:

clk    复位   

RGB数据输入的0到8位   场行同步信号 

输出:

out  编码后的10位并行blue信号

dvi_encoder encoder_b (
    .clkin      (pclk),
    .rstin	    (reset),
    
    .din        (video_din[7:0]),
    .c0			(video_hsync),
    .c1			(video_vsync),
    .de			(video_de),
    .dout		(blue_10bit)
    ) ;

dvi_encoder encoder_g (
    .clkin      (pclk),
    .rstin	    (reset),
    
    .din		(video_din[15:8]),
    .c0			(1'b0),
    .c1			(1'b0),
    .de			(video_de),
    .dout		(green_10bit)
    ) ;
    
dvi_encoder encoder_r (
    .clkin      (pclk),
    .rstin	    (reset),
    
    .din		(video_din[23:16]),
    .c0			(1'b0),
    .c1			(1'b0),
    .de			(video_de),
    .dout		(red_10bit)
    ) ;

此时已经有了TMDS编码后的30bit并行数据,

所以现在RGB要分3组(3*10位=30bit)并转串

serializer_10_to_1 serializer_b(
    .reset              (reset),                // 复位,高有效
    .paralell_clk       (pclk),                 // 输入并行数据时钟
    .serial_clk_5x      (pclk_x5),              // 输入串行数据时钟
    .paralell_data      (blue_10bit),           // 输入并行数据

    .serial_data_out    (tmds_data_serial[0])   // 输出串行数据
    );    
    
serializer_10_to_1 serializer_g(
    .reset              (reset),
    .paralell_clk       (pclk),
    .serial_clk_5x      (pclk_x5),
    .paralell_data      (green_10bit),

    .serial_data_out    (tmds_data_serial[1])
    );
    
serializer_10_to_1 serializer_r(
    .reset              (reset),
    .paralell_clk       (pclk),
    .serial_clk_5x      (pclk_x5),
    .paralell_data      (red_10bit),

    .serial_data_out    (tmds_data_serial[2])
    );

10bit clk转化为串行

serializer_10_to_1 serializer_clk(
    .reset              (reset),
    .paralell_clk       (pclk),
    .serial_clk_5x      (pclk_x5),
    .paralell_data      (clk_10bit),

    .serial_data_out    (tmds_clk_serial)
    );

串行转化完毕,接下来开始将串行转化为差分(调用源语OBUFDS)

//转换差分信号  
OBUFDS #(
    .IOSTANDARD         ("TMDS_33")    // I/O电平标准为TMDS
) TMDS0 (
    .I                  (tmds_data_serial[0]),
    .O                  (tmds_data_p[0]),
    .OB                 (tmds_data_n[0]) 
);

OBUFDS #(
    .IOSTANDARD         ("TMDS_33")    // I/O电平标准为TMDS
) TMDS1 (
    .I                  (tmds_data_serial[1]),
    .O                  (tmds_data_p[1]),
    .OB                 (tmds_data_n[1]) 
);

OBUFDS #(
    .IOSTANDARD         ("TMDS_33")    // I/O电平标准为TMDS
) TMDS2 (
    .I                  (tmds_data_serial[2]), 
    .O                  (tmds_data_p[2]), 
    .OB                 (tmds_data_n[2])  
);

OBUFDS #(
    .IOSTANDARD         ("TMDS_33")    // I/O电平标准为TMDS
) TMDS3 (
    .I                  (tmds_clk_serial), 
    .O                  (tmds_clk_p),
    .OB                 (tmds_clk_n) 
);
  
endmodule

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VGA转HDMI FPGA是一款电子设备转换器,它可以将VGA接口的视频信号转换为HDMI接口的视频信号。该设备采用了FPGA(现场可编程门阵列)技术,可以对信号进行实时转换,保证了信号的稳定性和高清晰度。FPGA芯片的可编程性,使得VGA转HDMI转换器可以在不同的输入和输出之间切换,满足用户的多样化需求。同时,FPGA芯片具有丰富的接口和功能,例如矩阵开关、图像处理和显示控制等,这让VGA转HDMI FPGA更加灵活和高效。 在实际应用中,VGA转HDMI FPGA主要用于各种需要视频信号转换的场合,例如电脑与电视、投影仪之间的连接、会议室演示等。该设备可以保证视频信号转换的质量和稳定性,使得用户可以享受到高清晰度的视频体验。作为一款高性能的电子设备,VGA转HDMI FPGA不仅具有广泛的应用领域,同时也是现代科技的代表,为人们的生活和工作带来了更多的便利和乐趣。 ### 回答2: VGA转HDMI FPGA是一种数字信号转换器,用于将一个模拟VGA输入信号转换为数码HDMI输出信号FPGA代表现场可编程门阵列,是一种可编程硬件平台,可以让工程师编写硬件描述语言代码,从而完成电路的设计和实现。FPGA可以用于许多应用程序,包括数字信号处理、图像处理等。在VGA转HDMI FPGA中,FPGA被用来完成VGA信号的采集和数字化,并把数字信号转换为HDMI输出信号的格式。这种转换器通常用于将模拟投影仪、电视机等老式设备连接到现代的数码电视、显示器等设备上,以获得更高的图像质量和分辨率。VGA转HDMI FPGA通常使用USB供电,因此可以轻松携带,并且易于设置和使用。虽然VGA信号已被淘汰,但在某些情况下,仍有必要连接老旧的设备,因此VGA转HDMI FPGA仍然是一项有用的技术。 ### 回答3: VGA转HDMI FPGA是指采用FPGA芯片设计的VGA转HDMI转换器。FPGA芯片具有高度可编程性和灵活性,可以根据需要定制设计,实现各种功能。它可以将电脑或显示器的VGA信号转换为高清晰度的HDMI信号,实现不同接口之间的视频信号转换。相比于传统的硬件转换器,FPGA芯片的转换效果更加精准,稳定性更强,能够避免因接口不兼容而产生的信号干扰和失真问题。此外,由于FPGA芯片具有低功耗、小体积、高速传输等特点,因此VGA转HDMI FPGA转换器在工业控制、医疗器械、机器视觉、汽车导航等领域也有广泛应用。总之,VGA转HDMI FPGA是一种高性能、高可靠性的视频信号转换器,能够实现不同接口之间的互相转换,具有广泛的应用前景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值