Устанавливать ошибки DCB при попытке настроить COM-порт - PullRequest
4 голосов
/ 16 ноября 2010

Я пытаюсь написать приложение CFC MFC, использующее последовательный порт (например, COM8). Каждый раз, когда я пытаюсь установить DCB, происходит сбой. Если кто-то может указать на то, что я делаю неправильно, я был бы очень признателен.

DCB dcb = {0};

dcb.DCBlength = sizeof(DCB);
port.Insert( 0, L"\\\\.\\" );

m_hComm = CreateFile(
    port,                           // Virtual COM port
    GENERIC_READ | GENERIC_WRITE,   // Access: Read and write
    0,                              // Share: No sharing
    NULL,                           // Security: None
    OPEN_EXISTING,                  // The COM port already exists.
    FILE_FLAG_OVERLAPPED,           // Asynchronous I/O.
    NULL                            // No template file for COM port.
    );

if ( m_hComm == INVALID_HANDLE_VALUE )
{
    TRACE(_T("Unable to open COM port."));
    ThrowException();
}

if ( !::GetCommState( m_hComm, &dcb ) )
{
    TRACE(_T("CSerialPort : Failed to get the comm state - Error: %d"), GetLastError());
    ThrowException();
}

dcb.BaudRate = 38400;               // Setup the baud rate.
dcb.Parity = NOPARITY;              // Setup the parity.
dcb.ByteSize = 8;                   // Setup the data bits.
dcb.StopBits = 1;                   // Setup the stop bits.

if ( !::SetCommState( m_hComm, &dcb ) ) // <- Fails here.
{
    TRACE(_T("CSerialPort : Failed to set the comm state - Error: %d"), GetLastError());
    ThrowException();
}

Спасибо.

Дополнительная информация: Сгенерированный код ошибки 87: «Параметр неверен». Вероятно, самый полезный код ошибки Microsoft. Дж / К

Ответы [ 5 ]

11 голосов
/ 16 ноября 2010

Мои деньги на это:

dcb.StopBits = 1; 

Документ MSDN говорит об этом в StopBits:

Количество используемых стоп-битов.Этот элемент может иметь одно из следующих значений:

ONESTOPBIT    0    1 stop bit.
ONE5STOPBITS  1    1.5 stop bits.
TWOSTOPBITS   2    2 stop bits.

Итак, вы запрашиваете 1,5 стоповых бита, что является настолько ужасной архаичной вещью, что я даже не могу вспомнить, откуда она,Телепринтеры, возможно.

Я предполагаю, что шансы вашего драйвера / аппаратного обеспечения, поддерживающего этот режим, невелики, следовательно, ошибка.

Итак, измените его на dcb.StopBits = ONESTOPBIT;

3 голосов
/ 16 ноября 2010

Вот некоторые возможности в произвольном порядке.

  • GetCommState заполняет структуру мусором, поскольку порт еще не был инициализирован.Вы можете просто пропустить этот шаг.
  • Есть два параметра, которые управляют настройками контроля четности, и неясно, есть ли какие-либо недопустимые комбинации.
  • Значение для StopBits не является числом битов,это константа магического числа.Значение 1 соответствует ONE5STOPBITS, что может быть недопустимым при сочетании с другими параметрами.
2 голосов
/ 16 ноября 2010

Мне удалось решить проблему, используя BuildCommDCB:

DCB dcb = {0};

if ( !::BuildCommDCB( _T("baud=38400 parity=N data=8 stop=1"), &dcb ) )
{
    TRACE(_T("CSerialPort : Failed to build the DCB structure - Error: %d"), GetLastError());
    ThrowException();
}
1 голос
/ 11 июня 2018

Это мой код, и он работает хорошо.

/* Try to open the port */
hCom = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

if (hCom != INVALID_HANDLE_VALUE) {
    printf("Handle success\n");
}

    dcb = { 0 };
    dcb.DCBlength = sizeof(dcb);

    fSuccess = GetCommState(hCom, &dcb);

    if (!fSuccess) {
        // Handle the error.
        printf("GetCommState failed with error %d.\n", GetLastError());
        CloseHandle(hCom);
        return APP_ERROR;
    }

    // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.
    dcb = { 0 };
    dcb.DCBlength = sizeof(dcb);

    dcb.BaudRate = CBR_115200;     // Set the baud rate
    dcb.ByteSize = 8;              // Data size, xmit, and rcv
    dcb.Parity = NOPARITY;         // No parity bit
    dcb.StopBits = ONESTOPBIT;     // One stop bit

    fSuccess = SetCommState(hCom, &dcb);

    if (!fSuccess) {
        // Handle the error.
        printf("SetCommState failed with error %d.\n", GetLastError());
        CloseHandle(hCom);
        return APP_ERROR;
    }
}

printf("Serial port successfully reconfigured.\n");
0 голосов
/ 16 ноября 2010

Посмотрите на параметры, которые вы даете функции. Они, вероятно, неверны, как говорит код ошибки. Поиск Google "SetCommState 87" показывает несколько случаев, когда параметры (например, скорость передачи) были несовместимы с последовательным портом.

...