dsPIC30F6014A写的Modbus程序

/*------------------------------Modbus.c--------------------------*/
#include "PRJ.h"
#include "p30f6014a.h"
#include "stdio.h"
#include "DFT.h"
#include "Freq.h"
#include "control.h"
#include "ModBus.h"

#define R485C PORTGbits.RG14
//#define R485C PORTGbits.RG12    //for profibus  test
#define TRUE   1
#define FALSE  0

unsigned char temp4[80];
unsigned int send_no;				//发送数据个数
unsigned int Send_data[12]={'t','e','s','t','\r','\n','1','2','3','4','\r','\n'}; //发送的数组

/* ****************************************************************
** 函  数 名: Uart_Initial()
** 功能描述: 通用异步收发器UART初始化
*************************************************************** */
 /*通用异步收发器UART初始化 
 */
void Uart_Initial()
{
	IFS0bits.U1TXIF=0;			//发送中断标志位清零
	IFS0bits.U1RXIF=0;			//接收中断标志位清零
	IPC2bits.U1TXIP=1;			//发中断优先级:1级  
    IEC0bits.U1TXIE=0;			//UART1发送中断使能 
    //IEC0bits.U1RXIE=TRUE;
	//IEC0bits.U1RXIE=FALSE;
    IEC0bits.U1RXIE=TRUE;
	U1MODE=0x8000; 			    //UART使能,8位数据,无奇偶校验
	U1STA=0x0400;				//当一个字符被传输到发送移位寄存器(发送缓冲器中至
	//U1STA=0x0000;   			//少还有一个字符)产生中断,当接收到一个字符时,中
								//断标志位置位
	//U1BRG=0X34;            	//U1BRG=Fcy/(16*波特率)-1,此处波特率为9600
    
    U1BRG=0X33;
    //U1BRG=0X06;
    //U1STA=0x0400;
  	return;
}

#define uchar  unsigned char

uchar rxd_get[20]={0x64,0x03,0x00,0x04,0x00,0x01};
uchar rxd_cnt=0;
uchar rxd_flag=FALSE;
uchar rxd_tms=0;
uchar rxd_id=0x64;

void uart_err_todo(void)
{
 if(U1STAbits.OERR==1)
	{
	 U1STAbits.OERR=0;	
     }
 }

void uart_get(void)//1ms cycle called 
{
 rxd_tms++;
 if(rxd_tms>5)//dt=5ms,帧同步
   {
	rxd_tms=0;
	rxd_cnt=0;
    }
 if(rxd_flag==FALSE)
	{
	  while(U1STAbits.URXDA==1)
		{
	     rxd_tms=0;
		 IFS0bits.U1RXIF=0;
		 rxd_get[rxd_cnt++]=U1RXREG;
		 if(rxd_get[0]!=rxd_id)
			{rxd_cnt=0;}
		 if(rxd_cnt>7)//get 8 byte 
			{
			 rxd_cnt=0;
			 rxd_flag=TRUE;
	         }//if()
         }//while()
	 }//if()
 }//end

//-------------------------------------------
//3.CRC16算法
//-------------------------------------------

#define U16   unsigned int
#define U8    unsigned char

 U16 CRC16(U8 *p,U8 n)
 {
  U16 temp=0xffff;
  U16 crc_result;
  U8 i,j;
  for(j=0;j<n;j++)
    {
	 temp^=(*p);
	 for(i=0;i<8;i++)
	  {
       /*
       temp>>=1;
       if(STATUSbits.C==1)
		  {temp^=0xa001;}*/
       
	   if((temp&0x0001)==0x0000)
		  {temp>>=1;}
	   else
		  {temp>>=1;
		   temp^=0xa001;	
		   }
        
	   }
     p++;
     }
   crc_result=(temp/256)+(temp%256)*256;
   return(crc_result);
  }
//------------------------------------------
//
//------------------------------------------
#define uint unsigned int

uchar txd_buff[8];
extern signed int I_sys;//=0;
extern signed char pf_2nd;//pf real is 0.98
extern uchar relay_state;//=0x00;

void uart_echo(void)//100ms cycle called
{
 uchar i;
 uint crc_temp,reg_addr;
 if(rxd_flag==TRUE)
   {
	//send
    /*
	for(i=0;i<8;i++)
	{
	 U1TXREG=rxd_get[i];
	 while(IFS0bits.U1TXIF==0);
	 IFS0bits.U1TXIF=0;
	 }
     */
    //crc test
    crc_temp=CRC16(rxd_get,6);
	if((crc_temp/256==rxd_get[6])&&\
	   (crc_temp%256==rxd_get[7])&&\
	   (rxd_get[1]==0x03))
		{
		    reg_addr=(uint)rxd_get[2]*256+rxd_get[3];
		    /*
			switch(reg_addr)
			{
			  case 1://电压
					 txd_buff[4]=VL_2nd/256;
					 txd_buff[5]=VL_2nd%256;
					 break;
			  case 2://电流
					 txd_buff[4]=I_sys/256;
					 txd_buff[5]=I_sys%256;
					 break;
			  case 3://功率因数
					 txd_buff[4]=pf_2nd/256;
					 txd_buff[5]=pf_2nd%256;
					 break;
			  case 4://投切状态
					 txd_buff[4]=relay_state/256;
					 txd_buff[5]=relay_state%256;
					 break;
			  case 5://
					 
					 break;
			  case 6://
                     
					 break;
					 
			  default:break;
			 }
			 */
			txd_buff[0]=rxd_id;
		    txd_buff[1]=0x03;
			txd_buff[2]=0x00;
			txd_buff[3]=0x01;
			crc_temp=CRC16(txd_buff,6);
			txd_buff[6]=crc_temp/256;
			txd_buff[7]=crc_temp%256;
			//_20ms_timer_clr();
			//while(_20ms_timer()==FALSE);
			//*
		 	for(i=0;i<8;i++)
			{
			 U1TXREG=txd_buff[i];
			 while(IFS0bits.U1TXIF==0);
			 IFS0bits.U1TXIF=0;
			 }
			 //*/
		 }
    rxd_flag=FALSE;
	 }
 }
//----------------------------------------
//for @30000# format get
//----------------------------------------
#define uint8    unsigned char
#define uint16   unsigned int
uint16 FS_SET=50;//300~30,000Hz
void FS_SET_Update(void)
{ 
 uint16 temp;
 temp=(uint16)(rxd_get[1]-'0')*10000;
 temp=temp+(uint16)(rxd_get[2]-'0')*1000;
 temp=temp+(uint16)(rxd_get[3]-'0')*100;
 temp=temp+(uint16)(rxd_get[4]-'0')*10;
 temp=temp+(uint16)(rxd_get[5]-'0');
 if(temp<=30000)
   {
    FS_SET=temp;
    //Update F sample
    //printf()
    PR4=(uint16)(250000.0/(float)temp);
    printf("FS_SET=%d,PR4 Set=%d\r\n",FS_SET,PR4);
    }
 else
    {printf("FS_SET Not Update\r\n");}
 }
//
uint8 SIND_Get_Flag=FALSE;
uint8 SIND_Get_State=0;
uint8 GetTemp;
extern void modbus_recieve(void);
///
void __attribute__((__interrupt__)) _U1RXInterrupt()
{
 /*
 //while(U1STAbits.URXDA==1)
//	{
	 //IFS0bits.U1RXIF=0;
	 rxd_get[rxd_cnt++]=U1RXREG;
	 if(rxd_cnt>9)
		{rxd_cnt=0;
		 rxd_flag=TRUE;
		 }
//	 }
 */
 if(SIND_Get_Flag==FALSE)
 {
  GetTemp=U1RXREG;
  modbus_recieve();
  switch(SIND_Get_State)
    {
     case 0:if(GetTemp=='@')
			 {rxd_cnt=0;
			  rxd_get[rxd_cnt++]=GetTemp;
			  SIND_Get_State=1;
  		      }
			break;
     case 1:if(GetTemp=='#')
			 {//rxd_cnt=0;
			  rxd_get[rxd_cnt++]=GetTemp;
			  rxd_get[rxd_cnt++]='\0';
			  rxd_cnt=0;
			  SIND_Get_State=0;
			  SIND_Get_Flag=TRUE;
  		      }	
			else
			  {
			   rxd_get[rxd_cnt++]=GetTemp;
               }		
			break;
     }
  }
 IFS0bits.U1RXIF=0;
 }
 
 
extern uint8 SIND_Get_Flag;//=FALSE;
extern uchar rs485_com_adr;//=0;//rs485 通讯地址
extern uint IL_real_uart;
extern uint relay_state_2nd;//=0x0fff;
extern unsigned int  ct_ratio;//CT 变比
extern unsigned int Iq_set;
extern unsigned int dt_interval;//控制时间间隔
extern unsigned int  pf_th;//功率因数上限
extern unsigned int uh_th;//电容运行电压上限
extern unsigned int swn;//补偿路数
void command_001_back(void)
{
 //VL_2nd=380;
 //IL_real_uart=2500;
 //relay_state_2nd=7;
 printf("\r\n");
 //0.
 printf("@%03d 001",(uint16)rs485_com_adr);
 //1.
 printf(" %03d",VL_2nd);
 //2.
 printf(" %04d",IL_real_uart);
 //printf(" %-04d")
 //pf_2nd=56;
 //3.
// pf_sign_2nd=IND;
 if(pf_sign_2nd==IND)
   {
	printf(" +%-04.2f",pf_2nd/100.0);
    }
 else
   {
	printf(" -%-04.2f",(pf_2nd/100.0));
    }
 //   */
  // pf_2nd=80;
  // printf(" %-04.2f",-(pf_2nd/100.0)); 
 //printf(" %-0d#\r\n",relay_state_2nd); 
 printf(" %05d",relay_state_2nd); 
 //-----------------------------------------------
 //2017.11.6 add part
 //-----------------------------------------------
 //4.ct_set
 printf(" %05d",ct_ratio);
 //5.iq_step
 printf(" %04d",Iq_set);
 //C:\quick_v5_2017.10.30\control.h:8: extern unsigned int Iq_set;
 //6.dt
 printf(" %05d",dt_interval);
 //7.pf_th
 printf(" %-04.2f",pf_th/100.0);
 //8.uh_th
 printf(" %04d",uh_th);
 //9.sw_sum
 printf(" %04d",swn);
 
 printf("#\r\n");
 
 }

//2020 modbus code 
///

int cnt_1ms_end=0;
int GET_EN=TRUE;
int pp_save=0;
unsigned char modbus_get_buff[100];

extern uint8 GetTemp;
//帧数据接收函数
void modbus_recieve(void)
{
 cnt_1ms_end=0;//
 if(GET_EN==TRUE)
   {
    modbus_get_buff[pp_save]=GetTemp;
    if(pp_save<99)
      {pp_save++;}
    }
 }

unsigned char modbus_send_buff[100];
unsigned char modbus_reg_data[20];//

void modbus_reg_data_init(void)
{
 int i;
 for(i=0;i<20;i++)
   {modbus_reg_data[i]=i;}
 }

void modbus_reg_update(void)
{
 /*
  0   380是当前电网电压
  1   2500是当前系统的电流
  2   小于100,例如98  代表0.98  大于100,代表容性,例如198,代表功率因数是-0.98
  3   7代表当前投切状态,转化成12位的二进制数,0000 0000 0000 0111
      “1”代表投入,“0”代表未投入
  4   00100 CT变比  100:5
  5   0020  单组电容电流
  6   00020  动作时间间隔单位ms,20ms
  7   0.90   补偿功率因数上限
  8   0420过电压保护阀值
  9   0012补偿总路数,12路
  */
/*
  VL_2nd=100;
  IL_real_uart=100;
  pf_2nd=98;
  relay_state_2nd=0xfff;
  ct_ratio=100;
  Iq_set=30;
  dt_interval=100;
  pf_th=98;
  uh_th=100;
  swn=10;
 */
//1  电网电压
   modbus_reg_data[0]=VL_2nd>>8;
   modbus_reg_data[1]=VL_2nd&0xff;
//2 电网侧电流   
   modbus_reg_data[2]=IL_real_uart>>8;
   modbus_reg_data[3]=IL_real_uart&0xff;
//3.功率因数
   if(pf_sign_2nd==IND)//感性
    {
      modbus_reg_data[4]=(unsigned int)pf_2nd>>8;
      modbus_reg_data[5]=(unsigned int)pf_2nd&0xff;
    }
    else
    {
     modbus_reg_data[4]=(unsigned int)(pf_2nd+100)>>8;
     modbus_reg_data[5]=(unsigned int)(pf_2nd+100)&0xff;
     }
//4 当前投切状态
   modbus_reg_data[6]=relay_state_2nd>>8;
   modbus_reg_data[7]=relay_state_2nd&0xff;
//5 CT变比比率 100,代表(500:5 或者100:1)
   modbus_reg_data[8]=ct_ratio>>8;
   modbus_reg_data[9]=ct_ratio&0xff;
//6 单组电容电流
   modbus_reg_data[10]=Iq_set>>8;
   modbus_reg_data[11]=Iq_set&0xff;
//7 动作时间间隔
   modbus_reg_data[12]=dt_interval>>8;
   modbus_reg_data[13]=dt_interval&0xff;
// 8   0.90   补偿功率因数上限
   modbus_reg_data[14]=pf_th>>8;
   modbus_reg_data[15]=pf_th&0xff;
//9 420过电压保护阀值
   modbus_reg_data[16]=uh_th>>8;
   modbus_reg_data[17]=uh_th&0xff;
//10 0012补偿总路数,12路
   modbus_reg_data[18]=swn>>8;
   modbus_reg_data[19]=swn&0xff; 


  Nop();
  Nop();
 }
///
//帧数据发送函数

void modbus_byte_send(unsigned char n)
{
 int i;
 for(i=0;i<n;i++)
 {
   //modbus_send_buff[i]=i;
   U1TXREG=modbus_send_buff[i];	// 返送接收到的数
  }
 }

#define  FRAME_TIME   200  //20ms
void modbus_echo(void)
{
 unsigned char x=100;
 int i=0;
 unsigned int reg_addr=0;
 unsigned int num_data=0;
 unsigned char CRC_L,CRC_H;
 unsigned int crc16,crc16_get;

 //IEC0bits.U1TXIE=1;
 //U1STAbits.UTXEN=1;//发送使能!!!
 IEC0bits.U1TXIE=1;U1STAbits.UTXEN=1;
 if((cnt_1ms_end>FRAME_TIME)&&(pp_save>7))
  {
     GET_EN=FALSE;
     cnt_1ms_end=0;
     R485C=1;
	 Nop();Nop();Nop();Nop();
	 Nop();Nop();Nop();Nop();
     
     reg_addr=((unsigned int)modbus_get_buff[2]<<8)+modbus_get_buff[3];
     num_data=((unsigned int)modbus_get_buff[4]<<8)+modbus_get_buff[5];
     crc16_get=((unsigned int)modbus_get_buff[6]<<8)+modbus_get_buff[7];
     crc16=CRC16(modbus_get_buff,6);
     Nop();
     /
     if(modbus_get_buff[0]==rs485_com_adr)//地址判断
     {
       if(modbus_get_buff[1]==0x03)//功能代码判断
         {
          if((reg_addr<10)&&(num_data<=10)&&(crc16_get==crc16))//地址 数据 CRC  校验
            {
              //todo:modbus 数据准备与发送 
              modbus_send_buff[0]=rs485_com_adr;
              modbus_send_buff[1]=0x03;
              modbus_send_buff[2]=num_data*2;//数据字节个数
              for(i=0;i<num_data;i++)
               {
                modbus_send_buff[3+2*i]=modbus_reg_data[reg_addr*2];
                modbus_send_buff[3+2*i+1]=modbus_reg_data[reg_addr*2+1];
                reg_addr++;
                }
              //add crc data
               CRC_L=CRC16(modbus_send_buff,3+num_data*2)>>8;
               CRC_H=CRC16(modbus_send_buff,3+num_data*2)&0xff;
               modbus_send_buff[3+num_data*2]=CRC_L;
               modbus_send_buff[3+num_data*2+1]=CRC_H;
              //send
              modbus_byte_send(5+num_data*2);
              Nop();
              Nop();
              }
          }
      }


     //modbus_byte_send(50);
	 pp_save=0;
    
     /
	 Nop();Nop();Nop();Nop();
	 Nop();Nop();Nop();Nop();
	 R485C=0; 

     GET_EN=TRUE;
   }
 }
///

void UartGetReturn(void)
{
 uint8 com_addr,com_command;
 if(SIND_Get_Flag==TRUE)
  {
	com_addr=(rxd_get[1]-'0')*100+(rxd_get[2]-'0')*10+(rxd_get[3]-'0');
	com_command=(rxd_get[4]-'0')*100+(rxd_get[5]-'0')*10+(rxd_get[6]-'0');
//	if(com_addr==rs485_com_adr)
    if(1)
	 {
	  switch(com_command)
	     {
		  case 1:
		  		  R485C=1;
			      Nop();Nop();Nop();Nop();
			      Nop();Nop();Nop();Nop();
			      //printf("%s",rxd_get);
			      //printf("\r\n");
			      //printf("----------------\r\n");
			      command_001_back();
			      //printf("command valid!\r\n");
			      R485C=0;
			      Nop();Nop();Nop();Nop();
			      Nop();Nop();Nop();Nop();
		  		 break;
		  default:
		  		  R485C=1;
			      Nop();Nop();Nop();Nop();
			      Nop();Nop();Nop();Nop();
			      //printf("%s",rxd_get);
			      //printf("\r\n");
			      //printf("----------------\r\n");
			      printf("command no valid!\r\n");
			      R485C=0;
			      Nop();Nop();Nop();Nop();
			      Nop();Nop();Nop();Nop();
			      break;
	      }
	  /*
      R485C=1;
      Nop();Nop();Nop();Nop();
      Nop();Nop();Nop();Nop();
      printf("%s",rxd_get);
      printf("\r\n");
      printf("----------------\r\n");
      R485C=0;
      Nop();Nop();Nop();Nop();
      Nop();Nop();Nop();Nop();
      */	  
	  }
	/*
    R485C=1;
    Nop();Nop();Nop();Nop();
    Nop();Nop();Nop();Nop();
    printf("%s",rxd_get);
    printf("\r\n");
    printf("----------------\r\n");
    R485C=0;
    Nop();Nop();Nop();Nop();
    Nop();Nop();Nop();Nop();
    */
    
    SIND_Get_Flag=FALSE;
   } 
 }
 
void __attribute__((__interrupt__)) _U1TXInterrupt()
 {
	while(U1STAbits.TRMT ==0);	//当为0时,表明移位寄存器没空
	IFS0bits.U1TXIF=0;			//发送中断标志位清零   
 }

void io_init(void)
{
  TRISGbits.TRISG14=0;
  Nop();
  R485C=1;
  Nop();
  R485C=0;
  Nop();
 }

void Send1Byte(void)
{
 unsigned char i;
 printf("**************************************************************\r\n");
 printf("*                   电能质量分析结果                         * \r\n");
 printf("**************************************************************\r\n");
 printf("频率f=%6.3f(Hz)\r\n",(1000000.0)/(float)FreqTerm);
 printf("功率Pa=%8.2f(W),Pb=%8.2f(W),Pc=%8.2f(W)\r\n",Pa,Pb,Pc);

 printf("功率因数cosFA=%5.2f,cosFB=%5.2f,cosFC=%5.2f\r\n",cosFA,cosFB,cosFC);

 printf("有效值(有名值):\r\n");
 printf("Va=%d(V),Vb=%d(V),Vc=%d(V)\r\n",Va_rms,Vb_rms,Vc_rms);
 printf("Ia=%f(A),Ib=%f(A),Ic=%f(A)\r\n",Ia_rms/100.0,Ib_rms/100.0,Ic_rms/100.0);
 printf("--------------------------------------------------------------\r\n");
 printf("谐波总畸变率:\r\n");
 printf("-------------------------------------------------------------\r\n");
 printf("THD is: Va_THD=%d%%%,Vb_THD=%d%%,Vc_THD=%d%%\r\n",Va_THD,Vb_THD,Vc_THD);
 printf("THD is: Ia_THD=%d%%%,Ib_THD=%d%%,Ic_THD=%d%%\r\n",Ia_THD,Ib_THD,Ic_THD);
 printf("-------------------------------------------------------------\r\n");
 printf("谐波含量(百分值)\r\n");
 for(i=1;i<32;i++)
 {
  printf("%2dst----Va=%d%%,Vb=%d%%,Vc=%d%%,Ia=%d%%,Ib=%d%%,Ic=%d%%",\
               i,Va_dft_pu[i],Vb_dft_pu[i],Vc_dft_pu[i],\
                 Ia_dft_pu[i],Ib_dft_pu[i],Ic_dft_pu[i]);
  printf("\r\n");
  printf("-------------------------------------------------------------\r\n");
  }
 printf("**************************************************************\r\n");
 printf("*                   The End of the Report                     * \r\n");
 printf("**************************************************************\r\n");
 }
 
unsigned char  print_cnt=0;
void UartSend(void)
{
 unsigned char i;
 switch(print_cnt)
 {case 0:
         printf("**************************************************************\r\n");
         printf("*                   电能质量分析结果                         * \r\n");
         printf("**************************************************************\r\n");
         break;
  case 1: 
         printf("频率f=%6.3f(Hz)\r\n",(1000000.0)/(float)FreqTerm);
         printf("功率Pa=%8.2f(W),Pb=%8.2f(W),Pc=%8.2f(W)\r\n",Pa,Pb,Pc);
         break;
  case 2:

         printf("功率因数cosFA=%5.2f,cosFB=%5.2f,cosFC=%5.2f\r\n",cosFA,cosFB,cosFC);

         printf("有效值(有名值):\r\n");
         break;
  case 3:
         printf("Va=%d(V),Vb=%d(V),Vc=%d(V)\r\n",Va_rms,Vb_rms,Vc_rms);
         printf("Ia=%f(A),Ib=%f(A),Ic=%f(A)\r\n",Ia_rms/100.0,Ib_rms/100.0,Ic_rms/100.0);
         break;
  case 4:
 		 printf("--------------------------------------------------------------\r\n");
         printf("谐波总畸变率:\r\n");
         printf("-------------------------------------------------------------\r\n");
         break;
  case 5:
         printf("THD is: Va_THD=%d%%%,Vb_THD=%d%%,Vc_THD=%d%%\r\n",Va_THD,Vb_THD,Vc_THD);
         printf("THD is: Ia_THD=%d%%%,Ib_THD=%d%%,Ic_THD=%d%%\r\n",Ia_THD,Ib_THD,Ic_THD);
         break;
  case 6:
         printf("-------------------------------------------------------------\r\n");
         printf("谐波含量(百分值)\r\n");
         break;
  case 7:
  case 8:
  case 9:
  case 10:
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
  case 16:
  case 17:
  case 18:
  case 19:
  case 20:
  case 21:
  case 22:
  case 23:
  case 24:
  case 25:
  case 26:
  case 27:
  case 28:
  case 29:
  case 30:
  case 31:
  case 32:
  case 33:
  case 34:
  case 35:
  case 36:
  case 37:
        i=print_cnt-6;
        printf("%2dst----Va=%d%%,Vb=%d%%,Vc=%d%%,Ia=%d%%,Ib=%d%%,Ic=%d%%",\
               i,Va_dft_pu[i],Vb_dft_pu[i],Vc_dft_pu[i],\
                 Ia_dft_pu[i],Ib_dft_pu[i],Ic_dft_pu[i]);
         printf("\r\n");
         printf("-------------------------------------------------------------\r\n");
        // }
         break;
  case 38:
        printf("**************************************************************\r\n");
        printf("*                   The End of the Report                     * \r\n");
        printf("**************************************************************\r\n");
        break;
  default:print_cnt=0;break;
 }
 print_cnt++;
 if(print_cnt>38){print_cnt=0;}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iCxhust

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值