1

概述:我试图通过在从串行端口读取的每个字节之间发出长延迟来触发溢出错误指示。长话短说 - 我不明白这个事件。

测试:DTE配置为920000BPS 8N1,无流量控制。DTE 通过“Silicon Labs CP210x USB to UART Bridge”设备连接到我的 Windows10 主机。

提供的代码片段打开端口,调用 SetCommMask 函数。在循环中对 ReadFile 的每次调用之间插入了 10 秒的延迟。DTE 以稳定的速率连续发送数据。

问题:我没有收到来自 WaitCommEvent 的任何溢出信号。

问题:我的代码有问题吗?USB驱动程序有一些已知的限制吗?我是否需要使用流控制来引起关于溢出事件的注意?

#include <Windows.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
    HANDLE hComm;  // Handle to the Serial port
    BOOL   Status; // Status
    DCB dcbSerialParams = { 0 };  // Initializing DCB structure
    COMMTIMEOUTS timeouts = { 0 };  //Initializing timeouts structure
    char SerialBuffer[64] = { 0 }; //Buffer to send and receive data
    DWORD BytesWritten = 0;          // No of bytes written to the port
    DWORD dwEventMask;     // Event mask to trigger
    char  ReadData;        //temperory Character
    DWORD NoBytesRead;     // Bytes read by ReadFile()
    unsigned char loop = 0;
    wchar_t pszPortName[10] = { 0 }; //com port id
    wchar_t PortNo[20] = { 0 }; //contain friendly name
    //Enter the com port id
    do
    {
        printf_s("Enter the Com Port: ");
        wscanf_s(L"%s", pszPortName, (unsigned)_countof(pszPortName));
        swprintf_s(PortNo, 20, L"\\\\.\\%s", pszPortName);
        //Open the serial com port
        hComm = CreateFile(PortNo, //friendly name
            GENERIC_READ | GENERIC_WRITE,      // Read/Write Access
            0,                                 // No Sharing, ports cant be shared
            NULL,                              // No Security
            OPEN_EXISTING,                     // Open existing port only
            0,                                 // Non Overlapped I/O
            NULL);                             // Null for Comm Devices
        if (hComm == INVALID_HANDLE_VALUE)
        {
            printf_s("\n Port can't be opened\n\n");
            break;
        }
        //Setting the Parameters for the SerialPort
        dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
        Status = GetCommState(hComm, &dcbSerialParams); //retreives  the current settings
        if (Status == FALSE)
        {
            printf_s("\nError to Get the Com state\n\n");
            break;
        }
        dcbSerialParams.BaudRate = 920000;//CBR_9600;      //BaudRate = 9600
        dcbSerialParams.ByteSize = 8;             //ByteSize = 8
        dcbSerialParams.StopBits = ONESTOPBIT;    //StopBits = 1
        dcbSerialParams.Parity = NOPARITY;      //Parity = None
        Status = SetCommState(hComm, &dcbSerialParams);
        if (Status == FALSE)
        {
            printf_s("\nError to Setting DCB Structure\n\n");
            break;
        }
        //Setting Timeouts
        timeouts.ReadIntervalTimeout = 50;
        timeouts.ReadTotalTimeoutConstant = 50;
        timeouts.ReadTotalTimeoutMultiplier = 10;
        timeouts.WriteTotalTimeoutConstant = 50;
        timeouts.WriteTotalTimeoutMultiplier = 10;
        if (SetCommTimeouts(hComm, &timeouts) == FALSE)
        {
            printf_s("\nError to Setting Time outs");
            break;
        }

        //Setting Receive Mask
        Status = SetCommMask(hComm, EV_ERR| EV_RX80FULL| EV_BREAK/*EV_RXCHAR*/);
        if (Status == FALSE)
        {
            printf_s("\nError to in Setting CommMask\n\n");
            break;
        }
        //Read data and store in a buffer
        do
        {
            Status = ReadFile(hComm, &ReadData, sizeof(ReadData), &NoBytesRead, NULL);
            //Setting WaitComm() Event
            Sleep(10000); /* Ten seconds */
            Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received
            if (Status == FALSE)
            {
                printf_s("\nError! in Setting WaitCommEvent()\n\n");
                break;
            }

            SerialBuffer[loop] = ReadData;
            ++loop;
        } while (NoBytesRead > 0);
        --loop; //Get Actual length of received data
        printf_s("\nNumber of bytes received = %d\n\n", loop);
        //print receive data on console
        printf_s("\n\n");
        int index = 0;
        for (index = 0; index < loop; ++index)
        {
            printf_s("%c", SerialBuffer[index]);
        }
        printf_s("\n\n");
    } while (0);

    CloseHandle(hComm);//Closing the Serial Port
    system("pause");
    return 0;
}


4

1 回答 1

0

即使在接口芯片和设备驱动程序缓冲区已满之后,在发送数据时也会发生串行端口溢出错误。
一个狭窄的定义溢出只会发出接口芯片(8250/16550/等)检测到的信号。

因此,即使您花很长时间调用 ReadFile,是否会发生这种情况也不清楚。

请尝试以下方法。

但是,无论您做什么,如果您使用的是 USB 串行转换芯片,则可能不会出现这种情况。

在尝试上述方法的同时,请询问芯片供应商是否存在溢出错误或是否可以检测到,如果是,如何尝试。

于 2021-10-20T15:04:16.170 回答