使用C使用Windows读取传入的串行数据

问题描述

我正在使用here中找到的代码来将数据从ATmega微控制器接收到我的PC。代码“ USB2SERIAL_Read_W32.c”处理Windows COM端口并接收串行数据,然后将其打印到控制台。

我试图修改代码以使其连续运行,即等待数据,在收到字符时打印它们,然后返回等待新数据。

在这里,您可以在我的干预下看到代码

    #include <Windows.h>
#include <stdio.h>

void main(void)
    {
        HANDLE hComm;                          // Handle to the Serial port
        char  ComPortName[] = "\\\\.\\COM9";  // Name of the Serial port(May Change) to be opened,BOOL  Status;                          // Status of the varIoUs operations 
        DWORD dwEventMask;                     // Event mask to trigger
        char  TempChar;                        // Temperory Character
        char  SerialBuffer[256];               // Buffer Containing Rxed Data
        DWORD NoBytesRead;                     // Bytes read by ReadFile()
        int i = 0;
        int counter=0;
        printf("\n\n +==========================================+");
        printf("\n |    Serial Port  Reception (Win32 API)    |");
        printf("\n +==========================================+\n");
        /*---------------------------------- opening the Serial Port -------------------------------------------*/
        
        hComm = CreateFile( ComPortName,// Name of the Port to be Opened
                            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("\n    Error! - Port %s can't be opened\n",ComPortName);
        else
            printf("\n    Port %s Opened\n ",ComPortName);

        /*------------------------------- Setting the Parameters for the SerialPort ------------------------------*/
        
        DCB dcbSerialParams = { 0 };                         // Initializing DCB structure
        dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

        Status = GetCommState(hComm,&dcbSerialParams);      //retreives  the current settings

        if (Status == FALSE)
            printf("\n    Error! in GetCommState()");

        dcbSerialParams.Baudrate = CBR_9600;      // Setting Baudrate = 9600
        dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
        dcbSerialParams.StopBits = OnesTOPBIT;    // Setting StopBits = 1
        dcbSerialParams.Parity = nopARITY;        // Setting Parity = None 

        Status = SetCommState(hComm,&dcbSerialParams);  //Configuring the port according to settings in DCB 

        if (Status == FALSE)
            {
                printf("\n    Error! in Setting DCB Structure");
            }
        else //If Successfull display the contents of the DCB Structure
            {
                printf("\n\n    Setting DCB Structure Successfull\n");
                printf("\n       Baudrate = %d",dcbSerialParams.Baudrate);
                printf("\n       ByteSize = %d",dcbSerialParams.ByteSize);
                printf("\n       StopBits = %d",dcbSerialParams.StopBits);
                printf("\n       Parity   = %d",dcbSerialParams.Parity);
            }

        /*------------------------------------ Setting Timeouts --------------------------------------------------*/
        
        COMMTIMEOUTS timeouts = { 0 };
        timeouts.ReadIntervalTimeout         = MAXDWORD;
        timeouts.ReadTotalTimeoutConstant    = 0;
        timeouts.ReadTotalTimeoutMultiplier  = 0;
        timeouts.WritetotalTimeoutConstant   = 0;
        timeouts.WritetotalTimeoutMultiplier = 0;
        
        if (SetCommTimeouts(hComm,&timeouts) == FALSE)
            printf("\n\n    Error! in Setting Time Outs");
        else
            printf("\n\n    Setting Serial Port Timeouts Successfull");

        /*------------------------------------ Setting Receive Mask ----------------------------------------------*/
        dwEventMask=EV_RXCHAR;
        Status = SetCommMask(hComm,dwEventMask); //Configure Windows to Monitor the serial device for Character Reception

        if (Status == FALSE)
            printf("\n\n    Error! in Setting CommMask");
        else
            printf("\n\n    Setting CommMask successfull");

        
       /*------------------------------------ Setting WaitComm() Event   ----------------------------------------*/
    while(1){
        int j =0;
        i=0;
        for(j=0;j<sizeof(SerialBuffer);j++){        //Clear SerialBuffer
            SerialBuffer[j]=0;
        }
        printf("\n\n    Waiting for Data Reception");
        Status = WaitCommEvent(hComm,&dwEventMask,NULL); //Wait for the character to be received
        
    
        /*-------------------------- Program will Wait here till a Character is received ------------------------*/             

        if (Status == FALSE){
            printf("\n    Error! in Setting WaitCommEvent()");
        }
        else //If  WaitCommEvent()==True Read the RXed data using ReadFile();
        {
            printf("\n\n    Characters Received");
            do{
                Status = ReadFile(hComm,&TempChar,sizeof(TempChar),&NoBytesRead,NULL);
                if(Status==TRUE){
                    if(NoBytesRead>0){
                        SerialBuffer[i] = TempChar;
                    }
                    i++;
                }
                else
                    printf("\n    Error! in Setting ReadFile()");
                
            }while (NoBytesRead);

            /*------------Printing the RXed String to Console----------------------*/

            printf("\n\n    ");
            
            for (j = 0; j < strlen(SerialBuffer); j++)      
                printf("%c",SerialBuffer[j]);
        }   
        //CloseHandle(hComm);//Closing the Serial Port
        printf("\n +==========================================+\n");
    }
}//End of Main()

我所做的更改是添加while(1)循环,在每个循环的开始处清除缓冲区,注释掉端口处理程序的关闭,更改超时,如{{ 3}},并进行一些其他小的调整和修饰。

问题是由于某种原因,每当我收到字符串“ 1234”时,首先触发预期事件,打印接收到的字符,然后由于某种原因触发另一个事件,没有字符等待,如下图所示:

enter image description here

总而言之,为什么会触发意外事件,我该如何解决

编辑:我还没有找到解决方案,但是我发布了一个发现的解决方法(也许它可以帮助某人发现最初的问题)。如果我将Comm Mask设置为零,并在每次循环迭代中将其重置为EV_RXCHAR,它似乎可以正常工作;也就是说,当我第二次到达WaitCommEvent行时,它不会像以前那样自动触发。不好的是,我无法解释为什么它现在可以工作,而且我认为它也应该首先正确地工作。因此,任何帮助将不胜感激。这是具有变通方法代码,该代码将CommMask设置为零并返回到EV_RXCHAR:

#include <Windows.h>
#include <stdio.h>

void main(void){

    printf("Hello!\n");

    DWORD dwCommEvent;
    DWORD dwRead;
    DWORD lpEvtMask;
    char  chRead;
    char  ComPortName[] = "\\\\.\\COM9";  // Name of the Serial port(May Change) to be opened,int i=0;

    HANDLE hComm;
    hComm = CreateFile( ComPortName,GENERIC_READ | GENERIC_WRITE,OPEN_EXISTING,0);
    if (hComm == INVALID_HANDLE_VALUE)
       printf("Error opening port.\n");
   
    //////////////////////////////////////////////////////   
    DCB dcb;

    FillMemory(&dcb,sizeof(dcb),0);
    if (!GetCommState(hComm,&dcb))     // get current DCB
       printf("Error GetCommState.\n");

    // Update DCB rate.
    dcb.Baudrate = CBR_9600 ;
    dcb.ByteSize = 8;             // Setting ByteSize = 8
    dcb.StopBits = OnesTOPBIT;    // Setting StopBits = 1
    dcb.Parity = nopARITY;        // Setting Parity = None 
    dcb.DCBlength = sizeof(dcb);
     // Set new state.
    if (!SetCommState(hComm,&dcb))
        printf("Error SetCommState.\n");
        // Error in SetCommState. Possibly a problem with the communications 
         // port handle or a problem with the DCB structure itself.


    /////////////////////////////////////////////////////////////////////
    COMMTIMEOUTS timeouts;

    timeouts.ReadIntervalTimeout = MAXDWORD; 
    timeouts.ReadTotalTimeoutMultiplier = 0;
    timeouts.ReadTotalTimeoutConstant = 0;
    timeouts.WritetotalTimeoutMultiplier = 0;
    timeouts.WritetotalTimeoutConstant = 0;

    if (!SetCommTimeouts(hComm,&timeouts))
       printf("Error timeouts.\n");

    if(!PurgeComm(hComm,PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT))
        printf("Error PurgeComm.\n");
    ////////////////////////////////////////
    for ( ; ; ) {
        if (!SetCommMask(hComm,0))
            printf("Error CommMask.\n");
    
        if (!SetCommMask(hComm,EV_RXCHAR))
            printf("Error CommMask.\n");
        
        printf("Waiting for characters.. \n\n");
    
       if (WaitCommEvent(hComm,&dwCommEvent,NULL)) {
           do {
                if (ReadFile(hComm,&chRead,1,&dwRead,NULL)){
                    if(dwRead!=0)
                        printf("Character Received: %c\n",chRead);
                }
                else{
                    printf("ErrorReadFile.\n");
                    break;
                }
            }while (dwRead);
       }
       else{
            printf("Error WaitCommEvent.\n");
             break;
        }
        printf("=========================\n");
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)