开发板实战篇3 6位数码管动态显示

这篇具有很好参考价值的文章主要介绍了开发板实战篇3 6位数码管动态显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

总结:

        模块例化思想: 例化2个定时器模块 + 数码管驱动

        根据自己思路编写代码,调试仿真代码,同时熟悉环境.加深细节理解 

         刚开始写得很乱,代码完全就是用modelsim仿真调试出来的     

注意:

       

一. 实现的功能

       使用FPGA开发板上的6位数码管以动态方式从0开始计数,每100ms计数值
增加一,当计数值从0增加到999999后重新从0开始计数。
 

二. 功能框图

        定时器模块1:加计数器,计数100ms到了产生overflow信号

        定时器模块2:加计数器,计数1ms到了产生overflow信号

        segled控制模块:

                根据en使能信号,增加显示值0~999999;

                根据en2使能信号,切换sel位选信号,并输出段选信号

        打开方法:  tools -> netlist viewers -> rtl viewer

开发板实战篇3 6位数码管动态显示

 三. RTL代码

        segled_dy_top.v

        与segled_dynamic_top.v基本相同。

        COUNT_OVERFLOW = 26'd5_000_000,即闪烁周期为100ms。

module segled_dy_top (
    input clk,
    input reset,
    output [5:0] sel,
    output [7:0] seg_led
);

parameter COUNT_OVERFLOW = 26'd5_000_000;				//1s
parameter COUNT_OVERFLOW2 = 26'd50_000_000/10'd1000;	//1ms

wire [1:0] overflow;                 

timer #(
  .COUNT_OVERFLOW (COUNT_OVERFLOW)
  )
  u_timer(
  .clk      (clk),
  .reset    (reset),
  .overflow (overflow[0])
);

timer #(
  .COUNT_OVERFLOW (COUNT_OVERFLOW2)
  )
  u2_timer(
  .clk      (clk),
  .reset    (reset),
  .overflow (overflow[1])
);

segled_dy_driver u_segled_dy_driver(clk,reset,overflow[0],overflow[1],sel,seg_led);

    
endmodule

        timer.v

        除将overflow <=修改为非阻塞赋值外,其它与led点灯工程的相同。

/*
********************************************************************************
  *Copyright ©, 2018, CunXin_ All Rights Reserved
  *文 件 名: key_led.v
  *说    明: 
            程序功能无按键按下时, LED灯全灭; 
            按键1按下时, LED灯显示自右向左的流水效果;
            按键2按下时, LED灯显示自左向右的流水效果;
            按键3按下时,四个LED灯同时闪烁;
            按键4按下时, LED灯全亮
  *版    本: V000B00D00
  *创建日期: 2018年4月3日		下午12:16:49
  *创 建 人: wansaiyon
  *修改信息:  
================================================================================
  *修 改 人    		  修改日期       	  修改内容 
  *<作者/修改者>      <YYYY/MM/DD>		  <修改内容>
********************************************************************************
*/

module timer #(
    parameter COUNT_OVERFLOW = 26'd10_000_000
) (
    input clk,
    input reset,
    output reg overflow
);

localparam period = COUNT_OVERFLOW;

reg [25:0] cnt;

always @(posedge clk,negedge reset) begin
    if(!reset) begin
      cnt <= 26'd0;
      overflow <= 1'b0;
    end        
    else if(cnt < period) begin
      cnt <= cnt + 1'd1;
      overflow <= 1'b0;
    end        
    else begin
      cnt <= 26'd0;
      overflow <= 1'b1;
    end
        
end

endmodule

        segled_dy_driver.v

        主要功能点:

        定义16个字符、

        0~999999计数,执行周期100ms

        连续赋值计算个位、十位、百位....

        计算待显示数字的位数,执行周期100ms

        位选控制 sel_ctrl 切换,执行周期1ms

        输出位选信号sel(采用独热码)和段选信号 seg_led, 执行周期1ms

/*
	6位数码管			
	sel[0]	output	N16	第一个数码管位选信号
	sel[1]	output	N15	第二个数码管位选信号
	sel[2]	output	P16	第三个数码管位选信号
	sel[3]	output	P15	第四个数码管位选信号
	sel[4]	output	R16	第五个数码管位选信号
	sel[5]	output	T15	第六个数码管位选信号
	seg_led[0]	output	M11	数码管段选a
	seg_led[1]	output	N12	数码管段选b
	seg_led[2]	output	C9	数码管段选c
	seg_led[3]	output	N13	数码管段选d
	seg_led[4]	output	M10	数码管段选e
	seg_led[5]	output	N11	数码管段选f
	seg_led[6]	output	P11	数码管段选g
	seg_led[7]	output	D9	数码管段选h
*/

module segled_dy_driver (
    input clk,
    input reset,
    input en,
    input en2,
    output reg [5:0] sel,
    output reg [7:0] seg_led
);

// localparam define  
/*
//显示.号
localparam CHAR_0 = 8'b0100_0000;
localparam CHAR_1 = 8'b0111_1001;
localparam CHAR_2 = 8'b0010_0100;
localparam CHAR_3 = 8'b0011_0000;
localparam CHAR_4 = 8'b0001_1001;
localparam CHAR_5 = 8'b0001_0010;
localparam CHAR_6 = 8'b0000_0010;
localparam CHAR_7 = 8'b0111_1000;
localparam CHAR_8 = 8'b0000_0000;
localparam CHAR_9 = 8'b0001_0000;
localparam CHAR_a = 8'b0000_1000;
localparam CHAR_b = 8'b0000_0011;
localparam CHAR_c = 8'b0100_0110;
localparam CHAR_d = 8'b0010_0001;
localparam CHAR_e = 8'b0000_0110;
localparam CHAR_f = 8'b0000_1110;
*/
localparam CHAR_0 = 8'b1100_0000;
localparam CHAR_1 = 8'b1111_1001;
localparam CHAR_2 = 8'b1010_0100;
localparam CHAR_3 = 8'b1011_0000;
localparam CHAR_4 = 8'b1001_1001;
localparam CHAR_5 = 8'b1001_0010;
localparam CHAR_6 = 8'b1000_0010;
localparam CHAR_7 = 8'b1111_1000;
localparam CHAR_8 = 8'b1000_0000;
localparam CHAR_9 = 8'b1001_0000;
localparam CHAR_a = 8'b1000_1000;
localparam CHAR_b = 8'b1000_0011;
localparam CHAR_c = 8'b1100_0110;
localparam CHAR_d = 8'b1010_0001;
localparam CHAR_e = 8'b1000_0110;
localparam CHAR_f = 8'b1000_1110;

// reg define     
reg [19:0] disp_num;	 /* 0~999999 */
reg [2:0]  disp_num_bit; /* disp_num的位数 */
reg [2:0]  sel_ctrl; 	 /* sel[0]~sel[5] */

// wire define
wire [3:0] data0;		/* 个位 */
wire [3:0] data1;		/* 十位 */
wire [3:0] data2;		/* 百位 */
wire [3:0] data3;		/* 千位 */
wire [3:0] data4;		/* 万位 */
wire [3:0] data5;		/* 十万位 */

// continues assignment
assign data0 =  disp_num%4'd10;				
assign data1 = (disp_num/4'd10)%4'd10;		
assign data2 = (disp_num/7'd100)%4'd10;		
assign data3 = (disp_num/10'd1000)%4'd10;	
assign data4 = (disp_num/14'd10000)%4'd10;	
assign data5 = (disp_num/17'd100000)%4'd10;	

/*
	循环计数 0~999999,en产生执行周期1s
*/
always @(posedge clk,negedge reset ) begin
    if(!reset) begin
        disp_num <= 20'd0;
    end
    else if(en && (disp_num < 20'd999999)) begin
        disp_num <= disp_num + 1'b1;
    end
    else if(en && (disp_num == 20'd999999))begin
        disp_num <= 20'd0;
    end 
	else begin
        disp_num <= disp_num;
    end 	
end

/*
	计算待显示数字的位数
*/
always @(posedge clk,negedge reset ) begin
    if(!reset) begin
        disp_num_bit <= 3'd0;
    end
    else if(en && (disp_num < 4'd10)) begin
        disp_num_bit <= 3'd0;
    end
	else if(en && (disp_num < 7'd100)) begin
        disp_num_bit <= 3'd1;
    end
	else if(en && (disp_num < 10'd1000)) begin
        disp_num_bit <= 3'd2;
    end
	else if(en && (disp_num < 14'd10000)) begin
        disp_num_bit <= 3'd3;
    end
	else if(en && (disp_num < 17'd100000)) begin
        disp_num_bit <= 3'd4;
    end
	else if(en && (disp_num < 20'd1000000)) begin
        disp_num_bit <= 3'd5;
    end
    else if(en && (disp_num == 20'd999999))begin
        disp_num_bit <= 3'd0;
    end 
	else begin
        disp_num_bit <= disp_num_bit;
    end 	
end

/* 
	位选控制 sel_ctrl 切换,en2产生周期1ms
	
	sel_ctrl = 0, 位选信号 = 6'b11_1110,即选择第1个数码管
	sel_ctrl = 1, 位选信号 = 6'b11_1101,即选择第2个数码管
	sel_ctrl = 2, 位选信号 = 6'b11_1011,即选择第3个数码管
	sel_ctrl = 3, 位选信号 = 6'b11_0111,即选择第4个数码管
	sel_ctrl = 4, 位选信号 = 6'b10_1111,即选择第5个数码管
	sel_ctrl = 5, 位选信号 = 6'b01_1111,即选择第6个数码管
*/
/*
always @(posedge clk,negedge reset ) begin
    if(!reset) begin
        sel_ctrl <= 3'd0;
    end
    else if(en2 && (sel_ctrl < 3'd5)) begin
        sel_ctrl <= sel_ctrl + 1'b1;
    end
	else if(en2 && (sel_ctrl == 3'd5)) begin
        sel_ctrl <= 3'd0;
    end
    else begin
        sel_ctrl <= sel_ctrl;
    end    
end
*/
always @(posedge clk,negedge reset ) begin
    if(!reset) begin
        sel_ctrl <= 3'd0;
    end
    else if(en2 && (sel_ctrl < disp_num_bit)) begin
        sel_ctrl <= sel_ctrl + 1'b1;
    end
	else if(en2 && (sel_ctrl == disp_num_bit)) begin
        sel_ctrl <= 3'd0;
    end
    else begin
        sel_ctrl <= sel_ctrl;
    end    
end

/* 
	输出位选信号sel(采用独热码)和段选信号 seg_led, 执行周期1ms	
	
	设计思路
	举例:如何显示数字 “654321”	
		第1ms,显示第1个数码管“1”
		第2ms,显示第2个数码管“2”
		第3ms,显示第3个数码管“3”
		第4ms,显示第4个数码管“4”
		第5ms,显示第5个数码管“5”
		第6ms,显示第6个数码管“6”	
	由于切换周期1ms,即6ms可以将6个数字 “654321”依次显示出来,
	同时由于视觉暂留的影响,显示数字“6”时,数字“1”、“2”、“3”、“4”、“5”仍然还能看到
	我们人眼看到的效果跟6个数字同时显示出来的效果是一样的。
	
	因此我们需要做的就是:
	
	第0ms,显示第1个数码管“1”, 位选信号 sel = 6'b11_1110,段选信号 seg_led = “data0对应的字符”
	第1ms,显示第2个数码管“2”, 位选信号 sel = 6'b11_1101,段选信号 seg_led = “data1对应的字符”
	第2ms,显示第3个数码管“3”, 位选信号 sel = 6'b11_1011,段选信号 seg_led = “data2对应的字符”
	第3ms,显示第4个数码管“4”, 位选信号 sel = 6'b11_0111,段选信号 seg_led = “data3对应的字符”
	第4ms,显示第5个数码管“5”, 位选信号 sel = 6'b10_1111,段选信号 seg_led = “data4对应的字符”
	第5ms,显示第6个数码管“6”, 位选信号 sel = 6'b01_1111,段选信号 seg_led = “data5对应的字符”
	
*/
always @(posedge clk ,negedge reset) begin
    if(!reset) begin	
        sel <= 6'b11_1110;
		seg_led <= CHAR_0;
    end
    else if(en2) begin		
		casex (sel_ctrl)
            3'd0: begin 
				sel <= 6'b11_1110;					
				if(data0==0)
					seg_led <= CHAR_0;
				else if(data0==1)
					seg_led <= CHAR_1;
				else if(data0==2)
					seg_led <= CHAR_2;
				else if(data0==3)
					seg_led <= CHAR_3;
				else if(data0==4)
					seg_led <= CHAR_4;	
				else if(data0==5)
					seg_led <= CHAR_5;
				else if(data0==6)
					seg_led <= CHAR_6;
				else if(data0==7)
					seg_led <= CHAR_7;
				else if(data0==8)
					seg_led <= CHAR_8;	
				else if(data0==9)
					seg_led <= CHAR_9;	
				else
					seg_led <= CHAR_0;
            end
            3'd1: begin 
				sel <= 6'b11_1101;
				if(data1==0)
					seg_led <= CHAR_0;
				else if(data1==1)
					seg_led <= CHAR_1;
				else if(data1==2)
					seg_led <= CHAR_2;
				else if(data1==3)
					seg_led <= CHAR_3;
				else if(data1==4)
					seg_led <= CHAR_4;	
				else if(data1==5)
					seg_led <= CHAR_5;
				else if(data1==6)
					seg_led <= CHAR_6;
				else if(data1==7)
					seg_led <= CHAR_7;
				else if(data1==8)
					seg_led <= CHAR_8;	
				else if(data1==9)
					seg_led <= CHAR_9;	
				else
					seg_led <= CHAR_0;
            end
            3'd2: begin 
				sel <= 6'b11_1011;
				if(data2==0)
					seg_led <= CHAR_0;
				else if(data2==1)
					seg_led <= CHAR_1;
				else if(data2==2)
					seg_led <= CHAR_2;
				else if(data2==3)
					seg_led <= CHAR_3;
				else if(data2==4)
					seg_led <= CHAR_4;	
				else if(data2==5)
					seg_led <= CHAR_5;
				else if(data2==6)
					seg_led <= CHAR_6;
				else if(data2==7)
					seg_led <= CHAR_7;
				else if(data2==8)
					seg_led <= CHAR_8;	
				else if(data2==9)
					seg_led <= CHAR_9;	
				else
					seg_led <= CHAR_0;
            end
            3'd3: begin 
				sel <= 6'b11_0111;
				if(data3==0)
					seg_led <= CHAR_0;
				else if(data3==1)
					seg_led <= CHAR_1;
				else if(data3==2)
					seg_led <= CHAR_2;
				else if(data3==3)
					seg_led <= CHAR_3;
				else if(data3==4)
					seg_led <= CHAR_4;	
				else if(data3==5)
					seg_led <= CHAR_5;
				else if(data3==6)
					seg_led <= CHAR_6;
				else if(data3==7)
					seg_led <= CHAR_7;
				else if(data3==8)
					seg_led <= CHAR_8;	
				else if(data3==9)
					seg_led <= CHAR_9;	
				else
					seg_led <= CHAR_0;
				
            end
            3'd4: begin 
				sel <= 6'b10_1111;
				if(data4==0)
					seg_led <= CHAR_0;
				else if(data4==1)
					seg_led <= CHAR_1;
				else if(data4==2)
					seg_led <= CHAR_2;
				else if(data4==3)
					seg_led <= CHAR_3;
				else if(data4==4)
					seg_led <= CHAR_4;	
				else if(data4==5)
					seg_led <= CHAR_5;
				else if(data4==6)
					seg_led <= CHAR_6;
				else if(data4==7)
					seg_led <= CHAR_7;
				else if(data4==8)
					seg_led <= CHAR_8;	
				else if(data4==9)
					seg_led <= CHAR_9;	
				else
					seg_led <= CHAR_0;
            end
            3'd5: begin 
				sel <= 6'b01_1111;
				if(data5==0)
					seg_led <= CHAR_0;
				else if(data5==1)
					seg_led <= CHAR_1;
				else if(data5==2)
					seg_led <= CHAR_2;
				else if(data5==3)
					seg_led <= CHAR_3;
				else if(data5==4)
					seg_led <= CHAR_4;	
				else if(data5==5)
					seg_led <= CHAR_5;
				else if(data5==6)
					seg_led <= CHAR_6;
				else if(data5==7)
					seg_led <= CHAR_7;
				else if(data5==8)
					seg_led <= CHAR_8;	
				else if(data5==9)
					seg_led <= CHAR_9;	
				else
					seg_led <= CHAR_0;
            end 
            default: begin
				sel <= 6'b11_1110;
				if(data0==0)
					seg_led <= CHAR_0;
				else if(data0==1)
					seg_led <= CHAR_1;
				else if(data0==2)
					seg_led <= CHAR_2;
				else if(data0==3)
					seg_led <= CHAR_3;
				else if(data0==4)
					seg_led <= CHAR_4;	
				else if(data0==5)
					seg_led <= CHAR_5;
				else if(data0==6)
					seg_led <= CHAR_6;
				else if(data0==7)
					seg_led <= CHAR_7;
				else if(data0==8)
					seg_led <= CHAR_8;	
				else if(data0==9)
					seg_led <= CHAR_9;	
				else
					seg_led <= CHAR_0;
            end
        endcase    
    end
    else begin
        sel <= sel;
		seg_led <= seg_led;
    end
end

    
endmodule

四.modelsim前仿真(功能仿真)

        每次打开modelsim时需要切换工作空间,否则可能创建工程添加的源码会是上一个仿真工程的代码,导致出错 。

        使用vscode打开segled_static_top.v, ctrl+shift+p,输入testbench,在terminal生成了segled_static_top_tb.v代码,需要安装插件verilog_testbench, 初始生成时可能提示失败,需要安装 python 库(根据错误提示自行百度)。

        生成的代码有点错误,需要自己再做点修改。

开发板实战篇3 6位数码管动态显示

        tb_segled_dy_top.v,

        为了方便减小了计数器周期为4'd10,2'd2。

`timescale  1ns / 1ns

module tb_segled_dy_top;

// segled_static_top Parameters
parameter PERIOD          = 10            ;     
parameter COUNT_OVERFLOW  = 4'd10;     
parameter COUNT_OVERFLOW2  = 2'd2;     

// segled_static_top Inputs
reg   clk                                  = 0 ;
reg   reset                                = 0 ;

// segled_static_top Outputs
wire  [5:0]  sel                           ;    
wire  [7:0]  seg_led                       ;    


initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

initial
begin
    #(PERIOD*2) reset  =  1;
end

segled_dy_top #(
    .COUNT_OVERFLOW ( COUNT_OVERFLOW ),
    .COUNT_OVERFLOW2 ( COUNT_OVERFLOW2 ))
 u_segled_dy_top (
    .clk                     ( clk            ),
    .reset                   ( reset          ),
	
    .sel                     ( sel      [5:0] ),
    .seg_led                 ( seg_led  [7:0] )
);


endmodule

        仿真波形

开发板实战篇3 6位数码管动态显示

 

五.下载验证

        FPGA开发板上的6位数码管以动态方式从0开始计数,每100ms计数值增加一,当计数值从0增加到999999后重新从0开始计数。

        但是发现4个LED有微弱的亮度,需要配置好未使用管脚的状态为高阻输入,同时将nCEO管脚修改为Use as regular I/0,修改后LED变为熄灭状态了。

        在 Quartus 软件中默认未使用管脚的状态为弱上拉输入,所以未使用到的管脚上也是有电压的,只是驱动能力很弱,这往往会导致一些不安全的隐患,所以我们需要将未使用管脚的状态设置为三态输入。        

开发板实战篇3 6位数码管动态显示

        在左侧Category一栏中选择Dual-Purpose Pin。对于需要使用EPCS器件的引脚时,需要将下图页面中所有的引脚都改成Use as regular IO,如果大家不确定工程中是否用到EPCS器件时,可以全部修改。本次实验只修改了nCEO一栏中, 将Use as programming pin修改为Use as regular I/0。

开发板实战篇3 6位数码管动态显示文章来源地址https://www.toymoban.com/news/detail-495218.html

到了这里,关于开发板实战篇3 6位数码管动态显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 单片机——数码管动态显示

    1.头文件和定义,代码还使用了 sbit 定义来声明了两个变量 duan 和 wei,它们实际上是 P2.6 和 P2.7 端口的别名,用于控制数码管的段选和位选信号。这种方法可以使代码更具可读性,并提高代码的可维护性。定义无符号整数便于后面应用。 2.使用一个 16 个元素的数组 table,该数

    2024年02月11日
    浏览(43)
  • FPGA学习之数码管时间显示模块

    在学习完小梅哥的串口通信以及数码管显示教程后,他留下了一个课后作业,也就是本次的数码管时间显示模块。作为一个FPGA新人,这也算是第一个比较完整的练手小项目了,也推荐和我一样的新人花时间去完成一下。总体功能虽然比较简单,但是我也花了小两天的时间去编

    2024年03月10日
    浏览(63)
  • FPGA(5)数码管静态显示与动态显示

    目录 一、数码管静态显示 二、数码管动态显示 1、变量定义 2、定时(60us) 3、动态显示 代码 FPGA的数码管有4位,8段 。( 位和段都是共阳,即低电平有效 )     位选的4位(二进制):分别为第1、2、3、4位数码管。 段选的8位(二进制):分别为第h、g、f、e、d、c、b、a段

    2023年04月12日
    浏览(46)
  • [FPGA 学习记录] 数码管动态显示

    数码管动态显示 在上一小节当中,我们对数码管的静态显示做了一个详细的讲解;但是如果单单只掌握数码管的静态显示这种显示方式是远远不够的,因为数码管的静态显示当中,被选中的数码位它们显示的内容都是相同的,这种显示方式在我们的实际应用当中显然是不合适

    2024年02月04日
    浏览(53)
  • 实验三 基于FPGA的数码管动态扫描电路设计 quartus/数码管/电路模块设计

    源文件的链接放在最后啦 实验目的: (1) 熟悉7段数码管显示译码电路的设计。 (2) 掌握数码管显示原理及静态、动态扫描电路的设计。 实验任务: (1) 基本任务1:利用FPGA硬件平台上的4位数码管做静态显示,用SW0-3输入BCD码,用SW4-7控制数码管位选; (2) 基本任务

    2024年02月07日
    浏览(59)
  • C51单片机-共阳极数码管循环显示数字0至9,共阴极数码管循环显示5201314(动态)

    keil uVision4界面: proteus仿真界面:

    2024年02月06日
    浏览(58)
  • 单片机-如何让数码管动态显示

    单片机IO口输出难稳定,需要数码管与单片机连接需要增加驱动电路, 使用 74HC245 abcdefgDP并联导出  74HC245 对数码管进行驱动,P0 是输出电流 来驱动各个段的 驱动芯片 增加电阻 是为了防止电流过大烧坏数码管 。P0输出段选的 共阴 就是所有阴极 连接 在一起,连接在公共端

    2024年02月09日
    浏览(50)
  • 51单片机控制数码管动态显示

    首先打开proteus,导入8位数码管和89c51。 然后如图连线,分清断码和位码, 断码就是一个数码管的7个LED灯。 位码:就是第几位显示,由于是共阴极,所以哪位接地就显示哪位。 下面通过改变位码的接线就可以看出不同的效果 下面就编写程序,从第1位到第8位显示从0到7的八

    2023年04月21日
    浏览(47)
  • 二、19【FPGA】数码管动态显示实验

    学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。 学习视频:是根据野火FPGA视频教程——第二十二讲 https://www.bilibili.com/video/BV1nQ4y1Z7zN?p=3 “天下武功唯快不破”    “看到的不一定为真” 眼睛的视觉暂留:光信号传入大脑需要短暂时间,

    2023年04月08日
    浏览(39)
  • STM32-GPIO数码管动态显示

    目录 一、数码管原理 1、LED数码管的结构 2、LED数码管工作原理 3、数码管动态显示 1)动态显示的概念 2)动态显示的接口 二、代码的实现 三、仿真结果展示   本篇文章将继续进一步了解GPIO外设输出模式 知道这一部分的朋友可以直接点击目录部分跳过这段跳过 ,这里介绍

    2023年04月08日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包