STC15单片机-无线通讯(WIFI模块)

无线通讯(WIFI模块)

ESP8266系列模组

ESP8266 系列模组是深圳市安信可科技有限公司开发的一系列基于乐鑫ESP8266EX的低功耗UART-WiFi芯片模组,可以方便地进行二次开发,接入云端服务,实现手机3/4G全球随时随地的控制,加速产品原型设计。

模块核心处理器 ESP8266 在较小尺寸封装中集成了业界领先的 Tensilica L106 超低功耗 32 位微型 MCU,带有 16 位精简模式,主频支持 80 MHz 和 160 MHz,支持 RTOS,集成 Wi-Fi MAC/ BB/RF/PA/LNA,板载天线。支持标准的 IEEE802.11 b/g/n 协议,完整的 TCP/IP 协议栈。用户可以使用该模块为现有的设备添加联网功能,也可以构建独立的网络控制器。

ESP8266 是高性能无线 SoC,以最低成本提供最大实用性,为 Wi-Fi 功能嵌入其他系统提供无限可能。

SoC称为系统级芯片,也有称片上系统,意指它是一个产品,是一个有专用目标的集成电路,其中包含完整系统并有嵌入软件的全部内容。同时它又是一种技术,用以实现从确定系统功能开始,到软/硬件划分,并完成设计的整个过程

ESP-12S

开发板上的WIFI模块使用的是安信可公司的ESP-12S型号

在这里插入图片描述

在这里插入图片描述

WIFI模块的规格书可以在安信可官网上找到

乐鑫和安信可

乐鑫和安信可的关系,其实大可理解为ARM与ST、NXP的关系,ARM负责设计CPU内核,然后将设计授权给ST、NXP这些芯片厂商,芯片厂商在内核之上添加必要的外设和自己家有特色的外设,就可以生产我们每天都用的MCU了。

乐鑫是芯片原厂,在研制ESP系列芯片(eg. ESP8266)之外,提供了上层的ESP-IDF操作系统及各类应用框架,以及国内外常用的云平台对接方案。

安信可则是乐鑫的大客户,负责生产基于ESP系列芯片的模组,开发者到手就能进行开发,所以一般我们手里的ESP系列模组都是安信可科技的。同时,乐鑫也提供自己的模组。

在这里插入图片描述

程序

实现功能

开发板每隔500ms获取PCB板的温度,并且在数码管上显示

长按按键1进入配网模式,可在安信可公众号进行配网

当WIFI模块连接上TCP服务器后,开启透传模式,发送PCB板的温度到服务器上

当WIFI模块没连接上TCP服务器时,每隔10s自动重连

文件结构

在这里插入图片描述

main.c ->主函数文件,包含main函数等,程序主要逻辑控制;

Public.c ->公共函数文件,包含Delay延时函数,Memory_Clr内存清除函数,Error_Handler错误处理函数,Sys_Soft_Reset系统软件复位函数;

Sys_init ->系统初始化函数,包含GPIO初始化函数等;

KEY1.c->按键1检测函数;

UART1.c->串口1初始化函数;

ADC.c ->ADC初始化,采集ADC值等;

NTC.c ->NTC外设函数,包含查表,获取环境温度等;

TM1620.c ->驱动IC初始化,协议,温度显示等函数;

UART2.c->串口2初始化函数,发送字符,字符串,数组函数,串口2中断服务函数;

ESP8266.c->WIFI模块函数,包含模块初始化、配网、通过TCP连接服务器、传送PCB板温度、接收信息

代码量太大,只对关键的地方和要注意的点进行记录

STC15L2K32S2单片机串口2配置

与串口1的头文件代码一样,要注意串口2的引脚跟串口1不同,TX是P11,RX是P10;串口2的使用方法与串口1相同

在UART2.c源文件中,可以将串口1的先全部复制过来,然后再修改为串口2的相关寄存器

在这里插入图片描述

因为P_SW2的BIT0位默认是0,所以串口2默认映射到P10和P11口,刚好接的是WiFi模块的TXD0和RXD0,所以P_SW2不用配置;其他寄存器就根据数据手册进行配置即可,定时器2的高8位和低8位是T2H和T2L,这个也要注意改

注意:所有的UART1都要改为UART2

SBUF改为S2BUF

后面发送一个字节、发送字符串和发送数组的函数与串口1的一样,只是把UART1改为UART2即可

/*
* @name   Init
* @brief  串口2初始化
* @param  None
* @retval None   
*/
static void Init()
{
    /*P_SW2 外围设备功能切换控制寄存器2(不可位寻址)的BIT0位默认为0,即串口2切换位S2_S为0
    默认串口2映射到P10和P11上,所以P_SW2寄存器不用配置*/

    S2CON = 0x50;		//8位数据,可变波特率,第4位S2REN位置1,开启中断
    //AUXR = 0000 0100,AUXR不可位寻址,T2x12为定时器2速度选择位,置1则定时器2的速度是传统8051的12倍,不分频
	  AUXR |= 0x04;
    switch (UART2.ucBandRate)
    {
        case Band_4800:   T2L = 0xCD; T2H = 0xFD; break;
        case Band_9600:   T2L = 0xE0; T2H = 0xFE; break;
        case Band_19200:  T2L = 0x70; T2H = 0xFF; break;
        case Band_115200: T2L = 0xE8; T2H = 0xFF; break;
        default:          T2L = 0xCD; T2H = 0xFD; break;
    }
    AUXR |= BIT4;       //启动定时器2   0001 0000,T2R位置为1,允许定时器2运行
}

串口2的中断处理函数中,判断接收标志位和发送标志位与串口1的不同,因为寄存器S2CON是不能位寻址的,所以不能单独拿接收标志位S2RI或者发送标志位S2TI来判断,要对S2CON寄存器进行与操作,取出BIT0的S2RI和BIT1的S2TI分别进行判断,清除标志位也是用寄存器操作

串口2的中断号是8

#define S2RI    BIT0        //串口2接收中断请求标志位
#define S2TI    BIT1        //串口2发送中断请求标志位
……………………
/*
* @name   UART1_isr
* @brief  串口2中断处理函数
* @param  None
* @retval None   
*/
void UART2_isr() interrupt 8
{
    //接收
    if(S2CON & S2RI)    //取出S2CON的BIT0位进行判断,如果是1则是接收中断,如果为0则不是
    {
        S2CON &= ~S2RI;                   //清除接收中断标志
        /*UART1_Rec_LENGTH宏定义为10,所以接收的数据不能超过10个字节
        UART1.ucRec_Cnt表示数组下标,初始化为0*/
        if(UART2.ucRec_Cnt < UART2_Rec_LENGTH)
        {
            ucRec_Buffer[UART2.ucRec_Cnt++] = S2BUF;
        }
        UART2.ucRec_Flag = TRUE;      //接收完成标志位
    }
    //发送
    if(S2CON & S2TI)
    {
        S2CON &= ~S2TI;                    //清除发送中断标志
        UART2.ucTX_Busy_Flag = FALSE;   //清除忙碌标志
    }
}

在Sys_Init.c系统初始化源文件的IE_Init()中断函数中,要打开串口2的中断

因为IE2寄存器是不能位寻址的,所以要对IE2寄存器进行赋值,将最低位SE2置1,允许串口2中断

IE2 |= BIT0;   //打开串口2中断
主函数main.c

程序的主要逻辑,串口1是负责往串口助手打印调式信息,比如输出单片机发送的AT指令,以及WIFI模块回复的应答;串口2就负责单片机与WIFI模块的通信

/*
* @name   main
* @brief  主函数
* @param  void	
* @retval int      
*/
int main(void)
{
	static idata uint16_t i = 0;
	//系统初始化
	Hradware.Sys_Init();

	//串口1发送初始化信息
	#ifdef Monitor_Run_Code
		printf("Initialization completed,system startup!\r\n\r\n");
	#endif
	
	//系统主循环
	while(1)
	{
		//连接服务器
		/*一开始TCP连接标志位为FALSE,TCP_Reconnect_Timer初始化为10S,上电进行一次TCP连接*/
		if(ESP8266.TCP_Connect_Status == FALSE)
		{
			if(ESP8266.TCP_Reconnect_Timer >= TIMER_10S)
			{
				ESP8266.TCP_Connect_Server();
			}
		}
		//接收TCP服务器的信息
		ESP8266.Receive_Information();
		//获取PCB板温度
		NTC.Get_Temperature_Value();
		//数码管显示温度
		TM1620.Disp_Tempareture();

		//将温度通过TCP传输到服务器
		ESP8266.Transfer_Tempareture(NTC.fTemperature);
		//延时500ms
		i = 500;
		while (i--)
		{
			Public.Delay_ms(1);
			//如果按键1被按下
			if(KEY1.KEY_Flag == TRUE)
			{
				break;
			}
		}
		//通过外部中断改变按键1标志位,然后进行按键1检测
		KEY1.KEY_Detect();
		//模块配网
		ESP8266.SmartConfig();
	}
}

Hradware.Sys_Init():系统初始化函数,GPIO初始化时要把串口2的引脚TXD2配置成推挽输出,RXD2配置成高阻输入,WIFI模块重启引脚RST和使能引脚EN都配置成推挽输出;要加上串口2和WIFI模块的初始化函数,WIFI模块初始化函数中会使能EN引脚启动WIFI模块,然后发送AT指令,待WIFI模块回应,如果10s内没有回应,则进行错误处理,PWM灯会一直闪烁

ESP8266.TCP_Connect_Server():WIFI 模块连接服务器函数,上电时标志位判断和定时器判断都为真,则进行TCP服务器连接,如果WIFI模块没有进行配网的话,是连接不上服务器的,因为WIFI模块还没联网,所以烧录后第一次上电,先进行模块配网操作,待联网成功后,模块会再次进行连接服务器;该函数里会通过串口2发送AT指令给WIFI模块,发送ATE0关闭回显,发送AT+CWMODE_CUR=1\r\n设置为station模式,发送AT+CIFSR\r\n不断查询IP地址,如果连接到WIFI则发送AT+CIPSTART=“TCP”,“172.29.168.61”,8888\r\n连接服务器,成功后发送AT+CIPMODE=1\r\n和AT+CIPSEND\r\n,开启透传模式以及开始发送数据

ESP8266.Receive_Information():WIFI模块接收服务器数据函数,先判断服务器连接状态标志位是否被置位,是则判断串口2的接收数组中是否有PWM = 100%的数据,可以用strstr函数来查找,有则设置PWM灯占空比为100%,并备份占空比;如果接收数组中有PWM = 0%,则设置PWM灯占空比为0%,也备份占空比

ESP8266.Transfer_Tempareture(NTC.fTemperature):将计算出来的浮点型PCB板温度传入该函数中,如果温度是个位,则转为字符型后调用串口2发送函数发送到服务器上,如果温度是十位,则分别提取个位和十位,再转为字符型,发送到服务器上显示,连同提示信息一起发送

KEY1.KEY_Detect():按键1检测,主要检测长按,通过外部中断0改变按键1的标志位,再进行判断是单击还是长按,函数退出前不清零长按标志位,要进行后面的模块配网操作

ESP8266.SmartConfig():WIFI 模块配网函数,函数中会检测按键1长按标志位是否被置为TRUE,是的话则进行配网,如果此时WIFI 模块已经处于透传模式,则先发送“+++”退出透传模式,再进行配网操作,主要是发送指令“AT+CWSTARTSMART\r\n”开启配网,开发板的运行指示灯会不断闪烁,在3分钟内,可以用手机打开安信可的公众号,找到微信配网选项,然后输入手机已连接的路由器WIFI信号密码,WIFI模块抓取网络信号,并通过串口1可在串口助手中看到配网过程,如果WIFI模块回应“Smart get wifi info”,则表示配网成功,随后重启单片机,再进行连接TCP服务器的操作

本次实验中使用到的AT指令以及其功能

AT指令响应功能以及参数说明
ATOK测试AT启动
ATE0OK关闭回显
AT+CWMODE_CUR=1OK设置当前Wi-Fi模式(sta/AP/sta+AP),不保存到flash;
参数说明:1 : station模式;2 : softAP模式;3 : softAP + station模式
AT+CIFSR+ CIFSR: < IP address >
+ CIFSR: < IP address >

OK
查询本地IP地址;
参数说明:< lP address>
ESP8266 softAP的IP地址
ESP8266 station的IP地址
AT+CWAUTOCONN=1OK上电是否自动连接AP
参数说明:
0:上电不自动连接AP
1:上电自动连接AP
ESP8266 station默认上电自动连接AP
AT+CWSTARTSMARTOK开启SmartConfig
SmartConfig类型为ESP-Touch + AirKiss
AT+CIPMODE=1OK设置传输模式
参数说明:
0:普通传输模式
1:透传模式,仅支持TCP单连接和UDP固定通信对端的情况
AT+CIPSEND收到此命令后先换行返回">“
进入透传模式发送数据,每包最大2048字节,或者每包数据以20ms间隔区分。
当输入单独一包”+++“时,返回普通AT指令模式。发送”+++"退出透传时,请至少间隔1秒再发下一条AT指令。
发送数据

注意

1.AT指令打开回显以及关闭回显的作用是什么?

回显的含义是:发送什么指令,返回给你结果的时候,会把发送的指令再显示一遍 如 AT+E=ON时 发送 AT+VER?查询版本号 返回的数据是 AT+VER?(会把下发的指令再显示一遍) +VER:V1.2.6 若是关闭回显,即AT+E=OFF 发送 AT+VER? 返回的是 +VER:V1.2.6

2.开启SmartConfig(配网)的指令AT+CWSTARTSMART = < type >:

如果指令指定参数< type >,则参数分别表示为:1 : ESP-Touch;2 : AirKiss;3 : ESP-Touch + AirKiss

该指令仅支持在ESP8266单station模式下调用。
消息“Smart get WiFi info”表示 Smart Config成功获取到AP信息,之后ESP8266尝试连接AP,打印连接过程。
消息"Smartconfig connected WiFi”表示成功连接到AP,此时可以调用"AT+CWSTOPSMART”停止SmartConfig再执行其他指令。注意,在 SmartConfig过程中请勿执行其他指令。
从AT_v1.0开始,SmartConfig可以自动获取协议类型,AirKiss或者ESP-TOUCH

实验现象以及连接步骤

注意:手机和电脑连的都是同一个路由器或者同一个手机热点,因为配过一次网后,WIFI模块会自动连接上AP,如果更换了路由器或者手机热点,那就要重新再进行配网

实现功能1

把TCP服务器IP地址改为手机端的,再编译烧录

//#define TCP_Server "AT+CIPSTART=\"TCP\",\"172.29.168.77\",8888\r\n"  //电脑端模拟的TCP服务器
#define TCP_Server "AT+CIPSTART=\"TCP\",\"172.29.168.66\",8888\r\n"  //手机端模拟的TCP服务器

手机安装一个网络助手,这里用安信可的,打开后点击创建TCP Server

在这里插入图片描述

输入端口号,然后点击CONFIRM

在这里插入图片描述

给开发板上电,可以在串口助手打印信息上看到WIFI模块连接TCP服务器过程,AT+CIPSEND后便开启了透传模式

在这里插入图片描述

然后就可以看到手机服务器上接收到了WIFI模块通过TCP协议传来的PCB板温度信息

在这里插入图片描述

服务器也可以发送信息控制开发板PWM灯的亮灭

在这里插入图片描述

在这里插入图片描述

实现功能2

先把TCP服务器IP地址改为电脑端的,再编译烧录

#define TCP_Server "AT+CIPSTART=\"TCP\",\"172.29.168.77\",8888\r\n"  //电脑端模拟的TCP服务器
//#define TCP_Server "AT+CIPSTART=\"TCP\",\"172.29.168.66\",8888\r\n"  //手机端模拟的TCP服务器

打开电脑的网络调试助手,选择TCP服务器IP地址,并设置端口号,打开服务器(电脑和手机连接的都是同一个路由器,这样就不用重新配网)

注意:电脑的防火墙要先关闭

在这里插入图片描述

开发板上电,同时串口助手可看到WIFI模块连接TCP服务器的情况,与手机端的串口输出信息一样

然后网络调试助手就可以看到WIFI模块发来的数据了

在这里插入图片描述

同样,服务器发送PWM = 100%可以点亮开发板的PWM灯,发送PWM = 0%熄灭PWM灯

实现功能3

微信配网

长按按键1三秒以上,WIFI模块进入配网模式,开发板的运行指示灯会闪烁,提示正处于配网状态;如果此时WIFI模块已经开启透传模式,单片机会先发送“+++”退出透传模式,不然后续发送的配网AT指令就会被发送到服务器上,控制不了WIFI模块

在这里插入图片描述

然后打开安信可的公众号,点击微信配网,进入WIFI配置界面,按要求连接WIFI和开启定位,点击开始配置

在这里插入图片描述

开始配置后,会获取并显示当前手机连接到的WIFI,输入WIFI密码,然后点击连接

在这里插入图片描述

如果该页面没有出现WIFI名称,如下图的情况,则要等待一会,等识别到后再输入密码,没识别到WIFI名称前输入密码也是没用的,会提示错误信息

在这里插入图片描述

输入密码点击连接后,等待配网,过一会后会看到WIFI模块回应一连串的数据并传到串口助手上显示,回应的数据是:smartconfig type:AIRKISS,表示配网使用的类型是AIRKISS协议,配网成功后,单片机会重启,这是代码里设置单片机系统重启的,并不是WIFI模块,系统重启后,WIFI模块也重新被使能启动,自动连接TCP服务器

在这里插入图片描述

同时也可以在手机公众号上看到配网成功的提示信息,这样说明配置成功,WIFI模块已经能自动连接上路由器,然后单片机就发送AT指令控制WIFI模块连接TCP服务器,并传输PCB板的温度到服务器上,服务器可以是在电脑端也可以在手机端

在这里插入图片描述

假如家里没有路由器,则用手机热点也是可以的

这时候就要有两台手机了,

手机B:开热点,相当于路由器的WiFi信号

手机A:连接手机B的热点,然后打开安信可公众号进行一键配网

此时手机B的热点连接又可以分为两种情况,一种是手机A连接另一种是电脑连接

手机A 连接 手机B 的热点

手机A控制界面,已连接手机B 的热点

在这里插入图片描述

点击WIFI信息,查看手机B热点的IP地址,为172.20.10.1

在这里插入图片描述

手机A打开SocketAssistant软件,可看到调试助手的本地IP地址为172.20.10.3,与连接的热点处于同一个网段,然后就可选择创建TCP server,输入端口号,等待客户端ESP-12S的连接

在这里插入图片描述

此时,如果是第一次连接手机热点,则需要进行一次配网,将WIFI模块也连上手机B的热点,微信配网过程与上面的一样,此时公众号获取到的WIFI名称是连接到的手机B的热点名称,待WIFI模块连接上热点后,就可以进一步连接服务器了

电脑连接手机B的热点

如果服务器是在电脑上的话,那电脑要连接上手机B的热点,手机A也要连接手机B的热点,用手机A的安信可公众号进行微信配网,将WIFI模块接入热点网络

在这里插入图片描述

在这里插入图片描述

配网成功后,单片机发送AT指令控制WIFI模块连接上电脑的服务器,并发送PCB板的温度,服务器发送PWM = 100%可点亮开发板的PWM灯,发送PWM = 0%熄灭PWM灯

在这里插入图片描述

遇到的疑惑

原本按键1的单击和长按动作要注释掉,并且单击和长按标志位清0的操作也要取消,因为main函数中按键检测完后的下一个函数就是配网函数 ,配网函数里第一条语句就先判断长按标志位是否为TRUE,为TRUE才进行后续配网操作,如果按键检测函数结束前把长按标志位清0了,则后面没法配网;

其次就是长按3秒成功后,标志位在按键检测中没有被清零,在配网函数完成后也没有看到被清零,全局搜索该长按标志后,也没有看到KEY1.Press = FALSE(在长按检测的循环内清0是判断有没有超过3秒,并不是标志位置位后的清零)那标志位是在哪里被清零了呢?如果不清零,则配网函数就会一直检测到长按标志位为TRUE,则一直进行配网操作

:在配网函数的最后,调用了Public.Sys_Soft_Reset()函数,进行了系统复位,单片机重启了,所以按键1的长按标志位也重新初始化为0了,所以不用再额外写长按标志位清零的操作

粗心导致的BUG

配网函数SmartConfig()中,发送完AT指令后等待WIFI模块返回回应时,if(strstr(UART2.pucRec_Buffer,“Smart get wifi info”) != NULL)这一句的"Smart get wifi info"应答信息一定要写对,不要写错,大小写不对都不行,不然微信这边显示配网成功,但程序没捕捉到退出条件,就一直在循环里跑,一直往串口助手打印串口2的接收缓存,系统软件重启也不行,已经错了两次

//等待配网,超过3分钟则进行退出
Timer0.usDelay_Timer = 0;
while(Timer0.usDelay_Timer <= TIMER_3MIN)
{
    Run_LED.Run_LED_Flip();
    Public.Delay_ms(100);

    if(strstr(UART2.pucRec_Buffer,"Smart get wifi info") != NULL)	//注意待匹配的子串要写对,wifi是全小写
    {
        Public.Delay_ms(1000);
        Public.Delay_ms(1000);
        Public.Delay_ms(1000);
        Public.Delay_ms(1000);
        Public.Delay_ms(1000);
        Public.Delay_ms(1000);
        break;
    }
    #ifdef Monitor_Run_Code
    	printf(UART2.pucRec_Buffer);
    #endif
}
//系统软件复位
Public.Sys_Reset();

下图是写错时串口打印的信息

在这里插入图片描述

看教程时需要注意的点

微信配网原理跟用单片机串口发送热点名称和密码一样,微信配网去到其他地方都可以将硬件设备连接到当地的网络中,这就是优势;而用串口发送的话,换个地方就不行了,需要重新修改代码,更新热点名称和密码,重新烧录才能联网;先配网连接上网络后,才能连接服务器

程序功能的配网模式是指,把路由器的wifi密码发送给开发板,ESP-12S就连接上路由器,然后就可以通过路由器与手机进行连接

联网的方式有:wifi、GPRS、3G/4G、NBIOT、有线

正常产品与TCP服务器之间是有心跳包的,检测两者的连接是否断开

主循环内如果联网状态是FALSE的话,就每隔10S进行一次联网,当联网成功后就不再连接
接收TCP服务器的信息,也就是通过指令控制PWM灯的亮度

AT指令中,开启SmartConfig功能,执行的指令是AT+CWSTARTSMART;AirKiss叫做“飞吻”协议,多用于微信配网;开启时如果不带参数指定协议类型,则默认设置为3,即ESP-Touch和AirKiss协议都支持

按键1是通过外部中断来检测按下的

ESP8266.c中初始化结构体变量时,重连定时器初始化为10S,这样的话在主函数中,一上电就进行一次连接,如果重连定时器初始化为0,则上电后要等10S才开始连接

串口2初始化,串口2中断允许寄存器2(不可位寻址)IE2 |= BIT0,最低位ES2置1,允许串口2中断
P_SW2:外围设备功能切换控制寄存器2(不可位寻址)

注意:串口2的配置中,因为是复制串口1的代码,一开始是串口1的寄存器,要全都改为串口2的寄存器,不能有遗漏

ESP8266的重连定时器变量记得要在定时器0中断中++,用来实现连接服务器失败后,10s再次执行连接服务器函数

按键1 KEY_Detect()检测中,要检测按键1长按超过3秒,for循环的 i 是小于300的,原来检测是两秒,所以 i 的类型为uint8_t,最大只能是256,所以是检测不了3秒的,要将变量 i 的类型改为uint16_t才能检测到长按3秒

串口2的接收数组长度为100,所以数组要声明为xdata,放在片外RAM,不然编译时会提示栈溢出

配网函数中,退出透传模式可用调用三次UART_SendData(‘+’)退出,也可以调用UART_SendString(“+++”)发送字符串退出

如果是用自己手机开热点给电脑连接,则电脑上的网络调试助手可以识别手机网络的IPv4地址,可以开启服务器,但在安信可公众号中却不能微信配网,因为微信配网只能配连接到的WIFI,如果是手机自己开的热点的则配不了,会显示没有搜索到WiFi信号,要求开启WiFi接收功能;也就是说,只有一台手机,没有连接WIFI或者其他手机热点的情况下,是没法微信配网的,想要设备连接手机的热点,只能在代码中添加连接AP的AT指令,用单片机控制WIFI模块连接手机热点

  • 4
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值