基于FPGA的自动售货机

一、自动售货机的功能

       自动售货机中有价值为1元,3.5元,5元的三种饮料,能识别的金额为0.5元,1元,5元,10元。在购买饮料时,当输入金额小于饮料价值时,LED灯100ms闪烁;输入金额与饮料价值相等时,LED灯常亮;输入金额大于饮料价值时,显示多出的钱数,LED灯2s闪烁。饮料与输入金额须在数码管显示,饮料选择与金额输入可通过按键或者拨码开关进行。

二、具体实现方法  

  这个自动售货机采用top-down思想,主要分为5个模块,分别是:消抖模块、计算模块、状态机控制模块、led模块、显示模块;

  这个自动售货机根据·功能分析,它的输入有:系统时钟、复位信号、[2:0]drink(表示所选货物,拨码开关控制 分别为1元,3.5元,5元)、四种钱币的信号(0.5元,1元,5元,10元 由按键控制);它的输出有:数码管的位选和段选(sel[3:0],seg[7:0])和一个led的控制信号;

各个模块的实现方法

(1)、top模块

 本模块的实现主要是各个端口的例化,想要清晰的的实现本模块,画图是最简单的方式,所以,这个自动售货机的结构图如下:watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA57Sr572X5YWw5LiO5rW35qOg55qE6L6j6bih5a6k5Y-L,size_20,color_FFFFFF,t_70,g_se,x_16

 根据上图所示,本模块的代码为:

module top(
	input	clk,		//系统时钟
	input	rst,		//复位信号
	input	[2:0] drink,//货物
	input	money_one,	 //0.5
	input	money_two,   //1
	input	money_three, //5
	input	money_four,  //10
	
	output	wire [3:0] sel,//数码管位选
	output  wire [7:0] seg,//数码管段选
	output  wire	   led
    );
	
	wire [7:0] money_1;
	wire [7:0] money_2;
	wire [2:0]	flag;
	wire [11:0] money_in;   
	wire [11:0] money_drink; 
	wire [11:0] money_out;   
	wire [2:0]  ctrl;

//消抖部分	
	xiaodou s0(
		.clk(clk),
	    .rst(rst),
	    .key_in(money_one),
	    .key_flag(key1)
	);

	xiaodou s1(
		.clk(clk),
	    .rst(rst),
	    .key_in(money_two),
	    .key_flag(key2)
	);
	
	xiaodou s2(
		.clk(clk),
	    .rst(rst),
	    .key_in(money_three),
	    .key_flag(key3)
	);
	
	xiaodou s3(
		.clk(clk),
	    .rst(rst),
	    .key_in(money_four),
	    .key_flag(key4)
	);
//计算部分
	money s4(
		.clk(clk),
		.rst(rst),
		.key1(key1),
		.key2(key2),
		.key3(key3),
		.key4(key4),
		.drink(drink),
		.money_1(money_1), 
		.money_2(money_2), 
		.flag(flag),
		.money_in(money_in),   
		.money_drink(money_drink),
		.money_out(money_out)
	);  
//状态机
	zhaungtai s5(
		.clk(clk),
		.rst(rst),
		.flag(flag),
		.ctrl(ctrl)
	);
//数码管显示部分	
	xianshi s6(
	.clk(clk),
	.rst(rst),
	.ctrl(ctrl),
	.date1(money_drink),
	.date2(money_in),
	.date3(money_out),
	.sel(sel),
	.seg(seg)
	);
//led灯控制部分
	led s7(
		.clk(clk),
		.rst(rst),
		.flag(flag),
		.money_1(money_1),
		.money_2(money_2),
		.led(led)
	);
endmodule

(2)、消抖模块

        本模块的主要功能是对四个有按键输入的信号进行消抖,并输出一个脉冲信号;本模块的实现方法与上个文章的实现方法一致,在此不再赘述;

(3)、计算模块

        本模块的主要功能是计算所选的饮料的价格、输入铅笔的价格和所要找零的钱数并将其转化为BCD码(方便在数码管上显示);

        本模块的的输入有:系统时钟、复位信号、drink[2:0]、四个消抖后的钱币信号;输出有: money_1所选货物的价格(二进制)、money_2/所支付的钱数(二进制)flag状态机状态转化信号、money_in所支付的钱数(BCD)、 money_drink所选货物的价格(BCD)、 money_out 找零的钱数(BCD)。

本模块的实现困难之处是在数据转化为BCD码上,对于本模块我采用了三种实现方法:

        money_drink转化为BCD码:

这个信号的实现较为简单、直接通过一个译码器来实现:

always@(posedge clk or negedge rst) begin
		if(rst==0)
			money_1<=0;
		else begin
			case(drink)
				3'd000:begin money_1<='d0 ;money_drink<=12'b0000_0000_0000;  end
				3'd001:begin money_1<='d10;money_drink<=12'b0000_0001_0000;  end
				3'd010:begin money_1<='d35;money_drink<=12'b0000_0011_0101;  end
				3'd011:begin money_1<='d45;money_drink<=12'b0000_0100_0101;  end
				3'd100:begin money_1<='d50;money_drink<=12'b0000_0101_0000;  end
				3'd101:begin money_1<='d60;money_drink<=12'b0000_0110_0000;  end
				3'd110:begin money_1<='d85;money_drink<=12'b0000_1000_0101;  end
				3'd111:begin money_1<='d95;money_drink<=12'b0000_1001_0101;  end
			endcase
		end
	end

        money_in转化为BCD码:

这个信号的处理采用直接赋值的方式,直接对数据的[3:0]、[7:4]进行赋值来实现;

always@(posedge clk or negedge rst)begin
		if(!rst) begin
		   money_in<=12'd0;
		   money_2<='d0;
		end
		else if(money_in[3:0]>4'b1001)begin
		   money_in[3:0]<=money_in[3:0]-4'b1010;
		   money_in[7:4]<=money_in[7:4]+1'b1;
		end
		else if(money_in[7:4]>4'b1001)begin
		   money_in[7:4]<=money_in[3:0]-4'b1010;
		   money_in[11:8]<=money_in[7:0]+1'b1;
		end
		else if(key1) begin
		   money_in[3:0]<=money_in[3:0]+4'b0101;
		   money_2<=money_2+'d5;
		end
		else if(key2) begin
		   money_in[7:4]<=money_in[7:4]+4'b0001;
		   money_2<=money_2+'d10;
		end
		else if(key3) begin
			money_in[7:4]<=money_in[7:4]+4'b0101;
			money_2<=money_2+'d50;
		end
		else if(key4) begin
		   money_in[11:8]<=money_in[11:8]+4'b0001;
		   money_2<=money_2+'d100;
		end
		else
		   money_in<=money_in;
	end

      money_out转化为BCD码 :

对这个部分的操作是一个比较通用的方法:由于BCD码只对0到9的数据有效,所以当我们这个数据:x

10=<x<20时, 给数据的[7:4]加1,[3:0]赋一个x-10;

20=<x<30时, 给数据的[7:4]加2,[3:0]赋一个x-20;

...以此类推;

always@(posedge clk or negedge rst) begin
		if(rst==0)
			money_3<=0;
		else if(money_2>=money_1&&flag[2]==0)
			money_3<=money_2-money_1;
		else
			money_3<=money_3;
	end
	always@(posedge clk or negedge rst) begin
		if(rst==0) 
			money_out<=0;
		else if(money_out[3:0]>4'b1001)begin
		   money_out[3:0]<=money_out[3:0]-4'b1010;
		   money_out[7:4]<=money_out[7:4]+1'b1;
		end
		else if(money_out[7:4]>4'b1001)begin
		   money_out[7:4]<=money_out[3:0]-4'b1010;
		   money_out[11:8]<=money_out[7:0]+1'b1;
		end
		else if(money_3>='d90&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b1001;
			money_out[3:0]<=money_3-'d90;
		end	
		else if(money_3>='d80&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b1000;
			money_out[3:0]<=money_3-'d80;
		end	
		else if(money_3>='d70&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0111;
			money_out[3:0]<=money_3-'d70;
		end	
		else if(money_3>='d60&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0110;
			money_out[3:0]<=money_3-'d60;
		end	
		else if(money_3>='d50&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0101;
			money_out[3:0]<=money_3-'d50;
		end	
		else if(money_3>='d40&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0100;
			money_out[3:0]<=money_3-'d40;
		end	
		else if(money_3>='d30&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0011;
			money_out[3:0]<=money_3-'d30;
		end	
		else if(money_3>='d20&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0010;
			money_out[3:0]<=money_3-'d20;
		end	
		else if(money_3>='d10&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0001;
			money_out[3:0]<=money_3-'d10;
		end	

本模块还有一个对状态机进行控制的转换信号:

由于key1,key2,key3,key4这四个信号都是脉冲信号,要将对其首先判断;

本模块的完整代码为

module money(
	input 	clk,
	input 	rst,
	input 	key1, //消抖后的信号
	input 	key2, //消抖后的信号
	input 	key3, //消抖后的信号
	input 	key4, //消抖后的信号
	input 	[2:0] drink,//货物
	
	output reg [7:0] money_1, 		//所选货物的价格(二进制)	
	output reg [7:0] money_2,       //所支付的钱数(二进制)
	output reg[2:0]	 flag,          //状态机状态转化信号
	output reg[11:0] money_in,      //所支付的钱数(BCD)
	output reg[11:0] money_drink,   //所选货物的价格(BCD)
	output reg[11:0] money_out      //找零的钱数(BCD)
);

	
	reg [7:0] money_3; //找零的钱数(二进制)

//所负的总钱数并转化为bcd码	
	always@(posedge clk or negedge rst)begin
		if(!rst) begin
		   money_in<=12'd0;
		   money_2<='d0;
		end
		else if(money_in[3:0]>4'b1001)begin
		   money_in[3:0]<=money_in[3:0]-4'b1010;
		   money_in[7:4]<=money_in[7:4]+1'b1;
		end
		else if(money_in[7:4]>4'b1001)begin
		   money_in[7:4]<=money_in[3:0]-4'b1010;
		   money_in[11:8]<=money_in[7:0]+1'b1;
		end
		else if(key1) begin
		   money_in[3:0]<=money_in[3:0]+4'b0101;
		   money_2<=money_2+'d5;
		end
		else if(key2) begin
		   money_in[7:4]<=money_in[7:4]+4'b0001;
		   money_2<=money_2+'d10;
		end
		else if(key3) begin
			money_in[7:4]<=money_in[7:4]+4'b0101;
			money_2<=money_2+'d50;
		end
		else if(key4) begin
		   money_in[11:8]<=money_in[11:8]+4'b0001;
		   money_2<=money_2+'d100;
		end
		else
		   money_in<=money_in;
	end

//所选饮料的钱数并将其转化为bcd码	
	always@(posedge clk or negedge rst) begin
		if(rst==0)
			money_1<=0;
		else begin
			case(drink)
				3'd000:begin money_1<='d0 ;money_drink<=12'b0000_0000_0000;  end
				3'd001:begin money_1<='d10;money_drink<=12'b0000_0001_0000;  end
				3'd010:begin money_1<='d35;money_drink<=12'b0000_0011_0101;  end
				3'd011:begin money_1<='d45;money_drink<=12'b0000_0100_0101;  end
				3'd100:begin money_1<='d50;money_drink<=12'b0000_0101_0000;  end
				3'd101:begin money_1<='d60;money_drink<=12'b0000_0110_0000;  end
				3'd110:begin money_1<='d85;money_drink<=12'b0000_1000_0101;  end
				3'd111:begin money_1<='d95;money_drink<=12'b0000_1001_0101;  end
			endcase
		end
	end
	
//计算所要找的钱并将其转化为BCD码
	always@(posedge clk or negedge rst) begin
		if(rst==0)
			money_3<=0;
		else if(money_2>=money_1&&flag[2]==0)
			money_3<=money_2-money_1;
		else
			money_3<=money_3;
	end
	always@(posedge clk or negedge rst) begin
		if(rst==0) 
			money_out<=0;
		else if(money_out[3:0]>4'b1001)begin
		   money_out[3:0]<=money_out[3:0]-4'b1010;
		   money_out[7:4]<=money_out[7:4]+1'b1;
		end
		else if(money_out[7:4]>4'b1001)begin
		   money_out[7:4]<=money_out[3:0]-4'b1010;
		   money_out[11:8]<=money_out[7:0]+1'b1;
		end
		else if(money_3>='d90&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b1001;
			money_out[3:0]<=money_3-'d90;
		end	
		else if(money_3>='d80&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b1000;
			money_out[3:0]<=money_3-'d80;
		end	
		else if(money_3>='d70&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0111;
			money_out[3:0]<=money_3-'d70;
		end	
		else if(money_3>='d60&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0110;
			money_out[3:0]<=money_3-'d60;
		end	
		else if(money_3>='d50&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0101;
			money_out[3:0]<=money_3-'d50;
		end	
		else if(money_3>='d40&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0100;
			money_out[3:0]<=money_3-'d40;
		end	
		else if(money_3>='d30&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0011;
			money_out[3:0]<=money_3-'d30;
		end	
		else if(money_3>='d20&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0010;
			money_out[3:0]<=money_3-'d20;
		end	
		else if(money_3>='d10&&flag[2]==0) begin
			money_out[7:4]<=money_out[7:4]+4'b0001;
			money_out[3:0]<=money_3-'d10;
		end	
	end
//状态机状态转化信号
	always@(posedge clk or negedge rst) begin
		if(rst==0)
			flag<=0;
		else if({key1,key2,key3,key4}>0&&flag[0]<=1)
			flag[1]<=1;
		else if(money_3>0&&flag[1]<=1)
			flag[2]<=1;
		else if(drink>0)
			flag[0]<=1;
		else 
			flag<=0;
	end
endmodule

(4)、状态机模块

        本模块的主要功能是控制各个状态的转换,将会有一下状态:IDLE,选货,付钱,找钱;本模块的的输入有:系统时钟、复位信号、flag信号;输出有:一个控制信号来控制数码管的显示;

状态机的工作为:当有人选货时也就是drink>0时flag[0]=1,进入选货状态;当有钱币投入时,也就是{key1,key2,key3,key4}>0(flag[1]=1),进入付钱状态;当所支付的钱数大于等于所选货的钱数时(我在这里加了一个并且本状态至少保持1s,原因是如果一次性所支付的钱数大于或者等于货物的价格时,数码管上只会显示一个时钟周期(20ns)的所支付钱数,时间太短,我们肉眼无法察觉),进入找钱状态;当进入找钱状态五秒后回到IDLE;

状态机的状态转移图为:

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA57Sr572X5YWw5LiO5rW35qOg55qE6L6j6bih5a6k5Y-L,size_20,color_FFFFFF,t_70,g_se,x_16

 本模块的代码为:

module zhaungtai(
	input	clk,
	input	rst,
	input	[2:0] flag,
	
	output reg [2:0]  ctrl
    );
	
	localparam
	  IDLE 		= 4'b0001,
	  XUANHUO	= 4'b0010,
	  FUQIAN 	= 4'b0100,
	  ZHAOQIAN 	= 4'b1000;

	reg		[3:0] c_stats;
	reg		[3:0] n_stats;
	reg				en_1;
	reg				en_2;
	
	localparam TIME_1S='d49_999_999;
	/* localparam TIME_1S='d4; */
	
	reg [25:0] cnt_1s;
	reg [25:0] cnt_1s2;
	reg [2:0]  cnt_1;

//三段式状态机	
	always@(posedge clk or negedge rst) begin
		if(rst==0)
			c_stats<= 	IDLE;
		else 
			c_stats<= n_stats;
	end
	
	always@(*)begin
		case(c_stats) 
			IDLE: begin
				if(flag[0])
					n_stats<=XUANHUO;
				else
					n_stats<=IDLE;
			end
			XUANHUO: begin
				if(flag[1])
					n_stats<=FUQIAN;
				else
					n_stats<=XUANHUO;
			end
			FUQIAN: begin
				if(flag[2]&&cnt_1s2==TIME_1S)
					n_stats<=ZHAOQIAN;
				else
					n_stats<=FUQIAN;
			end
			ZHAOQIAN: begin
				if(cnt_1=='d5)
					n_stats<=IDLE;
				else
					n_stats<=ZHAOQIAN;
			end
		endcase
	end
	always@(posedge clk or negedge rst) begin
		if(rst==0) begin
			ctrl<=0;
			en_1<=0;
			en_2<=0;
		end
		else if(c_stats==IDLE) begin
			ctrl<=3'b000;
			en_1<=0;
			en_2<=0;
		end
		else if(c_stats==ZHAOQIAN) begin
			ctrl<=3'b100;
			en_1<=1;
			en_2<=0;
		end
		else if(c_stats==FUQIAN) begin
			ctrl<=3'b010;
			en_1<=0;
			en_2<=1;
		end
		else if(c_stats==XUANHUO) begin
			ctrl<=3'b001;
			en_1<=0;
			en_2<=0;
		end
	end
	
//
	always@(posedge clk or negedge rst) begin
		if(rst==0)
			cnt_1s<='d0;
		else if(cnt_1s == TIME_1S)
			cnt_1s<='d0;
		else if(en_1==1)
			cnt_1s<= cnt_1s + 1'd1;
	end
	
	always@(posedge clk or negedge rst) begin
		if(rst==0)
			cnt_1<=0;
		else if(cnt_1=='d4)
			cnt_1<=0;
		else if(cnt_1s==TIME_1S)
			cnt_1<=cnt_1+1'd1;
		else
			cnt_1<=cnt_1;
	end
	
	always@(posedge clk or negedge rst) begin
		if(rst==0)
			cnt_1s2<='d0;
		else if(cnt_1s2 == TIME_1S)
			cnt_1s2<='d0;
		else if(en_2==1)
			cnt_1s2<= cnt_1s2 + 1'd1;
	end
endmodule

(5)、led模块

        本模块的主要功能是实现当输入金额小于饮料价值时,LED灯100ms闪烁;输入金额与饮料价值相等时,LED灯常亮;输入金额大于饮料价值时,显示多出的钱数,LED灯2s闪烁。

        本模块的的输入有:系统时钟、复位信号、flag信号、money_1、money_2;输出:led信号;

        本模块实现较为简单,具体代码如下:

module led(
	input	clk,
	input   rst,
	input	[2:0] flag, //状态转化信号
	input	[7:0] money_1,//所选货物的价格(二进制)
	input	[7:0] money_2,//所支付的钱数(二进制)
                         
	output	reg  led
    );
	
	localparam 
	TIME_1S		='d49_999_999,
	TIME_100MS	='d4999_999;
	
	reg [22:0] cnt_100ms;
	reg [25:0] cnt_1s;
	
	always@(posedge clk or negedge rst)begin
		if(rst==0)
			cnt_1s<=0;
		else if(cnt_1s==TIME_1S)
			cnt_1s<=0;
		else 
			cnt_1s<=cnt_1s+1'd1;
	end
	
	always@(posedge clk or negedge rst)begin
		if(rst==0)
			cnt_100ms<=0;
		else if(cnt_100ms==TIME_100MS)
			cnt_100ms<=0;
		else 
			cnt_100ms<=cnt_100ms+1'd1;
	end
	
	always@(posedge clk or negedge rst)begin
		if(rst==0)
			led<=0;
		else if(money_1>money_2 && cnt_100ms==TIME_100MS)
			led<=~led;
		else if(money_1==money_2 && flag>0)
			led<=1;
		else if(money_1<money_2 && cnt_1s==TIME_1S)
			led<=~led;
			
	end
endmodule

(6)、显示模块

        本模块的主要功能是将此状态下所要展示的数据显示在数码管上;本模块的的输入有:系统时钟、复位信号、ctrl信号、date1,date2,date3;输出:数码管的段选和位选;

        看到这里,我们一直所没有注意到问题:无论是产品的价格和所支付的钱数亦或是所要找零的钱数都会出现浮点数,我们的解决办法是给所有数据乘以10,在数据的第二位让其小数点常亮,也就是当动态扫描到sel[1]时;seg[7]为0;其余位置seg[7]都为1;

        本模块的代码为:

module xianshi(
	input	clk,
	input	rst,
	input	[2:0]	ctrl,
	input	[11:0] date1,//数据信号
	input	[11:0] date2,//数据信号
	input	[11:0] date3,//数据信号
	
	output	reg [3:0]  sel, // 数码管位选(选择当前要显示的数码管)
	output	reg [7:0]  seg // 数码管段选(选择当前要显示的内容)
    );
		reg [14:0] cnt_1;	//分频记数的计数器
		reg		   clk_out;	//分频后的时钟信号
		/* reg [3:0]	sel_r;	//表示那个数码管亮 */
		reg [3:0]	date_tmp;
		reg [11:0] disp_data;
		
	localparam TIME='d24999;
	/* localparam TIME='d4; */
	
	always@(posedge clk or negedge rst) begin
		if(rst==0)
			disp_data<=0;
		else 
			case(ctrl)
				3'b001:disp_data<=date1;
				3'b010:disp_data<=date2;
				3'b100:disp_data<=date3;
				default:disp_data<=0;
			endcase
	end
	//cnt_1的记数模块
		always@(posedge clk or negedge rst) begin
			if(rst==0)
				cnt_1 <= 15'd0;
			else if(cnt_1 ==TIME)
				cnt_1 <= 15'd0;
			else 
				cnt_1 <= cnt_1+1'd1;
		end
		
	//时钟分频模块
		always@(posedge clk or negedge rst) begin
			if(rst==0)
				clk_out<=1'b0;
			else if(cnt_1== TIME)
				clk_out<=~clk_out;
			else	
				clk_out<=clk_out;
		end
		
	//移位寄存器
		always@(posedge clk_out or negedge rst) begin
			if(rst==0)
				sel<=4'b1110;
			else  
				sel[2:0]<={sel[1:0],sel[2]};
			/* if(rst==0)
				sel_r<=4'b0001;
			else 
				sel_r<={sel_r[2:0],sel_r[3]}; */
		end

	//四选一多路器
		always@(*) begin
			case(sel)
				4'b1110 : date_tmp <= disp_data[3:0]; 
				4'b1101 : date_tmp <= disp_data[7:4]; 
				4'b1011 : date_tmp <= disp_data[11:8]; 
				default:date_tmp<=4'b0000;
			endcase
		end
		
	//字典(译码器)
		always@(*) begin
			if(sel[2:0]==3'b101)begin
				case(date_tmp)
				4'h0:seg<=8'b01000000;
				4'h1:seg<=8'b01111001;
				4'h2:seg<=8'b00100100;
				4'h3:seg<=8'b00110000;
				4'h4:seg<=8'b00011001;
				4'h5:seg<=8'b00010010;
				4'h6:seg<=8'b00000010;
				4'h7:seg<=8'b01111000;
				4'h8:seg<=8'b00000000;
				4'h9:seg<=8'b00010000;
			endcase
			end
			else begin
			case(date_tmp)
				4'h0:seg<=8'b11000000;
				4'h1:seg<=8'b11111001;
				4'h2:seg<=8'b10100100;
				4'h3:seg<=8'b10110000;
				4'h4:seg<=8'b10011001;
				4'h5:seg<=8'b10010010;
				4'h6:seg<=8'b10000010;
				4'h7:seg<=8'b11111000;
				4'h8:seg<=8'b10000000;
				4'h9:seg<=8'b10010000;
			endcase
			end
		end
		

endmodule

 

 

 

 

 

 

 

 

  • 31
    点赞
  • 199
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值