簡體   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