RS232 四入四出模块控制代码

通信标准入门:rs232和rs485的区别系统学习 深入讲解rs232和rs485的区别,从传输距离、电气特性到应用场景全面对比,帮助掌握两种常见串行通信标准的核心差异,适合初学者系统学习rs232和rs485的区别。 阅读详情
#ifndef ZIOMODULE_H
#define ZIOMODULE_H

#include <QObject>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>

#define ZDebugInfo    1

#define ADDR_DEST   0x01
const uchar zresponse_failed[]={0xA3,0x0D,0x0A,};
const uchar zcmd_output1_open[]={0x3A,0x88,ADDR_DEST,0x01,0x00,0x0D,0x0A};
const uchar zcmd_output1_close[]={0x3A,0x88,ADDR_DEST,0x01,0xFF,0x0D,0x0A};
const uchar zcmd_output2_open[]={0x3A,0x88,ADDR_DEST,0x02,0x00,0x0D,0x0A};
const uchar zcmd_output2_close[]={0x3A,0x88,ADDR_DEST,0x02,0xFF,0x0D,0x0A};
const uchar zcmd_output3_open[]={0x3A,0x88,ADDR_DEST,0x03,0x00,0x0D,0x0A};
const uchar zcmd_output3_close[]={0x3A,0x88,ADDR_DEST,0x03,0xFF,0x0D,0x0A};
const uchar zcmd_output4_open[]={0x3A,0x88,ADDR_DEST,0x04,0x00,0x0D,0x0A};
const uchar zcmd_output4_close[]={0x3A,0x88,ADDR_DEST,0x04,0xFF,0x0D,0x0A};
const uchar zresponse_output_open_close[]={0xA3,ADDR_DEST,0x00,0xFF,0x0D,0x0A};

//get all relays status.
const uchar zcmd_get_all_relay_status[]={0x3A,0x99,ADDR_DEST,0x00,0x0D,0x0A};
const uchar zresponse_all_relay_status[]={0xA3,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A};
//get all input status.
const uchar zcmd_get_all_inputs_status[]={0x3A,0x98,ADDR_DEST,0x00,0x0D,0x0A};
const uchar zresponse_all_inputs_status[]={0xA5,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A};



class ZIOModule : public QObject
{
    Q_OBJECT
public:
    typedef enum
    {
        OutputPort1=1,
        OutputPort2=2,
        OutputPort3=3,
        OutputPort4=4,
    }ZOutputPort;
    //portName: ttyUSB0.
    //responseTimeout: the wait time for the device response.
    explicit ZIOModule(QString portName,qint32 responseTimeOut=2000,QObject *parent = 0);
    ~ZIOModule();

    //execute serial port initial operations.
    bool ZDoInit();

    //do some clean work here.
    void ZCleanUp();

    //set output status of specified port.
    bool ZSetOutputPort(ZOutputPort port,bool bOpen);

    //get all output port status.
    qint32 ZGetOutputPortsStatus(qint32 *status);

    //get all input port status.
    qint32 ZGetInputPortsStatus(qint32 *status);

signals:

public slots:

private:
    qint32 ZWriteData(const uchar *cmd,quint32 len);
    bool ZVerifyResponseForOutputOpenClose(qint32 index,bool bOpen);
private:
    QSerialPort *m_serialPort;
    qint32 m_responseTimeout;
};

#endif // ZIOMODULE_H




#include "ziomodule.h"

ZIOModule::ZIOModule(QString portName,qint32 responseTimeOut,QObject *parent) :
    QObject(parent)
{
    this->m_serialPort=new QSerialPort(portName);
    this->m_responseTimeout=responseTimeOut;
}
ZIOModule::~ZIOModule()
{
    delete this->m_serialPort;
}
bool ZIOModule::ZDoInit()
{
    this->m_serialPort->setBaudRate(QSerialPort::Baud9600);
    this->m_serialPort->setDataBits(QSerialPort::Data8);
    this->m_serialPort->setStopBits(QSerialPort::OneStop);
    this->m_serialPort->setParity(QSerialPort::NoParity);
    this->m_serialPort->setFlowControl(QSerialPort::NoFlowControl);
    this->m_serialPort->setReadBufferSize(1024);
    if(!this->m_serialPort->open(QIODevice::ReadWrite))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:"<<this->m_serialPort->errorString();
        qDebug()<<"available ports are:";
        foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
        {
            qDebug()<<info.portName();
        }
#endif
        return false;
    }
    //clear input buffer before.
    (void)this->m_serialPort->readAll();
    return true;
}
void ZIOModule::ZCleanUp()
{
    this->m_serialPort->flush();
    this->m_serialPort->close();
}
qint32 ZIOModule::ZWriteData(const uchar *cmd,quint32 len)
{
    qint32 tWrites=-1;
    if(this->m_serialPort && this->m_serialPort->isOpen())
    {
        QByteArray tSendBuffer((char*)cmd,len);
        tWrites=this->m_serialPort->write(tSendBuffer);
        this->m_serialPort->waitForBytesWritten(100);
    }
    return tWrites;
}
//set output status of specified port.
bool ZIOModule::ZSetOutputPort(ZOutputPort port,bool bOpen)
{
    qint32 portIndex;
    switch(port)
    {
    case ZIOModule::OutputPort1:
        if(bOpen)
        {
            this->ZWriteData(zcmd_output1_open,sizeof(zcmd_output1_open));
        }else{
            this->ZWriteData(zcmd_output1_close,sizeof(zcmd_output1_close));
        }
        portIndex=1;
        break;
    case ZIOModule::OutputPort2:
        if(bOpen)
        {
            this->ZWriteData(zcmd_output2_open,sizeof(zcmd_output2_open));
        }else{
            this->ZWriteData(zcmd_output2_close,sizeof(zcmd_output2_close));
        }
        portIndex=2;
        break;
    case ZIOModule::OutputPort3:
        if(bOpen)
        {
            this->ZWriteData(zcmd_output3_open,sizeof(zcmd_output3_open));
        }else{
            this->ZWriteData(zcmd_output3_close,sizeof(zcmd_output3_close));
        }
        portIndex=3;
        break;
    case ZIOModule::OutputPort4:
        if(bOpen)
        {
            this->ZWriteData(zcmd_output4_open,sizeof(zcmd_output4_open));
        }else{
            this->ZWriteData(zcmd_output4_close,sizeof(zcmd_output4_close));
        }
        portIndex=4;
        break;
    default:
#ifdef ZDebugInfo
        qDebug()<<"error:invalid output port index!";
#endif
        return false;
    }
    return this->ZVerifyResponseForOutputOpenClose(portIndex,bOpen);
}
bool ZIOModule::ZVerifyResponseForOutputOpenClose(qint32 index,bool bOpen)
{
    Q_UNUSED(index);
    Q_UNUSED(bOpen);
    //here we use sync mode to wait device's response.
    //wait for device response.
    qint32 tWaitTimeout=0;
    while(this->m_serialPort->bytesAvailable()<6)
    {
        this->m_serialPort->waitForReadyRead(1000);
        if(++tWaitTimeout>=3)
        {
#ifdef ZDebugInfo
            qDebug()<<"error:device no response,timeout.";
#endif
            return false;
        }
    }
    QByteArray tRecvBuffer=this->m_serialPort->readAll();
    if(tRecvBuffer.count()!=sizeof(zresponse_output_open_close) && tRecvBuffer.count()!=sizeof(zresponse_failed))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:invalid response!";
        qDebug("success:%d,failed:%d,now is %d.\n",sizeof(zresponse_output_open_close),sizeof(zresponse_failed),tRecvBuffer.count());
#endif
        return false;
    }
    if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed)))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:device execute command failed!";
#endif
        return  false;
    }
    //{0xA3,ADDR_DEST,0x00,0xFF,0x0D,0x0A};
    //verify the response byte by byte.
    qint32 tPrefix=(qint32)tRecvBuffer.at(0)&0xFF;
    qint32 tAddr=(qint32)tRecvBuffer.at(1)&0xFF;
    qint32 tSuffix1=(qint32)tRecvBuffer.at(tRecvBuffer.count()-2)&0xFF;
    qint32 tSuffix2=(qint32)tRecvBuffer.at(tRecvBuffer.count()-1)&0xFF;
    if(0xA3!=tPrefix || ADDR_DEST!=tAddr || 0x0D!=tSuffix1 || 0x0A!=tSuffix2)
    {
#ifdef ZDebugInfo
        qDebug()<<"error:specified byte is not right!";
#endif
        return false;
    }
    return true;
}
//get all output ports status.
qint32 ZIOModule::ZGetOutputPortsStatus(qint32 *status)
{
    qint32 ret;
    ret=this->ZWriteData(zcmd_get_all_relay_status,sizeof(zcmd_get_all_relay_status));
    if(ret!=sizeof(zcmd_get_all_relay_status))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:write data failed!";
#endif
        return -1;
    }
    if(!this->m_serialPort->waitForReadyRead(this->m_responseTimeout))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:wait for response timeout!";
#endif
        return -1;
    }
    QByteArray tRecvBuffer=this->m_serialPort->readAll();
    if(tRecvBuffer.count()!=sizeof(zresponse_all_relay_status) && tRecvBuffer.count()!=sizeof(zresponse_failed))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:invalid response!";
#endif
        return -1;
    }
    if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed)))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:device execute command failed!";
#endif
        return -1;
    }
    //{0xA3,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A};
    //verify byte by byte.
    qint32 tPrefix=(qint32)tRecvBuffer.at(0)&0xFF;
    qint32 tAddr=(qint32)tRecvBuffer.at(1)&0xFF;
    qint32 tSuffix1=(qint32)tRecvBuffer.at(tRecvBuffer.count()-2)&0xFF;
    qint32 tSuffix2=(qint32)tRecvBuffer.at(tRecvBuffer.count()-1)&0xFF;
    if(0xA3!=tPrefix || ADDR_DEST!=tAddr || 0x0D!=tSuffix1 || 0x0A!=tSuffix2)
    {
#ifdef ZDebugInfo
        qDebug()<<"error:specified byte is not right!";
#endif
        return -1;
    }
    //combine bytes.
    *status=(qint32)tRecvBuffer.at(2)<<24|(qint32)tRecvBuffer.at(3)<<16|(qint32)tRecvBuffer.at(4)<<8|(qint32)tRecvBuffer.at(5)<<0;
    return 0;
}
//get all input port status.
qint32 ZIOModule::ZGetInputPortsStatus(qint32 *status)
{
    qint32 ret;
    ret=this->ZWriteData(zcmd_get_all_inputs_status,sizeof(zcmd_get_all_inputs_status));
    if(ret!=sizeof(zcmd_get_all_inputs_status))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:write data failed!";
#endif
        return -1;
    }

    qint32 waitTimeout=0;
    while(this->m_serialPort->bytesAvailable()<8)
    {
        this->m_serialPort->waitForReadyRead(1000);
        if(++waitTimeout>5)
        {
#ifdef ZDebugInfo
            qDebug("error:device no response!");
#endif
            return -1;
        }
    }

    QByteArray tRecvBuffer=this->m_serialPort->readAll();
    if(tRecvBuffer.count()!=sizeof(zresponse_all_inputs_status) && tRecvBuffer.count()!=sizeof(zresponse_failed))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:invalid response!";
#endif
        return -1;
    }
    if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed)))
    {
#ifdef ZDebugInfo
        qDebug()<<"error:device execute command failed!";
#endif
        return -1;
    }
    //{0xA5,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A};
    //verify byte by byte.
    qint32 tPrefix=(qint32)tRecvBuffer.at(0)&0xFF;
    qint32 tAddr=(qint32)tRecvBuffer.at(1)&0xFF;
    qint32 tSuffix1=(qint32)tRecvBuffer.at(tRecvBuffer.count()-2)&0xFF;
    qint32 tSuffix2=(qint32)tRecvBuffer.at(tRecvBuffer.count()-1)&0xFF;
    if(0xA5!=tPrefix || ADDR_DEST!=tAddr || 0x0D!=tSuffix1 || 0x0A!=tSuffix2)
    {
#ifdef ZDebugInfo
        qDebug()<<"error:specified byte is not right!";
#endif
        return -1;
    }
    //combine bytes.
    *status=(qint32)tRecvBuffer.at(2)<<24|(qint32)tRecvBuffer.at(3)<<16|(qint32)tRecvBuffer.at(4)<<8|(qint32)tRecvBuffer.at(5)<<0;
    return 0;
}

#include <QCoreApplication>
#include <QThread>
#include <ziomodule.h>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    bool bRet;
    qint32 tInportStatus;
    ZIOModule ioModule("ttyUSB0");
    if(!ioModule.ZDoInit())
    {
        qDebug()<<"initial failed!";
        return -1;
    }
#if 1
    while(1)
    {
        ioModule.ZGetInputPortsStatus(&tInportStatus);
        QThread::sleep(1);
        qDebug("InputPort:0x%x\n",tInportStatus);
    }
#endif

#if 1
    while(1)
    {
        bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort1,true);
        QThread::sleep(1);
        bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort2,true);
        QThread::sleep(1);
        bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort3,true);
        QThread::sleep(1);
        bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort4,true);
        QThread::sleep(5);


        bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort1,false);
        QThread::sleep(1);
        bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort2,false);
        QThread::sleep(1);
        bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort3,false);
        QThread::sleep(1);
        bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort4,false);
        QThread::sleep(5);
    }
#endif
    //ioModule.ZCleanUp();
    return a.exec();
}


长距离传输中RS485和RS232性能对比及硬件优化 在长距离数据传输场景中,rs485和rs232通信协议的表现差异显著。RS485凭借差分信号优势,在抗干扰和传输距离上远超RS232,适用于工业环境。结合硬件设计优化,可进一步提升rs485和rs232通信协议的稳定性与可靠性。 阅读详情

相关推荐

RS485与RS232通信距离限制及原理入门

深入浅出讲解rs485和rs232通信协议的关键区别,重点剖析两者在通信距离上的限制原因。通过电气特性与信号传输机制的对比,帮助理解rs485和rs232通信协议在工业应用中的实际选择依据。

weixin_42452924的博客 312

使用QT程序控制Linux开发板上的继电器(二)

接上文,驱动程序已经完成,接下来编写QT程序

weixin_45457363的博客 973

低成本方案中RS485与RS232接口共享设计技巧

在低成本方案中实现RS485和RS232通信协议的高效共存,通过合理电路设计与信号切换机制,提升系统兼容性与稳定性,适用于多种工业通信场景。

weixin_30633869的博客 809

Qt继电器控制板代码

#ifndef ZIOMODULE_H #define ZIOMODULE_H #include #include #include #include #define ADDR_DEST   0x01 const uchar zresponse_failed[]={0xA3,0x0D,0x0A,}; const uchar zcmd_output1_open[]={

烟台 嵌入式产品开发 1348

RS485 vs RS232:电气特性对比新手教程

RS485和RS232通信协议在工业现场和嵌入式系统中应用广泛,但它们的电气特性差异显著:RS485支持多点、远距离、抗干扰强的差分传输,而RS232仅限点对点、短距离、单端通信。理解这些区别,是选型和调试RS485和RS232通信协议的关键第一步。

weixin_35706067的博客 399

基于FPGA的串口通信RS232:从原理到实现

在RS232协议中,使用了两条信号线(TXD和RXD)来传输数据,同时还需要使用几条控制信号线(如RTS、CTS、DSR等)来进行流控制、错误检测等操作。3.编写通信协议:为了使FPGA和其他设备间能够进行正常的通信,我们需要定义一套符合RS232协议的通信规范。下面是一个简单的FPGA代码示例,用于实现基于RS232协议的串口通信。通过合理的电路连接、逻辑设计和通信协议的制定,我们可以轻松地搭建起一个高效稳定的串口通信系统。在这里,我们需要实现串口数据的接收和发送功能,同时还需要进行信号的控制和管理。

uote_e的博客 198

使用QT程序控制Linux开发板上的继电器(一)

通过点击QT程序上的按钮来控制连接在IMX6ULL开发板IO上继电器的通断,进而控制连接在继电器上的LED的点亮与熄灭。

weixin_45457363的博客 1599

CAPL通过RS232通信发送指令控制程控电源

本文调试的是ITECH系列电源,IT6512,IT6722等程控电源,必须是可以程控的电源。其他品牌的也可参考,只是发送的指令有些差别而已,RS232通信都是可以复用的。像tdk lambda电源改下指令就可以直接使用。 以下是两款电源的指令区别。 本文实现的内容可以通过代码控制,也可以在面板上控制,函数都已实现,直接调用使用即可,在自己的测试代码需要控制电源的步骤中插入即可。ITECH 艾德克斯 电源 官方程控上位机安装 上面这个链接里有驱动下载和指令手册。 visa和icp是必须要安装的。 NI-VI

天赐好车的博客 4279

继电器介绍及qt操作继电器实战

继电器介绍及qt操作继电器实战

qq_71286244的博客 1434

投影机232控制代码汇总.doc

市面上大部分投影机的串口控制码,3M…………………………………………………………………1 ASK………………………………………………………………2 BARCO……………………………………………………………4 BOXLIGHT………………………………………………………4 CHRISTIE…………………………………………………………5 DIGITEL……………………………………………………………6 EIKI…………………………………………………………7 INFOCUS…………………………………………………………10 LENOVO…………………………………………………………14 LG…………………………………………………………………15 LIESEGANG………………………………………………………15 LUMENS…………………………………………………………15 MITSUBISHI……………………………………………………16 NEC………………………………………………………………17 OPTOMA…………………………………………………………18 PLUS………………………………………………………………19 POLAROID………………………………………………………19 PROJECTIONDESIGN……………………………………………19 PROXIMA…………………………………………………………20 VIEWSONIC………………………………………………………23 爱普生……………………………………………………………23 奥视………………………………………………………………27 东芝………………………………………………………………28 飞浰普……………………………………………………………30 富士通……………………………………………………………31 惠普………………………………………………………………31 佳能………………………………………………………………32 明基………………………………………………………………33 日立………………………………………………………………35 三洋………………………………………………………………36 胜利………………………………………………………………40 松下………………………………………………………………41 索尼………………………………………………………………42 夏普………………………………………………………………43

vb上位机控制51系列单片机开关继电器软件

上下位机串口控制,vb上位机串口控制,下位机用的at89s52,

HONEYWELL 05704-A-0144 四通道控制卡 控制卡 可编程

支持多种通信接口,如RS232、RS485、CAN等,方便与各种设备和控制系统进行连接和集成。这种通信接口的多样性使得控制卡能够轻松地与现有的设备和系统兼容,降低了系统集成的难度和成本。控制卡可以同时控制四个通道的输入和输出信号,这大大提高了控制系统的灵活性和可扩展性。在需要同时监控和控制多个设备或参数的应用场景中,这种设计非常有用。这种可编程性为用户提供了很大的灵活性,使得控制卡能够适应各种复杂的工业自动化需求。采用高效的电路设计和优质的材料,确保长时间稳定运行,降低故障率。

WX13265023130的博客 296

C#上位机控制8路继电器

可以通过上位机控制8路继电器,直接提供的源码,稍加改动,可以进行自己的项目

rs232串口接线图_8路电源控制器控制代码和接线图

一、串口控制指令说明串口控制的波特率为9600。数据格式8N1。下表中的控制指令都是16进制格式。COM口的接线顺序:2TX,3RX,5GND。命令名称命令指令说明继电器控制指令0XAF 0X73 ID PORT Logic 0X0D 0X0ALogic为1就继电器闭合。Logic为0就断开输出。ID表示设备的ID码PORT 是0-7的数字,表示是哪个端口被控制二、接线示意图左边的4PI...

weixin_39572288的博客 7998

sony 投影机的232控制代码及发码程序

sony 投影机控制最重要的是要选择奇偶校验位偶校验,写中控的时候也一定要选择偶校验

树莓派3B Qt 使用GIOP 18 控制继电器开关

树莓派3B Qt 使用GIOP 18 控制继电器开关

Python与RS232继电器的自动化控制方法

** 一 前言 ** 在嵌入式测试过程中,通常会遇到需要对待测设备(DUT)进行上下电的情况,如果有程控电源,那么是更加好的选择;但是在没有程控电源的条件,我们可以选择价格亲民的RS232继电器。 ** 二 测试环境搭建 ** 将继电器的一路端口直接串联到DUT的电源线中即可,若有接线疑惑者,可以下方留言 ** 三 软件准备 ** 1.Python 3.7.0 2.Serial模块 ** 四 代码参考 ** # encoding=utf-8 import serial import time Serial

qq_39780125的博客 2803

Android 12高通thermal-engine调试实战:如何快速开启debug日志并解决CPU降频问题

本文详细介绍了Android 12高通thermal-engine的调试实战,包括如何快速开启debug日志、解读关键日志信息以及解决CPU降频问题。通过优化配置文件和调整温控策略,开发者可以有效提升设备性能,避免因温度管理导致的性能瓶颈。

i3j4k5的博客 305

RS232 串口介绍及针脚功能定义,串口定义,DB9,rs232

<br />RS232接口是1970年由美国电子工业协会(EIA)联合贝尔系统、调制解 调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。<br /><br /> 它的全名是“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准”该标准规定采用一个25个脚的DB25连接器,对 连接器的每个引脚的信号内容加以规定,还对各种信号的电平加以规定。DB25的串口一般只用到的管脚只有2(RXD)、3(TXD)、7(GND)这三 个,随着设备的不断改进,现在DB25针很少看到了

LYJ个人博客,记录技术、八卦、生活,分享各种心得,期待与朋友们一同进步 8935

深度解析中国支付清算体系

说起国之重器,不仅仅有 东风快递、渔16、渔17、渔18,还有另外一个国之重器-CNAPS2(中国支付清算体系)。 中国国内支付行业的发达水平、繁荣程度,不客气的讲,在全世界都是数一数二的,世界上最大的银行卡组织银联在中国,世界上交易量最大的网络零售支付清算体网联在中国。可以说现在我国经济的高速发展,离不开CNAPS2。

银行信息系统应用架构详解 2508

手把手教你学SOC芯片架构--NoC(片上网络,Network on Chip)全方位解析

​、​。

MHD0815的博客 863
上一篇: arm 自动升级脚本
下一篇: gstreamer插件之 videotestsrc
Yantai666
博客等级 码龄15年 45粉丝 271原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值