从WriteFile转换为QtSerial写入

时间:2017-01-04 19:21:02

标签: c++ qt serial-port

我正在尝试转换一些旧代码以使用QtSerial集成。

我有以下内容:

void SendCmd(HANDLE Handle, UCHAR Address, UCHAR Command, UCHAR Type, UCHAR Motor, INT Value)
{

    UCHAR TxBuffer[9];
    DWORD BytesWritten;
    int i;

    TxBuffer[0]=Address;
    TxBuffer[1]=Command;
    TxBuffer[2]=Type;
    TxBuffer[3]=Motor;
    TxBuffer[4]=Value >> 24;
    TxBuffer[5]=Value >> 16;
    TxBuffer[6]=Value >> 8;
    TxBuffer[7]=Value & 0xff;
    TxBuffer[8]=0;
    for(i=0; i<8; i++)
        TxBuffer[8]+=TxBuffer[i];

    //Send the datagram

  WriteFile(Handle, TxBuffer, 9, &BytesWritten, NULL);
}

我想使用QTSerial来处理端口和读取/发送数据。我有点过头了。对于我目前的处理:

HANDLE OpenRS2322(const wchar_t* ComName, DWORD BaudRate)
{
    HANDLE ComHandle;
    DCB CommDCB;
    COMMTIMEOUTS CommTimeouts;
    ComHandle=CreateFileW(ComName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if(GetLastError()!=ERROR_SUCCESS) return INVALID_HANDLE_VALUE;
    else
    {
        GetCommState(ComHandle, &CommDCB);

        CommDCB.BaudRate=BaudRate;
        CommDCB.Parity=NOPARITY;
        CommDCB.StopBits=ONESTOPBIT;
        CommDCB.ByteSize=8;

        CommDCB.fBinary=1;  //Binary Mode only
        CommDCB.fParity=0;
        CommDCB.fOutxCtsFlow=0;
        CommDCB.fOutxDsrFlow=0;
        CommDCB.fDtrControl=0;
        CommDCB.fDsrSensitivity=0;
        CommDCB.fTXContinueOnXoff=0;
        CommDCB.fOutX=0;
        CommDCB.fInX=0;
        CommDCB.fErrorChar=0;
        CommDCB.fNull=0;
        CommDCB.fRtsControl=RTS_CONTROL_TOGGLE;
        CommDCB.fAbortOnError=0;

        SetCommState(ComHandle, &CommDCB);

        //Set buffer size
        SetupComm(ComHandle, 100, 100);

        //Set up timeout values (very important, as otherwise the program will be very slow)
        GetCommTimeouts(ComHandle, &CommTimeouts);

        CommTimeouts.ReadIntervalTimeout=MAXDWORD;
        CommTimeouts.ReadTotalTimeoutMultiplier=0;
        CommTimeouts.ReadTotalTimeoutConstant=0;

        SetCommTimeouts(ComHandle, &CommTimeouts);

        return ComHandle;
  }
}

当我发送命令时,我使用(例如):

HANDLE RS232Handle;
    RS232Handle=OpenRS232(COM5, 9600);
    SendCmd(RS232Handle, 1, 5, 154, 5, 0);
    CloseRS232(RS232Handle);

我在QT中使用上面的代码遇到了一些问题。就像异步阅读问题一样。

我蹩脚的尝试修改上述代码以使用QSerialPort

对于端口的句柄:

QSerialPort serial;
    serial.setPortName("COM5");
    serial.open(QIODevice::ReadWrite);
    serial.setBaudRate(QSerialPort::Baud115200);
    serial.setDataBits(QSerialPort::Data8);
    serial.setParity(QSerialPort::NoParity);
    serial.setStopBits(QSerialPort::OneStop);
    serial.setFlowControl(QSerialPort::HardwareControl);
    if (serial.isOpen() && serial.isWritable())
    {
    qDebug() << "Serial is open";
      }

对于以前通过WriteFile发送的数据的实际写入,我不知道。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

由于QSerialPortQIODevice延伸,只需使用readwrite方法从端口发送和接收数据。在这方面,QSerialPort就像你用Qt打开的任何其他文件一样。当您向串行端口写出内容时,最简单的方法是将数据简单地放入QByteArray然后将其写出来。以下内容应该有效:

void SendCmd(QSerialPort* port, UCHAR Address, UCHAR Command, UCHAR Type, UCHAR Motor, INT Value)
{

QByteArray ba;
UCHAR checksum = 0;

ba.append(Address);
ba.append(Command);
ba.append(Type);
ba.append(Motor);
ba.append(Value >> 24;
ba.append(Value >> 16);
ba.append(Value >> 8);
ba.append(Value & 0xff);
for(i=0; i<8; i++)
    checksum += ba[i];
ba.append( checksum );

//Send the datagram
port->write( ba );
}

请注意,此时数据可能尚未写入设备(一旦控制返回主循环就会发生这种情况)。

要读取数据,请创建一个连接到串行端口的readyRead信号的插槽。当有一些数据要从端口读取时,会发出此信号。一个简单的实现可能如下所示:

/* When the seral port is made */
/* (using new signal/slot syntax) */
connect( serialPort, &QSerialPort::readyRead,
         this, &MyClass::readyRead );

/* ... other initialization code ... */

void MyClass::readyRead(){
    QByteArray data = serialPort.readAll();

    /* Data processing here */
}