EGO1—UART串行接口设计及通信的实现

使用软件: Vivado
开发板: EGO1采用Xilinx Artix-7系列XC7A35T-1CSG324C FPGA

功能描述及分析

实现功能

(1)发送:8个拨码开关控制数码管最后后两位显示16进制数字,按下按键,数码管显示的内容通过TX发送,通过串口调试助手接收到内容。
(2)接收:从串口调试助手发送两位16进制数,接收到之后通过数码管倒数3、4位显示。

UART管脚约束:
在这里插入图片描述

串行发送程序设计

收发的过程,在发送器空闲时间,数据线处于逻辑 1 状态,当提示有数据要
传输时,首先使数据线的逻辑状态为低,之后是 8 个数据位、一位校验位、一位
停止位,校验一般是奇偶校验,停止位用于标示一帧的结束,接收过程亦类似,
当检测到数据线变低时,开始对数据线以约定的频率抽样,完成接收过程。本例
数据帧采用:无校验位,停止位为一位。
在这里插入图片描述
系统启动后进入空闲态IDLE,如果按了实验电路板中间的按键(S2)也可以进入IDLE状态。如果有其他的按键按下,开始发送数据,数据为拨码开关设置的8位数值,在时钟的有效边沿进入START状态发送起始位,时钟选用clk_x约为9600Hz。

串行接收程序设计

采用16倍于波特率的频率时钟clk_16x进行采样,在第8个周期采集数据值。
在这里插入图片描述
由上图可知,将串行接收状态划分为4个主要状态。系统启动后进入空闲态IDLE,如果捕捉到了RXD信号的下降沿,开始接收数据启动计数。因为这里是启动信号0的开始,所以延后24个时钟,24=16+8,就大约到了数据位0的中间,在这个时间点上才转换到接收数据态ONE。
在接收数据态ONE,每隔16个时钟,就采集一次数据,分别存放到寄存器data_out的对应位。在第136分时钟开始之后的16个时钟,处于检查校验的状态TWO,判断校验是否有误,如果有误,则置位校验出错信号data_error,如果无误,则置位数据准备好信号data_ready。
之后进入STOP状态,等待时钟计数到168,清时钟计数回到IDLE态,继续监测串行输入RXD信号的到来。

代码实现

顶层设计代码

`timescale 1ns / 1ps
//
// Module Name: v_uart
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module v_uart(
    input clk,//时钟输入
    input[7:0] sw,//拨码开关输入
    input[4:0] btn,//键盘输入
    output[7:0] seg,//段码
    output[7:0] seg1,
    output[7:0] an,
    output[7:0] led,//led
    output txd,//数据发送
    input rxd  //数据接收 
); 
wire clk_ms,clk_20ms,clk_16x,clk_x;
wire[4:0] btnout;
wire[15:0] data_disp;//显示数据
wire data_ready;//数据是否准备好
wire data_error;
//调用分频模块
//clk 输入时钟50Mhz
//clk_ms 输出时钟1Khz
//clk_20ms 输出时钟50Hz
//clk_x 输出时钟9600Hz
//clk_16x 输出时钟9600hz*16
divclk my_divclk(
    .clk(clk),
    .clk_ms(clk_ms),
    .btnclk(clk_20ms),
    .clk_16x(clk_16x),
    .clk_x(clk_x)
);
v_smg uut_disp( //显示
    .clk(clk),
    .show_data({data_disp[15:0],sw[7:0]}),
    .seg(seg),
    .seg1(seg1),
    .an(an)
);
v_ajxd uut_ajxd(//按键消抖
        .clk(clk_ms),
        .btn_clk(clk_20ms),
        .btn(btn),
        .btn_out(btnout)
    );
uart_tx(//调用串口发送模块
    .clk_x(clk_x),
    .data_in(sw[7:0]),
    .btn(btnout),
    .txd(txd),
    .led(led)
    );
uart_rx(
    .clk_16x(clk_16x),
    .rst(btnout[0]),
    .rxd(rxd),
    .data_disp(data_disp),
    .data_ready(data_ready),
    .data_error(data_error)
);
endmodule

时钟分频

`timescale 1ns / 1ps
//
// Module Name: divclk
// Revision 0.01 - File Created
// Additional Comments:
// 
//
//分频模块
/*
clk:输入时钟100MHZ
clk_ms:输出时钟 1KHz
clk_20ms:输出时钟50HZ
clk_x 输出时钟9600HZ
clk_16x 输出时钟9600hz*16
*/

module divclk(clk,clk_ms,btnclk,clk_16x,clk_x);
input clk;
output clk_ms,btnclk,clk_16x,clk_x;
reg[31:0] cnt1=0;
reg[31:0] cnt2=0;
reg[31:0] cnt3=0;
reg[31:0] cntclk_cnt=0;
reg clk_ms=0;
reg btnclk=0;
reg clk_16x=0;
reg clk_x=0;
always@(posedge clk)//系统时钟分频 100M/1000 = 100000   1000HZ
begin
    if(cnt1==26'd50000)
    begin
        clk_ms=~clk_ms;
        cnt1=0;
    end
    else
        cnt1=cnt1+1'b1;
end
always@(posedge clk)//20MS: 100M/50 = 2000 000   50HZ
begin
    if(cntclk_cnt==1000000)
    begin
        btnclk=~btnclk;
        cntclk_cnt=0;
    end
    else
        cntclk_cnt=cntclk_cnt+1'b1;
end
always@(posedge clk)//100M/153600 = 651       9.6K*16=153.6k
begin
    if(cnt2=='d326)
    begin
        clk_16x<=~clk_16x;
        cnt2<='d0;
    end
    else
        cnt2=cnt2+1'b1;
end
always@(posedge clk)//100M/9600 = 10416.67       9600HZ
begin
    if(cnt3=='d5208)
    begin
        clk_x<=~clk_x;
        cnt3<= 0;
    end
    else
        cnt3=cnt3+1'b1;
end
endmodule

数码管显示

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/10/05 20:00:57
// Design Name: 
// Module Name: v_smg
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module v_smg(
input clk,
    input[19:0] show_data, //开关
    output[7:0] seg,//段选,高有效
    output[7:0] seg1,
    output[7:0] an //位选,低有效
);
    reg[18:0] divclk_cnt = 0;//分频计数器
    reg divclk = 0;//分频后的时钟
    reg[7:0] seg=0;//段码
    reg[7:0] seg1=0;
    reg[7:0] an=8'b00000001;//位码
    reg[3:0] disp_dat=0;//要显示的数据
    reg[2:0] disp_bit=0;//要显示的位
    parameter maxcnt = 50000;// 周期:50000*2/100M
    always@(posedge clk)
    begin
        if(divclk_cnt==maxcnt)
        begin
            divclk=~divclk;
            divclk_cnt=0;
        end
        else
        begin
            divclk_cnt=divclk_cnt+1'b1;
        end
    end
    always@(posedge divclk) begin
        if(disp_bit >= 4)
            disp_bit=0;
         else
            disp_bit=disp_bit+1'b1;
         case (disp_bit)
            3'b000 :
            begin
                disp_dat=show_data[3:0];
                an=8'b00000001;//显示第一个数码管,高电平有效
            end
            3'b001 :
            begin
                disp_dat=show_data[7:4];
                an=8'b00000010;//显示第二个数码管,低电平有效
            end
            3'b010 :
            begin
                disp_dat=show_data[11:8];
                an=8'b00000100;//显示第三个数码管,低电平有效
            end
            3'b011 :
            begin
                disp_dat=show_data[15:12];
                an=8'b00001000;//显示第四个数码管,低电平有效
            end
            3'b100 :
            begin
                disp_dat=show_data[19:16];
                an=8'b00010000;//显示第五个数码管,低电平有效
            end
            default:
            begin
                disp_dat=0;
                an=8'b00000000;
            end
        endcase
    end
    always@(disp_dat)
    begin
        if(an > 8'b00001000) begin
            case (disp_dat)
            //显示0-F
            4'h0 : seg = 8'hfc;
            4'h1 : seg = 8'h60;
            4'h2 : seg = 8'hda;
            4'h3 : seg = 8'hf2;
            4'h4 : seg = 8'h66;
            4'h5 : seg = 8'hb6;
            4'h6 : seg = 8'hbe;
            4'h7 : seg = 8'he0;
            4'h8 : seg = 8'hfe;
            4'h9 : seg = 8'hf6;
            4'ha : seg = 8'hee;
            4'hb : seg = 8'h3e;
            4'hc : seg = 8'h9c;
            4'hd : seg = 8'h7a;
            4'he : seg = 8'h9e;
            4'hf : seg = 8'h8e;
            endcase
        end
        else begin
            case (disp_dat)
            //显示0-F
            4'h0 : seg1 = 8'hfc;
            4'h1 : seg1 = 8'h60;
            4'h2 : seg1 = 8'hda;
            4'h3 : seg1 = 8'hf2;
            4'h4 : seg1 = 8'h66;
            4'h5 : seg1 = 8'hb6;
            4'h6 : seg1 = 8'hbe;
            4'h7 : seg1 = 8'he0;
            4'h8 : seg1 = 8'hfe;
            4'h9 : seg1 = 8'hf6;
            4'ha : seg1 = 8'hee;
            4'hb : seg1 = 8'h3e;
            4'hc : seg1 = 8'h9c;
            4'hd : seg1 = 8'h7a;
            4'he : seg1 = 8'h9e;
            4'hf : seg1 = 8'h8e;
            endcase
        end
    end
endmodule


串行发送

`timescale 1ns / 1ps
//
// Module Name: uart_tx
// Revision 0.01 - File Created
// Additional Comments:
// 
//

//发送器设计
module uart_tx(clk_x,data_in,btn,txd,led);
input clk_x;
input[7:0] data_in;
input[4:0] btn;
output txd;
output[7:0] led;
reg txd=1;
reg[7:0] led=8'b00000000;
reg[10:0] clk_x_cnt=0;
reg[7:0] data_in_buf;
reg[4:0] btn_out0,btn_out1;
reg[4:0] btn_down;

parameter 
    idle=5'b00000,
    start=5'b00001,
    b0=5'b00011,          
    b1=5'b00010,
    b2=5'b00110,
    b3=5'b00111,
    b4=5'b00101,
    b5=5'b00100,
    b6=5'b01100,
    b7=5'b01101,
    check=5'b01111,
    stop=5'b01110;
reg[4:0] present_state=idle;
//assign led[4:0]=present_state;
always@(posedge clk_x)
begin
    btn_out0<=btn;
    btn_out1<=btn_out0;
    btn_down<=btn_out0&~btn_out1;
    led[4:0]<=present_state;
    if(btn_down[0]) //复位
    begin
        present_state <= idle;
        led[6] <= 0;//指示空闲状态
        clk_x_cnt <= 'd0;
        txd <= 1;
    end
    else begin
        led[6]<=1; //指示开始发送数据
     case(present_state)
        idle: begin //空闲状态
                txd<=1;
                data_in_buf<=data_in;
                led[6]<=0;
                if(btn_down[4:1]>0) //如果按键按下
                begin
                    present_state <= start;
                end
                else
                    present_state <= idle;        
             end
             start: begin
                led[6]<=1;//指示正在发送数据
                txd <= 'd0; //发送起始位
                present_state <= b0;
             end
             b0: begin
                txd <= data_in_buf[0];//发送位0
                present_state<=b1;
             end
             b1: begin
                txd<=data_in_buf[1];//发送位1
                present_state<=b2;
             end
             b2: begin
                txd<=data_in_buf[2];//发送位2
                present_state<=b3;
             end
             b3: begin
                txd<=data_in_buf[3];//发送位3
                present_state<=b4;
             end
             b4: begin
                txd<=data_in_buf[4];//发送位4
                present_state<=b5;
             end
             b5: begin
                txd<=data_in_buf[5];//发送位5
                present_state<=b6;
             end
             b6: begin
                txd<=data_in_buf[6];//发送位6
                present_state<=b7;
             end
             b7: begin
                txd<=data_in_buf[7];//发送位7
                present_state<=check;
             end
             check: begin//发送偶校验
                txd<=data_in_buf[7]^data_in_buf[6]^data_in_buf[5]^data_in_buf[4]^data_in_buf[3]^data_in_buf[2]^data_in_buf[1]^data_in_buf[0];
                present_state<=stop;
             end
             stop: begin//发送停止位
                txd<='d1;
                led[6]<=0;//指示发送数据完成
                 present_state<=idle;//回到空闲状态
             end
        endcase
    end
    
end

endmodule

串行接收

`timescale 1ns / 1ps
//
// Create Date: 2022/10/06 14:19:41
// Design Name: 
// Module Name: uart_rx
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_rx(clk_16x,rst,rxd,data_disp,data_ready,data_error);//接收器设计
input clk_16x;//16倍的波特率采样时钟信号
input rst;//复位信号
input rxd;//接收串行数据输入
output data_ready;//数据准备好信号,当data_ready=1时,提醒后级设备可以接收这8位数据
output data_error;//奇偶校验错
output[15:0] data_disp;
reg data_ready,data_error,framing_error;
reg[7:0] data_out,data_out1;
reg rxd_buf;
reg[15:0] clk_16x_cnt;
reg rxd1,rxd2;
reg start_flag;
parameter width=3;
parameter idle=1,one=2,two=3,stop=4;//状态机的4个状态
reg[width-1:0] present_state,next_state;//状态机当前状态和下一个状态
assign data_disp[15:8]=0;
assign data_disp[7:0]=data_out1;
assign check=^data_out;
initial
begin
    clk_16x_cnt=0;
    present_state=idle;
    next_state=idle;
    rxd1=1'd1;
    rxd2=1'd1;
    data_ready='d0;
    start_flag=0;
end
//更新状态机当前状态
always@ (posedge clk_16x)
begin
    if(rst)
        present_state<=idle;
     else
        present_state<=next_state;
end
always@(clk_16x_cnt)//根据当前状态机的状态和判断条件,决定状态机的下一个状态
begin
    if(clk_16x_cnt<='d8)//校验起始位条件
        next_state=idle;
    if(clk_16x_cnt>'d8 && clk_16x_cnt <= 'd136)//接收8位数据条件
        next_state=one;
    if(clk_16x_cnt>'d136 && clk_16x_cnt <= 'd152)//奇偶校验位条件
        next_state=two;
    if(clk_16x_cnt>'d152 && clk_16x_cnt <= 'd168)//检验停止位条件
        next_state=stop;
    if(clk_16x_cnt > 'd168)
        next_state=idle;
end
always@(posedge clk_16x)//根据当前状态机的状态,决定输出
begin
    if(rst)
    begin
        rxd1<=1'd1;
        rxd2<=1'd1;
        data_ready<='d0;
        clk_16x_cnt<='d0;
        start_flag<=0;
    end
    else begin
        case(present_state)
        idle: begin //检测开始位
              rxd1<=rxd;
              rxd2<=rxd1;
              if((~rxd1)&&rxd2)//检测开始位,看rxd是否由高电平跳变到低电平
                    start_flag<='d1;//当rxd1=0,rxd2=1时,高电平跳变到低电平
              else if(start_flag==1)
                clk_16x_cnt<=clk_16x_cnt+'d1;
            end
         one: begin //接收8位数据
                clk_16x_cnt<=clk_16x_cnt + 'd1;
                if(clk_16x_cnt=='d24)data_out[0]<=rxd;
                else if(clk_16x_cnt=='d40)data_out[1]<=rxd;
                else if(clk_16x_cnt=='d56)data_out[2]<=rxd;
                else if(clk_16x_cnt=='d72)data_out[3]<=rxd;
                else if(clk_16x_cnt=='d88)data_out[4]<=rxd;
                else if(clk_16x_cnt=='d104)data_out[5]<=rxd;
                else if(clk_16x_cnt=='d120)data_out[6]<=rxd;
                else if(clk_16x_cnt=='d136)data_out[7]<=rxd;
            end
         two: begin//奇偶校验位
                if(clk_16x_cnt=='d152)
                begin
                    if(rxd_buf==rxd) data_error<=1'd0;//无错误
                    else data_error<=1'd1;//有错误
                end
                clk_16x_cnt <= clk_16x_cnt+'d1;
            end
         stop: begin //停止位
                if(clk_16x_cnt=='d168)
                begin
                    if(1'd1==rxd)
                    begin
                        data_error<=1'd0;//无错误
                        data_ready<='d1;
                    end
                    else begin
                        data_error<=1'd1;//有错误
                        data_ready<='d0;
                    end
                end
                data_out1<=data_out;
                if(clk_16x_cnt>168)
                begin
                    clk_16x_cnt <= 0;
                    start_flag <= 0;
                end
                else
                    clk_16x_cnt <= clk_16x_cnt + 'd1;
            end
         endcase
    end
end
endmodule

约束

## clk
set_property PACKAGE_PIN P17 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
## switch


##smg位码
set_property PACKAGE_PIN G2 [get_ports an[7]]
set_property IOSTANDARD LVCMOS33 [get_ports an[7]]
set_property PACKAGE_PIN C2 [get_ports an[6]]
set_property IOSTANDARD LVCMOS33 [get_ports an[6]]
set_property PACKAGE_PIN C1 [get_ports an[5]]
set_property IOSTANDARD LVCMOS33 [get_ports an[5]]
set_property PACKAGE_PIN H1 [get_ports an[4]]
set_property IOSTANDARD LVCMOS33 [get_ports an[4]]
set_property PACKAGE_PIN G1 [get_ports an[3]]
set_property IOSTANDARD LVCMOS33 [get_ports an[3]]
set_property PACKAGE_PIN F1 [get_ports an[2]]
set_property IOSTANDARD LVCMOS33 [get_ports an[2]]
set_property PACKAGE_PIN E1 [get_ports an[1]]
set_property IOSTANDARD LVCMOS33 [get_ports an[1]]
set_property PACKAGE_PIN G6 [get_ports an[0]]
set_property IOSTANDARD LVCMOS33 [get_ports an[0]]



##按键
set_property PACKAGE_PIN V1 [get_ports {btn[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {btn[4]}]
set_property PACKAGE_PIN U4 [get_ports {btn[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {btn[3]}]
set_property PACKAGE_PIN R11 [get_ports {btn[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {btn[2]}]
set_property PACKAGE_PIN R17 [get_ports {btn[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {btn[1]}]
set_property PACKAGE_PIN R15 [get_ports {btn[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {btn[0]}]

## 段码
set_property PACKAGE_PIN B4 [get_ports {seg[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[7]}]
set_property PACKAGE_PIN A4 [get_ports {seg[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[6]}]
set_property PACKAGE_PIN A3 [get_ports {seg[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[5]}]
set_property PACKAGE_PIN B1 [get_ports {seg[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[4]}]
set_property PACKAGE_PIN A1 [get_ports {seg[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[3]}]
set_property PACKAGE_PIN B3 [get_ports {seg[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[2]}]
set_property PACKAGE_PIN B2 [get_ports {seg[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[1]}]
set_property PACKAGE_PIN D5 [get_ports {seg[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[0]}]

# 段码2
set_property PACKAGE_PIN D4 [get_ports {seg1[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[7]}]
set_property PACKAGE_PIN E3 [get_ports {seg1[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[6]}]
set_property PACKAGE_PIN D3 [get_ports {seg1[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[5]}]
set_property PACKAGE_PIN F4 [get_ports {seg1[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[4]}]
set_property PACKAGE_PIN F3 [get_ports {seg1[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[3]}]
set_property PACKAGE_PIN E2 [get_ports {seg1[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[2]}]
set_property PACKAGE_PIN D2 [get_ports {seg1[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[1]}]
set_property PACKAGE_PIN H2 [get_ports {seg1[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg1[0]}]

## 拨码开关
set_property PACKAGE_PIN P5 [get_ports {sw[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[7]}]
set_property PACKAGE_PIN P4 [get_ports {sw[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[6]}]
set_property PACKAGE_PIN P3 [get_ports {sw[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[5]}]
set_property PACKAGE_PIN P2 [get_ports {sw[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[4]}]
set_property PACKAGE_PIN R2 [get_ports {sw[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[3]}]
set_property PACKAGE_PIN M4 [get_ports {sw[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[2]}]
set_property PACKAGE_PIN N4 [get_ports {sw[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[1]}]
set_property PACKAGE_PIN R1 [get_ports {sw[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}]

## led
set_property PACKAGE_PIN F6 [get_ports {led[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]
set_property PACKAGE_PIN G4 [get_ports {led[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
set_property PACKAGE_PIN G3 [get_ports {led[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
set_property PACKAGE_PIN J4 [get_ports {led[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
set_property PACKAGE_PIN H4 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property PACKAGE_PIN J3 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property PACKAGE_PIN J2 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property PACKAGE_PIN K2 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]

## TX发送
set_property PACKAGE_PIN T4 [get_ports txd]
set_property IOSTANDARD LVCMOS33 [get_ports txd]

## RX接收
set_property PACKAGE_PIN N5 [get_ports rxd]
set_property IOSTANDARD LVCMOS33 [get_ports rxd]

结果

(1)串口调试助手发送16进制数:C4,实验板晶体管显示:C4;
(2)拨码开关4位一组,显示16进制数:F3,按一下按键之后,串口调试助手接收到F3
在这里插入图片描述
在这里插入图片描述

  • 8
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 34
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值