基于STC12单片机实现nRF24L01遥控器发射机和接收机开源程序分享

基于STC12单片机实现nRF24L01遥控器发射机和接收机开源程序分享


  • ✨这是一个来源于开源的基于nRF24L01控制的项目,资料齐全,仅供个人学习研究使用,其其可靠性自行验证。
  • 📌该项目基于STC12C5A60S2单片机。

  • 📑发射端原理图部分
    在这里插入图片描述

  • 📜接收端原理图
    在这里插入图片描述

🌼发射端程序说明

  • 🌿Keil编译设置

在这里插入图片描述

由于程序代码过长贴出来了。

  • 编译信息
    在这里插入图片描述

🌻接收端

//#include<reg51.h>
#include <STC89C5xRC.H>

#define u8 unsigned char
#define u16 unsigned int

sfr IAP_DATA=0xe2;
sfr IAP_ADDRH=0xe3;
sfr IAP_ADDRL=0xe4;
sfr IAP_CMD=0xe5;
sfr IAP_TRIG=0xe6;
sfr IAP_CONTR=0xe7;
//sfr AUXR=0x8e;
sfr BRT=0x9c;
sbit LED=P2^2;
//sbit LED=P2^3;

sbit CH1=P2^1;
sbit CH2=P2^0;
sbit CH3=P1^7;
sbit CH4=P1^6;
sbit CH5=P1^5;
sbit CH6=P1^4;
sbit CH7=P1^3;
sbit CH8=P1^1;

sbit CHB=P1^0;
sbit CHC=P3^7;
sbit CHD=P2^7;
sbit CHE=P2^6;

sbit MDO=P3^5;
sbit SCK=P2^4;
sbit CE=P2^5;
sbit IRQ=P3^4;
sbit MDI=P3^3;
sbit CSN=P3^2;

sfr P1M1=0x92;
sfr P3M1=0xb2;
sfr P2M1=0x96;


u8 code random[100]={4,1,3,2,2,1,0,0,2,2,2,3,4,1,2,1,4,3,3,4,//随机跳频序列
										 2,0,2,2,3,1,2,3,2,2,2,4,2,4,0,3,4,2,3,1,
										 0,3,1,3,3,0,2,0,4,3,3,3,3,3,4,1,1,4,3,0,
	                   1,0,3,2,3,2,3,3,4,4,1,3,0,0,3,1,3,3,3,0,
	                   3,3,4,1,2,4,1,3,0,1,3,4,4,3,2,3,1,2,3,3};


u16 timer1,timer2,timer3;
u8 rx_num,receive;
											


u8 rx[11];		//接收的11字节数据
u8 tx[11];
u8 m;
u8 hopping_turn,hopping_num,hopping_count;


//u8 missing_data[4];
u8 address[5]={0xe7,0xe7,0xe7,0xe7,0xe7};
u8 code address_0[5]={'L','O','V','E','!'};//使用LOVE作为对频暗语

u8 hopping[5]={10,35,60,85,110};
bit first,restar;
bit connecting,lose;
bit jump_1,jump_2,jump_mode;

u8 NRF_error;
u16 CH_data[8]={0,1024,0,1024,0,1024};
u16 data buff[8];
u16 temp1,temp2;
u8 t_output;

u8 TX_power=3;

bit LED_flash;
bit out_control_change;
u16 idata out_control_data[8];


void Delay1ms()		//@12.000MHz
{
	unsigned char i, j;
	i = 12;
	j = 168;
	do
	{
		while (--j);
	} while (--i);
}

void delay_ms(u8 i)
{
	while(i--)
	Delay1ms();
}

u8 EEPROM_read(u8 address)
{
	IAP_CMD=0x01;
	IAP_ADDRH=0;
	IAP_ADDRL=address;
	IAP_TRIG=0x46;			
	IAP_TRIG=0xb9; 
	return IAP_DATA;
}

void EEPROM_write(u8 address,u8 byte)
{
	IAP_CMD=0x02;
	IAP_DATA=byte;
	IAP_ADDRH=0;
	IAP_ADDRL=address;
	IAP_TRIG=0x46;
	IAP_TRIG=0xb9; 
	
}

void EEPROM_clean(u8 address)
{
	IAP_CMD=0x03;
	IAP_ADDRH=0;
	IAP_ADDRL=address;
	IAP_TRIG=0x46;
	IAP_TRIG=0xb9;
}

void DATA_read()
{
	IAP_CONTR=0x82;
	if((EEPROM_read(0)!=0xe4)||(EEPROM_read(1)!=0xa5))	 
	{
	   first=1;

	}
	else
	{
	  hopping[0]=EEPROM_read(2);
		hopping[1]=EEPROM_read(3);
		hopping[2]=EEPROM_read(4);
		hopping[3]=EEPROM_read(5);
		hopping[4]=EEPROM_read(6);
		address[0]=EEPROM_read(7);
		address[1]=EEPROM_read(8);
		address[2]=EEPROM_read(9);
		address[3]=EEPROM_read(10);
		address[4]=EEPROM_read(11);
	}
	
	if((EEPROM_read(12)!=0xe4)||(EEPROM_read(13)!=0xa5))	 
	{
	  out_control_data[0]=512;
		out_control_data[1]=512;
		out_control_data[2]=80;
		out_control_data[3]=512;
		out_control_data[4]=512;
		out_control_data[5]=512;
		out_control_data[6]=512;
		out_control_data[7]=512;

	}
	else
	{
		
		out_control_data[0]=EEPROM_read(14);
		out_control_data[0]<<=8;
		out_control_data[0]+=EEPROM_read(15);
		out_control_data[1]=EEPROM_read(16);
		out_control_data[1]<<=8;
		out_control_data[1]+=EEPROM_read(17);
		out_control_data[2]=EEPROM_read(18);
		out_control_data[2]<<=8;
		out_control_data[2]+=EEPROM_read(19);
		out_control_data[3]=EEPROM_read(20);
		out_control_data[3]<<=8;
		out_control_data[3]+=EEPROM_read(21);
		out_control_data[4]=EEPROM_read(22);
		out_control_data[4]<<=8;
		out_control_data[4]+=EEPROM_read(23);
		out_control_data[5]=EEPROM_read(24);
		out_control_data[5]<<=8;
		out_control_data[5]+=EEPROM_read(25);
		out_control_data[6]=EEPROM_read(26);
		out_control_data[6]<<=8;
		out_control_data[6]+=EEPROM_read(27);
		out_control_data[7]=EEPROM_read(28);
		out_control_data[7]<<=8;
		out_control_data[7]+=EEPROM_read(29);

	}
	
 
	IAP_CONTR=0;
}
void DATA_save()
{
	IAP_CONTR=0x82;
		EEPROM_clean(0);
		EEPROM_write(0,0xe4);
		EEPROM_write(1,0xa5);
		EEPROM_write(2,hopping[0]);
		EEPROM_write(3,hopping[1]);
		EEPROM_write(4,hopping[2]);
		EEPROM_write(5,hopping[3]);
		EEPROM_write(6,hopping[4]);
		EEPROM_write(7,address[0]);
		EEPROM_write(8,address[1]);
		EEPROM_write(9,address[2]);
		EEPROM_write(10,address[3]);
		EEPROM_write(11,address[4]);
	
		if(out_control_change)
		{
			EEPROM_write(12,0xe4);
			EEPROM_write(13,0xa5);
		
			EEPROM_write(14,out_control_data[0]>>8);
			EEPROM_write(15,out_control_data[0]);
			EEPROM_write(16,out_control_data[1]>>8);
			EEPROM_write(17,out_control_data[1]);
			EEPROM_write(18,out_control_data[2]>>8);
			EEPROM_write(19,out_control_data[2]);
			EEPROM_write(20,out_control_data[3]>>8);
			EEPROM_write(21,out_control_data[3]);
			EEPROM_write(22,out_control_data[4]>>8);
			EEPROM_write(23,out_control_data[4]);
			EEPROM_write(24,out_control_data[5]>>8);
			EEPROM_write(25,out_control_data[5]);
			EEPROM_write(26,out_control_data[6]>>8);
			EEPROM_write(27,out_control_data[6]);
			EEPROM_write(28,out_control_data[7]>>8);
			EEPROM_write(29,out_control_data[7]);
		}
	
		
		
	
	
	
		IAP_CONTR=0;
}

/**************************************************************************/
//NRF24L01
u8 SPI(u8 byte)
{
	u8 i;
	for(i=0;i<8;i++)
	{
		MDI=(byte&0x80);
		SCK=1;
		byte<<=1;
		byte|=MDO;
		SCK=0;
	}
	return byte;
}

void REG_write(u8 address,u8 command)
{
	CSN=0;
	SPI(0x20+address);
	SPI(command);
	CSN=1;
}

void FIFO_write(u8 DATA_OUT[],u8 lengh)
{
	u8 i;
	CSN=0;
	SPI(0xa0);
	for(i=0;i<lengh;i++)
	SPI(DATA_OUT[i]);
	CSN=1;
}
void FIFO_read(u8 DATA_IN[],u8 lengh)		//读取接收数据缓冲区
{
	u8 i;
	CSN=0;
	SPI(0x61);	//读取命令
	for(i=0;i<lengh;i++)
	DATA_IN[i]=SPI(0);	   
	CSN=1;
}

void TX_address(u8 DATA_IN[])
{
	CSN=0;		 
	SPI(0x20+0x10);
	SPI(DATA_IN[0]);
	SPI(DATA_IN[1]);
	SPI(DATA_IN[2]);
	SPI(DATA_IN[3]);
	SPI(DATA_IN[4]);
	CSN=1;  
}  
void RX_address(u8 DATA_IN[])
{
	CSN=0;		 
	SPI(0x20+0x0a);
	SPI(DATA_IN[0]);
	SPI(DATA_IN[1]);
	SPI(DATA_IN[2]);
	SPI(DATA_IN[3]);
	SPI(DATA_IN[4]);
	CSN=1;  
}
void RX_mode()				 
{
	CE=0;
	REG_write(0x00,0x3b); //CRC,8 bit,Power on,RX
	CE=1;
} 				   
	
void TX_mode()				 
{
	CE=0;
	REG_write(0x00,0x0a);
  CE=1;
}

void  NRF_power(u8 P)				//发射功率设置 250k
{														
	CE=0;
	if(P==3)REG_write(0x06,0x27);		  //0db 修正之前注释错误
	else if(P==2)REG_write(0x06,0x25);	  //-6db
	else if(P==1)REG_write(0x06,0x23);	  //-12db
	else if(P==0)REG_write(0x06,0x21);    //-18db
	CE=1;
}

void NRF_size(u8 l)
{
	CE=0;
	REG_write(0x11,l);  
	CE=1;
}

void NRF_channel(u8 c)
{
	CE=0;
	REG_write(0x05,c);  
	CE=1;
}


void NRF_init()
{	
	CE=0;
	SCK=0;
	REG_write(0x01,0x00); //禁止 自动应答
	REG_write(0x02,0x01); //允许 P0信道
	REG_write(0x04,0x00); //禁止 自动重发
	RX_mode(); 			 
	NRF_channel(66);
	NRF_power(TX_power);
	NRF_size(11);
	RX_address(address);
	TX_address(address);
}

void NRF_test()	//无线模块终极测试
{	
	u8 reset_err=0;
	CE=0;
	SCK=0;
	CSN=0;
	
	if(SPI(0x20)!=0x0e){reset_err=1;}
	SPI(0x0a);

	CSN=1;

	CSN=0;
	SPI(0x00);

	if(SPI(0x00)!=0x0a){NRF_error|=0x02;}//MOSI bad
	CSN=1;

	REG_write(0x01,0x00);
	REG_write(0x04,0x00);
	REG_write(0x11,1);
	
	FIFO_write(tx,1);
	CE=1;

	delay_ms(2);
	
	CSN=0;

	if(SPI(0x00)!=0x2e){NRF_error|=0x04;}//CE bad
	CSN=1;
		
	if(IRQ)NRF_error|=0x18;	//IRQ bad
	else 
	{
		if(NRF_error&0x04==0)NRF_error|=0x10;		//MISO bad
	}
	CE=1;
	
	if(reset_err&&NRF_error>1)NRF_error|=0x01;//CSN,CLK bad
	
	REG_write(0x07,0x20);	//清除TX中断信号
}

void data_check(int x,int max,int min)
{
	
	if(x>max)x=max;
	if(x<min)x=min;

}

void initial()
{	
	u8 t;
	
	CH5=0;			//如果CH5与CH6被短接,重新对码
	Delay1ms();
	if(CH6==0)		  //新增修正通道6插上舵机不能用的BUG
	{
		P1M1=0x08;	  //插上舵机也会使CH6为0,所以将CH5设为推挽
		CH5=1;
		Delay1ms();
		if(CH6)restar=1;   //如果CH6被拉高,说明5/6通道短接,启动重新对码
	}
	 	
	LED=0;		//点亮指示灯再关闭,表示单片机正常工作
	delay_ms(100);
	P1M1=0xfb;
	P2M1=0xc7;
	P3M1=0x80;	//将6通道输出IO口配置为大电流推挽模式,保证正常驱动电调与舵机
	TMOD=0x11;	//允许两个定时器中断	
	IE=0x8a;
	IP=0x08; 


	if(restar)first=1;
	DATA_read();

	
	data_check(out_control_data[0],1023,0);
	data_check(out_control_data[1],1023,0);
	data_check(out_control_data[2],1023,0);
	data_check(out_control_data[3],1023,0);
	data_check(out_control_data[4],1023,0);
	data_check(out_control_data[5],1023,0);
	data_check(out_control_data[6],1023,0);
	data_check(out_control_data[7],1023,0);
	

	NRF_test();
	if(NRF_error)
	{
		t=10;
		while(t)
		{
			LED=0;		//模块错误闪灯
			delay_ms(50);
			LED=1;		//模块错误闪灯
			delay_ms(50);
			t--;
		}
	}
	
	NRF_init();

	

	
	if(first)
	{
		NRF_power(0);
		NRF_channel(33);
		TX_address(address_0);
		RX_address(address_0);
		while(IRQ);
		FIFO_read(rx,11);		//读取接收数据
		CE=0;
		REG_write(0x07,0x40);	//清除无线模块中断信号
		CE=1;
		if(rx[0]==0xa0)
		{
			hopping[0]=rx[1];
			hopping[1]=rx[2];
			hopping[2]=rx[3];
			hopping[3]=rx[4];
			hopping[4]=rx[5];
			address[0]=rx[6];
			address[1]=rx[7];
			address[2]=rx[8];
			address[3]=rx[9];
			address[4]=rx[10];
		}
		
		tx[0]='O',tx[1]='K';
		connecting=1;
		while(connecting)
		{
			TX_mode();		
			NRF_channel(33);
			TX_address(address_0);
			RX_address(address_0);
			FIFO_write(tx,11);
			Delay1ms();
			
			RX_mode();
			NRF_channel(hopping[0]);
			TX_address(address);
			RX_address(address);
			while(1)
			{
				Delay1ms();
				if(IRQ==0)
				{
					FIFO_read(rx,11);		//读取接收数据
					CE=0;
					REG_write(0x07,0x40);	//清除无线模块中断信号
					CE=1;	 
					connecting=0;break;
				}
				t++;if(t>100){t=0;break;}
			}			  
		}
			DATA_save();
	RX_address(address);
	TX_address(address);
	NRF_power(3);
	}
	
}

																	     

main()
{	
	delay_ms(200);delay_ms(200);//开机延时以避过电源波动
	
	initial();
PCON |= 0x80;		//使能波特率倍速位SMOD
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x04;		//独立波特率发生器时钟为Fosc,即1T
	BRT = 0xF3;		//设定独立波特率发生器重装值
	AUXR |= 0x01;		//串口1选择独立波特率发生器为波特率发生器
	AUXR |= 0x10;
	  	
	
	TR0=1;			//打开定时器

	
	NRF_channel(hopping[0]);
	
	
	while(IRQ);
	TR1=1;
	lose=1;
	LED=1;
	while(1)
	{	
		while(IRQ&lose);
		if(lose)
		{	
			jump_1=0;jump_2=0;hopping_count=0;//收到有效信号后刷新跳频器
			receive++;timer1=0;timer3=0;m=0;		
			
			FIFO_read(rx,11);		//读取接收数据
			CE=0;
			REG_write(0x07,0x40);	//清除无线模块中断信号
			CE=1;
			
			TX_mode();
			tx[0]=rx_num;
			tx[1]=0;
			tx[2]=0;
			tx[3]=0;
			tx[4]=0;
			FIFO_write(tx,11);
			Delay1ms();

			RX_mode();
						
			if(jump_mode)
			{
				jump_mode=0;
				hopping_turn=random[hopping_num];
			}
			hopping_turn++;
			if(hopping_turn>4)hopping_turn=0;
			NRF_channel(hopping[hopping_turn]);
			



			if(rx[0]==0xa0)
			{
				LED_flash=1,LED=0;
				buff[0]=rx[1];
				buff[0]<<=2;
				buff[0]+=rx[2]>>6;
				buff[1]=rx[2]&0x3f;
				buff[1]<<=4;
				buff[1]+=rx[3]>>4;			
				buff[2]=rx[3]&0x0f;
				buff[2]<<=6;
				buff[2]+=rx[4]>>2;
				buff[3]=rx[4]&0x03;
				buff[3]<<=8;
				buff[3]+=rx[5];

				buff[4]=rx[6];
				buff[4]<<=2;
				buff[4]+=rx[7]>>6;
				buff[5]=rx[7]&0x3f;
				buff[5]<<=4;
				buff[5]+=rx[8]>>4;			
				buff[6]=rx[8]&0x0f;
				buff[6]<<=6;
				buff[6]+=rx[9]>>2;
				buff[7]=rx[9]&0x03;
				buff[7]<<=8;
				buff[7]+=rx[10];
				
				
				data_check(buff[0],1023,0);
				data_check(buff[1],1023,0);
				data_check(buff[2],1023,0);
				data_check(buff[3],1023,0);
				data_check(buff[4],1023,0);
				data_check(buff[5],1023,0);
				data_check(buff[6],1023,0);
				data_check(buff[7],1023,0);
				
				out_control_data[0]=buff[0];
				out_control_data[1]=buff[1];
				out_control_data[2]=buff[2];
				out_control_data[3]=buff[3];
				out_control_data[4]=buff[4];
				out_control_data[5]=buff[5];
				out_control_data[6]=buff[6];
				out_control_data[7]=buff[7];
				
				out_control_change=1;
				DATA_save();
				out_control_change=0;
				
			}
			else if(rx[0]==0xa1)
			{
				buff[0]=rx[1];
				buff[0]<<=2;
				buff[0]+=rx[2]>>6;
				buff[1]=rx[2]&0x3f;
				buff[1]<<=4;
				buff[1]+=rx[3]>>4;			
				buff[2]=rx[3]&0x0f;
				buff[2]<<=6;
				buff[2]+=rx[4]>>2;
				buff[3]=rx[4]&0x03;
				buff[3]<<=8;
				buff[3]+=rx[5];

				buff[4]=rx[6];
				buff[4]<<=2;
				buff[4]+=rx[7]>>6;
				buff[5]=rx[7]&0x3f;
				buff[5]<<=4;
				buff[5]+=rx[8]>>4;			
				buff[6]=rx[8]&0x0f;
				buff[6]<<=6;
				buff[6]+=rx[9]>>2;
				buff[7]=rx[9]&0x03;
				buff[7]<<=8;
				buff[7]+=rx[10];
				
				
				data_check(buff[0],1023,0);
				data_check(buff[1],1023,0);
				data_check(buff[2],1023,0);
				data_check(buff[3],1023,0);
				data_check(buff[4],1023,0);
				data_check(buff[5],1023,0);
				data_check(buff[6],1023,0);
				data_check(buff[7],1023,0);
				
				CH_data[0]=buff[0];
				CH_data[1]=buff[1];
				CH_data[2]=buff[2];
				CH_data[3]=buff[3];
				CH_data[4]=buff[4];
				CH_data[5]=buff[5];
				CH_data[6]=buff[6];
				CH_data[7]=buff[7];				
			}
			
			


		}
		else
		{
		 	hopping_count++;
			if(hopping_count>5)jump_mode=1;
			
			if(jump_mode)
			{
				hopping_num++;
				if(hopping_num>99)hopping_num=0;
				NRF_channel(hopping[random[hopping_num]]);
				lose=1;
			}
			else
			{
				hopping_turn++;
				if(hopping_turn>4)hopping_turn=0;
				NRF_channel(hopping[hopping_turn]);
				lose=1;
			}
			
		}
		
	}
	
}


void et0()interrupt 1			//跳频定时器 3ms
{
	TL0=0x47;TH0=0xf4;

	timer1++;
	if(timer1>333)			//每秒统计有效信号,小于20个点亮LED示警,表示信号微弱
	{
		timer1=333;
		rx_num=0;LED=0;
	}
	else LED=1;
	
	timer2++;
	if(timer2>333)
	{
		timer2=0;
		rx_num=receive;
		receive=0;
	}
	
	timer3++;
	if(timer3>666)
	{
		timer3=666;
		CH_data[0]=out_control_data[0];
		CH_data[1]=out_control_data[1];
		CH_data[2]=out_control_data[2];
		CH_data[3]=out_control_data[3];
		CH_data[4]=out_control_data[4];
		CH_data[5]=out_control_data[5];
		CH_data[6]=out_control_data[6];
		CH_data[7]=out_control_data[7];
	}
	
	if(LED_flash)
	{
		
	}
		
	m++;					//两个标志位循环跳频
	if(jump_1==0)
	{
		if(m>7)lose=0,jump_1=1,jump_2=0;	  //未收到信号,开始第一跳
	}
	else
	{
		if(jump_2==0)
		{
			if(m>14)lose=0,jump_2=1;		 //第一跳之后仍无信号,开始第二跳
		}
		else
		{
			 if(m>22)m=0,lose=0,jump_1=0;	 //第二跳之后仍无信号,复位重新跳。
			
		}		
	}	
		
}

void et1()interrupt 3	//定时器1用作信号输出
{
TR1=0;CHE=!CHE;
	t_output++;
	switch(t_output)
	{
		
		case 1:CH1=1;temp1=64750-CH_data[0]*27/20;
						TL1=temp1,TH1=temp1>>8;break;
						
		
		case 2:CH1=0;temp2=128600-temp1;
						TL1=temp2,TH1=temp2>>8;break;
		case 3:CH2=1;temp1=64750-CH_data[1]*27/20;
						TL1=temp1,TH1=temp1>>8;break;
						
						
		case 4:CH2=0;temp2=128600-temp1;
						TL1=temp2,TH1=temp2>>8;break;
		case 5:CH3=1;temp1=64750-CH_data[2]*27/20;
						TL1=temp1,TH1=temp1>>8;break;
		case 6:CH3=0;temp2=128600-temp1;
						TL1=temp2,TH1=temp2>>8;break;
		case 7:CH4=1;temp1=64750-CH_data[3]*27/20;
						TL1=temp1,TH1=temp1>>8;break;
		case 8:CH4=0;temp2=128600-temp1;
						TL1=temp2,TH1=temp2>>8;break;
		case 9:CH5=1;temp1=64750-CH_data[4]*27/20;
						TL1=temp1,TH1=temp1>>8;break;
		case 10:CH5=0;temp2=128600-temp1;
						TL1=temp2,TH1=temp2>>8;break;
		case 11:CH6=1;temp1=64750-CH_data[5]*27/20;
						TL1=temp1,TH1=temp1>>8;break;
		case 12:CH6=0;temp2=128600-temp1;
						TL1=temp2,TH1=temp2>>8;break;
		case 13:CH7=1;temp1=64750-CH_data[6]*27/20;
						TL1=temp1,TH1=temp1>>8;break;
		case 14:CH7=0;temp2=128600-temp1;
						TL1=temp2,TH1=temp2>>8;break;
		case 15:CH8=1;temp1=64750-CH_data[7]*27/20;
						TL1=temp1,TH1=temp1>>8;break;
		case 16:CH8=0;temp2=128600-temp1;
						TL1=temp2,TH1=temp2>>8;t_output=0;break;

								
	}
TR1=1;CHE=!CHE;
}

项目资源

链接:https://pan.baidu.com/s/10pIrI1faPqnzoxdwXafR7g 
提取码:fgcj
  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值