繁体   English   中英

使用 WinAPI 获取串行通信溢出错误指示

[英]Getting Serial communication Overrun error indication using WinAPI

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

测试: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;
}


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

因此,即使您花费很长时间来调用 ReadFile,也不清楚它是否会发生。

请尝试以下操作。

但是,无论您做什么,如果您使用的是USB串行转换芯片,则可能不会发生。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM