DSP SPI串行外设接口

1.SPI介绍

1.1 SPI简介

SPI的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器,还有数字信号处理器和数字信号解码器之间。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线。

SPI内部结构简易图

 

SPI 主要特点有: 可以同时发出和接收串行数据; 可以当作主机或从机工作; 提供频率可编程时钟; 发送结束中断标志; 写冲突保护; 总线竞争保护等。

1.2 F28335 的 SPI 模块介绍

①4 个外部引脚:

SPISOMI:SPI 从输出/主输入引脚。

SPISIMO:SPI 从输入/主输出引脚。

SPISTE:SPI 从发送使能引脚。

SPICLK:SPI 串行时钟引脚。

②2 种工作方式:主、从工作方式

③波特率:125 种可编程波特率。

④数据字长:可编程的 1-16 个数据长度。

⑤4 种时钟模式(由时钟极性和时钟相位控制)

--无相位延时的下降沿;SPICLK 为高电平有效。在 SPICLK 信号的下降沿发 送数据,在 SPICLK 信号的上升沿接收数据。

--有相位延时的下降沿:SPICLK 为高电平有效。在 SPICLK 信号的下降沿之 前的半个周期发送数据,在 SPICLK 信号的下降沿接收数据。

--无相位延时的上升沿:SPICLK 为低电平有效。在 SPICLK 信号的上升沿发 送数据,在SPICLK 信号的下降沿接收数据。

--有相位延时的上升沿:SPICLK 为低电平有效。在 SPICLK 信号的下降沿之 前的半个周期发送数据,而在 SPICLK 信号的上升沿接收数据。

 

⑥接收和发送可同时操作(可以通过软件屏蔽发送功能)。通过中断或查询 方式实现发送和接收操作。9个SPI 模块控制寄存器。

⑦增强特点:

--16 级发送/接收 FIFO。

--延时发送控制。

1.3 SPI 内部结构框图

 1.4 F28335 的 SPI 两种工作模式

 

主控制器发送 SPICLK 信号时,也启动了数据传输。无论是主控制器还是从 控制器,数据都是在 SPICLK 边沿时移出移位寄存器,并且在相反的边沿锁存进 移位寄存器。如果 CLOCK PHASE(SPICTL.3)位为高电平,则数据在 SPICLK 跳 变之前的半个周期被发送和接收。因此两个控制器的数据的接收与发送是同步 的。应用软件决定数据是否有用还是仅仅是占位的无意义数据。数据传输的时候 有 3 种可能形式:

①主机发送数据,从机发送伪数据。

②主机发送数据,从机发送数据。

③主机发送伪数据,从机发送数据。

主控制器因为控制着 SPICLK 信号,所以可以在任何时候启动数据传输。然 而软件决定着当从控制器已经准备好数据传输时主控制器如何检测到。

SPI 的工作模式通过主/从位(MASTER/SLAVE 位 SPICTL.2)进行选择

1.5 SPI的数据传输

SPI 接口数据传输时一共有 3 种模式:简单模式、基本模式和增强模式。下 面分别介绍这 3 种模式。

在简单工作模式下,SPI 可以通过一位寄存器实现数据交换,即通过 SPIDAT 寄存器移入或移出数据。在发送数据帧的过程中将 16 位数据发送到 SPITXBUF 缓冲,直接从 SPIRXBUF 读取接收到的数据帧。

在基本操作模式下,接收操作采用双缓冲,也就是在新的接收操作启动时, CPU 可以暂时不读取 SPIRXBUF 中接收到的数据,但是在新的接收操作完成之前 必须读取 SPIRXBUF,否则将会覆盖原来接收到的数据。在这种模式下,发送操 作不支持双缓冲操作。在下一个字写到 SPITXDAT 寄存器之前必须将当前的数据 发送出去,否则会导致当前的数据损坏。由于主设备控制 SPICLK 时钟信号,它 可以在任何时候配置数据传输。

在增强的 FIFO 缓冲模式下,用户可以建立 16 级深度的发送和接收缓冲,而 对于程序操作仍然使用 SPITXBUF 和 SPIRXBUF 寄存器。这样可以使 SPI 具有接收 或发送 16 次数据的能力。此种模式下还可以根据两个 FIFO 的数据装载状态确定 其中断级别。SPI 接口的内部功能如下图所示:

 

F28335 的 SPI 主要为后 2 中操作模式:基本操作模式和增强的 FIFO 缓冲模式。

SPI 主设备负责产生系统时钟,并决定整个 SPI 网络的通信速率。所有的 SPI 设备都采用相同的接口方式,可以通过调整处理器内部寄存器改变时钟的极性和 相位。由于 SPI 器件并不一定遵循同一个标准,比如 EEPROM、DAC、ADC、实时 时钟及温度传感器等器件的 SPI 接口的时序都有所不同,为了能够满足不同的接 口需要,采用时钟的极性和相位可配置就能够调整 SPI 的通信时序。

SPI 设备传输数据过程中总是先发送或接受高字节数据,每个时钟周期接收 器或收发器左移 1 位数据。对于小于 16 位的数据发送之前必须左对齐,如果接 收的数据小于 16 位则采用软件将无效的位屏蔽。

1.6 FIFO操作

下面我们通过具体的步骤来讲述下 FIFO 的特点,在使用 SPI FIFO 功能时, 这些步骤有助于编程。系统在上电复位时,SPI 工作在标准 SPI 模式,禁止 FIFO 功能。FIFO 的寄存器 SPIFFTX、SPIFFRX 和 SPIFFCT 不起作用。通过将 SPIFFTX 寄存器中的 SPIFFEN 的位置为 1,使能 FIFO 模式。SPIRST 能在操作的任一阶段 复位 FIFO 模式。

FIFO 模式有 2 个中断,一个用于发送 FIFO、SPITXINT,另一个用于接收 FIFO、 SPIINT/SPIRXINT。对于 SPI FIFO 接收来说,产生接收错误或者接收 FIFO 溢出 都会产生 SPIINT/SPIRXINT 中断。对于标准 SPI 的发送和接收,唯一的 SPIINT 将被禁止且这个中断将服务于 SPI 接收 FIFO 中断。发送和接收都能产生 CPU 中 断。一旦发送 FIFO 状态位 TXFFST(位 12-8)和中断触发级别位 TXFFIL 匹配, 就会触发中断。这给 SPI 的发送和接收提供了可编程的中断触发器。接收 FIFO的触发级别位的默认值是0x11111,发送FIFO的触发级别位的默认值是0x00000。

发送和接收缓冲器使用 2 个 16*16FIFO,标准 SPI 功能的一个字的发送缓冲 器作为在发送 FIFO 和移位寄存器间的发送缓冲器。移位寄存器的最后一位被移 出后,发送缓冲器中的这一个字符将从发送 FIFO 装载。FIFO 中的自发送到发送 移位寄存器的速率是可编程的。SPIFFCT 寄存器位 FFTXDLY7-FFTXDLY0 定义了在 两个字节发送间的延时,这个延时以 SPI 串行时钟周期的数量来定义。该 8 位寄 存器可以定义最小 0 个串行时钟周期的延时和最大 256 个串行时钟周期的延时。 0 时钟周期延时的 SPI 模块能将 FIFO 字一位紧接一位的移位,连续发送数据。 256 个时钟周期延时的 SPI 模块能在最大延时模式下发送数据,每个 FIFO 字的 移位间隔 256 个 SPI 时钟周期的延时。可编程延时的特点,使得 SPI 接口可以方 便的同许多速率较慢的 SPI 外设如 EEPROM、ADC、DAC 等直接连接。

发送和接收 FIFO 都有状态位 TXFFST 或 RXFFST,状态位定义在任何时刻在 FIFO 中可或得的字的数量。当发送 FIFO 复位位 TXFIFO 和接收复位位 RXFIFO 被 设置为 1 时,FIFO 指针指向 0。一旦这两个复位位被清除为 0,则 FIFO 将重新 开始操作。

1.6 SPI 相关寄存器介绍

SPI 模块相关寄存器主要有如下部分:

SPI 波特率设置寄存器(SPIBRR):

SPI 模块支持 125 种不同的波特率和 4 种不同时钟方式。当 SPI 工作在主模 式时,SPICLK 引脚为通信网络提供的时钟;当 SPI 工作在从模式时,SPICLK 引 脚接收外部时钟信号。

在从模式下,SPI 时钟的 SPICLK 引脚使用外部时钟源,而且要求该时钟信号 的频率不能大于 CPU 时钟的 1/4。在主模式下,SPICLK 引脚想网络输出时钟,并 且该时钟频率不能大于 LSPCLK 频率的 1/4。

SPI 波特率的计算公式如下:

①当 SPIBRR=3~127 时:SPI 波特率=LSPCLK/(SPIBRR+1)

②当 SPIBRR=0、1 或 2 时:SPI 波特率=LSPCLK/4

其中:LSPCLK 为 DSP 的低速外设时钟频率;SPIBRR 为主动 SPI 模块 SPIBRR 的值。 要确定 SPIBRR 需要设置的值,用户必须知道 DSP 的系统时钟 LSPCLK 频率和 用户希望使用的通信波特率。该寄存器各位功能描述如下:

 2.SPI配置步骤

SPI 相关库函数在DSP2833x_Spi.c 和 DSP2833x_Spi.h 文件中

(1)使能 SPI 外设时钟及初始化对应 GPIO

EALLOW;
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A
EDIS;

InitSpiaGpio();

(2)SPI 工作方式及参数设置,包括数据格式、相位极性、FIFO 功能等

// Initialize SPI FIFO registers
SpiaRegs.SPIFFTX.all=0xE040;//使能 FIFO,清除发送中断
SpiaRegs.SPIFFRX.all=0x204f;//使能 FIFO 接收 16 级深度
SpiaRegs.SPIFFCT.all=0x0;//清除 FIFO 计数器
SpiaRegs.SPICCR.all =0x000F;//复位 SPI,上升沿发送,下降沿接收,16位数据
SpiaRegs.SPICTL.all =0x0006;// 无相位延时,主模式
SpiaRegs.SPIBRR =0x007F;//确定 SPICLK
SpiaRegs.SPICCR.all =0x009F;//自测模式并从复位状态释放
SpiaRegs.SPIPRI.bit.FREE = 1;//自由运行

(3)SPI 发送和接收函数

Uint16 SPIA_SendReciveData(Uint16 dat)
{
    // Transmit data
    SpiaRegs.SPITXBUF=dat;

    // Wait until data is received
    while(SpiaRegs.SPIFFRX.bit.RXFFST !=1);
    return SpiaRegs.SPIRXBUF;
}

3.硬件设计

本实验使用到硬件资源如下:

(1)D1 指示灯

(2)RS232 模块

(3)SPI

 4.软件设计

本章所要实现的功能是:使用 SPI 实现数据的自发自收,通过串口将收发的数据输出显示,并且 D1 指示灯闪烁,指示系统运行状态。程序框架如下:

(1)SPI loopback

void InitSpiaGpio()
{

   EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.  
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.


//    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;   // Enable pull-up on GPIO16 (SPISIMOA)
//	GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;   // Enable pull-up on GPIO17 (SPISOMIA)
//	GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;   // Enable pull-up on GPIO18 (SPICLKA)
//	GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;   // Enable pull-up on GPIO19 (SPISTEA)

    GpioCtrlRegs.GPBPUD.bit.GPIO54 = 0;   // Enable pull-up on GPIO54 (SPISIMOA)
    GpioCtrlRegs.GPBPUD.bit.GPIO55 = 0;   // Enable pull-up on GPIO55 (SPISOMIA)
    GpioCtrlRegs.GPBPUD.bit.GPIO56 = 0;   // Enable pull-up on GPIO56 (SPICLKA)
    GpioCtrlRegs.GPBPUD.bit.GPIO57 = 0;   // Enable pull-up on GPIO57 (SPISTEA)

/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

//    GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)

    GpioCtrlRegs.GPBQSEL2.bit.GPIO54 = 3; // Asynch input GPIO16 (SPISIMOA)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO55 = 3; // Asynch input GPIO17 (SPISOMIA)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO56 = 3; // Asynch input GPIO18 (SPICLKA)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO57 = 3; // Asynch input GPIO19 (SPISTEA)
    
/* Configure SPI-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SPI functional pins.
// Comment out other unwanted lines.

//    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
//    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
//    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
//    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

    GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 1; // Configure GPIO54 as SPISIMOA
    GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 1; // Configure GPIO55 as SPISOMIA
    GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 1; // Configure GPIO56 as SPICLKA
    GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 1; // Configure GPIO57 as SPISTEA

    EDIS;
}

void SPIA_Init(void)
{
	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;   // SPI-A
	EDIS;

	InitSpiaGpio();

	// Initialize SPI FIFO registers
	SpiaRegs.SPIFFTX.all=0xE040;
	SpiaRegs.SPIFFRX.all=0x204f;
	SpiaRegs.SPIFFCT.all=0x0;


	SpiaRegs.SPICCR.all =0x000F;	             // Reset on, rising edge, 16-bit char bits
	SpiaRegs.SPICTL.all =0x0006;    		     // Enable master mode, normal phase,
	                                                 // enable talk, and SPI int disabled.
	SpiaRegs.SPIBRR =0x007F;
	SpiaRegs.SPICCR.all =0x009F;		         // Relinquish SPI from Reset
	SpiaRegs.SPIPRI.bit.FREE = 1;                // Set so breakpoints don't disturb xmission

}

Uint16 SPIA_SendReciveData(Uint16 dat)
{
	// Transmit data
	SpiaRegs.SPITXBUF=dat;

	// Wait until data is received
	while(SpiaRegs.SPIFFRX.bit.RXFFST !=1);

	return SpiaRegs.SPIRXBUF;
}

void main()
{
	int i=0;
	Uint16 senddata=0;
	Uint16 recdata=0;
	char str[40];

	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);
	SPIA_Init();

	while(1)
	{
		i++;
		if(i%500==0)
		{
			recdata=SPIA_SendReciveData(senddata++);
			sprintf(str,"senddata=%d    recdata=%d\r\n",senddata,recdata);
			UARTa_SendString(str);
		}
		DELAY_US(1000);
	}
}

(2)SPI loopback interrupt

void InitSpiaGpio()
{

   EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.  
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPBPUD.bit.GPIO54 = 0;   // Enable pull-up on GPIO54 (SPISIMOA)
    GpioCtrlRegs.GPBPUD.bit.GPIO55 = 0;   // Enable pull-up on GPIO55 (SPISOMIA)
    GpioCtrlRegs.GPBPUD.bit.GPIO56 = 0;   // Enable pull-up on GPIO56 (SPICLKA)
    GpioCtrlRegs.GPBPUD.bit.GPIO57 = 0;   // Enable pull-up on GPIO57 (SPISTEA)


//    GpioCtrlRegs.GPBPUD.bit.GPIO54 = 0;   // Enable pull-up on GPIO54 (SPISIMOA)
//    GpioCtrlRegs.GPBPUD.bit.GPIO55 = 0;   // Enable pull-up on GPIO55 (SPISOMIA)
//    GpioCtrlRegs.GPBPUD.bit.GPIO56 = 0;   // Enable pull-up on GPIO56 (SPICLKA)
//    GpioCtrlRegs.GPBPUD.bit.GPIO57 = 0;   // Enable pull-up on GPIO57 (SPISTEA)

/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

//    GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)

    GpioCtrlRegs.GPBQSEL2.bit.GPIO54 = 3; // Asynch input GPIO16 (SPISIMOA)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO55 = 3; // Asynch input GPIO17 (SPISOMIA)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO56 = 3; // Asynch input GPIO18 (SPICLKA)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO57 = 3; // Asynch input GPIO19 (SPISTEA)

    
/* Configure SPI-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SPI functional pins.
// Comment out other unwanted lines.

//    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
//    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
//    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
//    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

    GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 1; // Configure GPIO54 as SPISIMOA
    GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 1; // Configure GPIO55 as SPISOMIA
    GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 1; // Configure GPIO56 as SPICLKA
    GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 1; // Configure GPIO57 as SPISTEA

    EDIS;
}

interrupt void spiTxFifoIsr(void)
{
 	Uint16 i;
    for(i=0;i<8;i++)
    {
 	   SpiaRegs.SPITXBUF=sdata[i];      // Send data
    }

    for(i=0;i<8;i++)                    // Increment data for next cycle
    {
 	   sdata[i]++;
    }


    SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1;  // Clear Interrupt flag
	PieCtrlRegs.PIEACK.all|=0x20;  		// Issue PIE ACK
}

interrupt void spiRxFifoIsr(void)
{
    Uint16 i;
    for(i=0;i<8;i++)
    {
	    rdata[i]=SpiaRegs.SPIRXBUF;		// Read data
	}
	for(i=0;i<8;i++)                    // Check received data
	{
	    if(rdata[i] != rdata_point+i) spi_error(); //运行一段时间后,在此处设置断点
	}
	rdata_point++;
	SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1;  // Clear Overflow flag
	SpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; 	// Clear Interrupt flag
	PieCtrlRegs.PIEACK.all|=0x20;       // Issue PIE ack
}

void SPIA_INT_Init(void)
{
	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;   // SPI-A
	EDIS;

	InitSpiaGpio();

	// Interrupts that are used in this example are re-mapped to
	// ISR functions found within this file.
	EALLOW;	// This is needed to write to EALLOW protected registers
	PieVectTable.SPIRXINTA = &spiRxFifoIsr;
	PieVectTable.SPITXINTA = &spiTxFifoIsr;
	EDIS;   // This is needed to disable write to EALLOW protected registers


	// Initialize SPI FIFO registers
	SpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI

	SpiaRegs.SPICCR.all=0x001F;       //16-bit character, Loopback mode
	SpiaRegs.SPICTL.all=0x0017;       //Interrupt enabled, Master/Slave XMIT enabled
	SpiaRegs.SPISTS.all=0x0000;
	SpiaRegs.SPIBRR=0x0063;           // Baud rate
	SpiaRegs.SPIFFTX.all=0xC028;      // Enable FIFO's, set TX FIFO level to 8
	SpiaRegs.SPIFFRX.all=0x0028;      // Set RX FIFO level to 8
	SpiaRegs.SPIFFCT.all=0x00;
	SpiaRegs.SPIPRI.all=0x0010;

	SpiaRegs.SPICCR.bit.SPISWRESET=1;  // Enable SPI

	SpiaRegs.SPIFFTX.bit.TXFIFO=1;
	SpiaRegs.SPIFFRX.bit.RXFIFORESET=1;

	// Enable interrupts required for this example
	PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
	PieCtrlRegs.PIEIER6.bit.INTx1=1;     // Enable PIE Group 6, INT 1
	PieCtrlRegs.PIEIER6.bit.INTx2=1;     // Enable PIE Group 6, INT 2
	IER=0x20;                            // Enable CPU INT6
	EINT;                                // Enable Global Interrupts

}

void SPIA_INTFIFO_Test(void)
{
	unsigned char i=0;

	for(i=0; i<8; i++)
	{
		sdata[i] = i;
	}
	rdata_point = 0;

	SPIA_INT_Init();

}

void main()
{
	int i=0;


	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);

	SPIA_INTFIFO_Test();

	while(1)
	{

	}
}
  • 2
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值