串行COM端口通信无法正常工作

时间:2016-01-18 15:33:57

标签: c++ visual-c++ mfc serial-port

我正在编写一个测试应用程序,用于我的团队正在进行的一些串行通信。它在VS2010上用Visual C ++(非托管)编写。我们正在Windows 7x64上进行测试。如果我们先运行Putty(并连接),我们的代码就可以了。如果我们不先运行Putty(并连接),那么一切都无效。

读/写文件的返回码如下:

没有腻子

写文件= 1 读取文件= 1

w / putty

写文件= 1 读取文件= 1

SetCommState例程返回1(传递):https://msdn.microsoft.com/en-us/library/windows/desktop/aa363436%28v=vs.85%29.aspx 只需仔细检查:在SetCommState返回0之后立即调用GetLastError;

我们在COM7上运行,但在GUI中选择了COM4(脏黑客)。会发生什么是readfile例程不返回字符串(通过指针)。这表明writefile无法正常工作,但我对此并不是100%肯定。

有没有人知道为什么会这样?

以下是代码:

注意:我试图显示所有内容,但代码格式化程序搞砸了。所有重要的事情都在这里。

OutputDebugStringW(L"Previous COM port = " + portString + "\n");
        comPort = 4;
        com4 = true;
        OutputDebugStringW(L"SETCOM - COM4\n");
        hComm = CreateFile(L"COM7", GENERIC_READ | GENERIC_WRITE,
            0,
            0,
            OPEN_EXISTING,
            0,
            NULL);
        if (hComm == INVALID_HANDLE_VALUE)
            OutputDebugStringW(L"Error!");
        else
            OutputDebugStringW(L"Success!");
        DCB comSettings;
        SecureZeroMemory(&comSettings, sizeof(DCB));
        comSettings.BaudRate = 9600;
        comSettings.ByteSize = 8;
        comSettings.Parity = NOPARITY;
        comSettings.StopBits = ONESTOPBIT;
        comSettings.fAbortOnError = TRUE;
        b = SetCommState(hComm, &comSettings);
        commSetupResult = GetLastError();
        /*OutputDebugStringW(L"SetCommState = " + (int)SetCommState(hComm, &comSettings));*/
        //s.Format("%d",4);//SetCommState(hComm, &comSettings));

            // instance an object of COMMTIMEOUTS.
            COMMTIMEOUTS comTimeOut;
            // Specify time-out between charactor for receiving.
            comTimeOut.ReadIntervalTimeout = 3;
            // Specify value that is multiplied 
            // by the requested number of bytes to be read. 
            comTimeOut.ReadTotalTimeoutMultiplier = 3;
            // Specify value is added to the product of the 
            // ReadTotalTimeoutMultiplier member
            comTimeOut.ReadTotalTimeoutConstant = 2;
            // Specify value that is multiplied 
            // by the requested number of bytes to be sent. 
            comTimeOut.WriteTotalTimeoutMultiplier = 3;
            // Specify value is added to the product of the 
            // WriteTotalTimeoutMultiplier member
            comTimeOut.WriteTotalTimeoutConstant = 2;
            // set the time-out parameter into device control.
            SetCommTimeouts(hComm, &comTimeOut);
            break;
        case ID_SETCOM_COM5:
            OutputDebugStringW(L"Previous COM port = " + portString + "\n");
            comPort = 5;
            OutputDebugStringW(L"SETCOM - COM5\n");
            hComm = CreateFile(L"COM5", GENERIC_READ | GENERIC_WRITE,
                0,
                0,
                OPEN_EXISTING,
                FILE_FLAG_OVERLAPPED,
                0);
            if (hComm == INVALID_HANDLE_VALUE)
                OutputDebugStringW(L"Error!");
            else
                OutputDebugStringW(L"Success!");
            break;
        case ID_SETCOM_COM6:
            OutputDebugStringW(L"Previous COM port = " + portString + "\n");
            comPort = 6;
            OutputDebugStringW(L"SETCOM - COM6\n");
            hComm = CreateFile(L"COM6", GENERIC_READ | GENERIC_WRITE,
                0,
                0,
                OPEN_EXISTING,
                FILE_FLAG_OVERLAPPED,
                0);
            if (hComm == INVALID_HANDLE_VALUE)
                OutputDebugStringW(L"Error!");
            else
                OutputDebugStringW(L"Success!");
            break;
        case ID_SETCOM_COM7:
            OutputDebugStringW(L"Previous COM port = " + portString + "\n");
            comPort = 7;
            OutputDebugStringW(L"SETCOM - COM7\n");
            hComm = CreateFile(L"COM7", GENERIC_READ | GENERIC_WRITE,
                0,
                0,
                OPEN_EXISTING,
                FILE_FLAG_OVERLAPPED,
                0);
            if (hComm == INVALID_HANDLE_VALUE)
                OutputDebugStringW(L"Error!");
            else
                OutputDebugStringW(L"Success!");
            break;
        case ID_SETCOM_COM8:
            OutputDebugStringW(L"Previous COM port = " + portString + "\n");
            comPort = 8;
            OutputDebugStringW(L"SETCOM - COM8\n");
            hComm = CreateFile(L"COM8", GENERIC_READ | GENERIC_WRITE,
                0,
                0,
                OPEN_EXISTING,
                FILE_FLAG_OVERLAPPED,
                0);
            if (hComm == INVALID_HANDLE_VALUE)
                OutputDebugStringW(L"Error!");
            else
                OutputDebugStringW(L"Success!");
            break;
        case ID_SETCOM_COM9:
            OutputDebugStringW(L"Previous COM port = " + portString + "\n");
            comPort = 9;
            OutputDebugStringW(L"SETCOM - COM9\n");
            hComm = CreateFile(L"COM9", GENERIC_READ | GENERIC_WRITE,
                0,
                0,
                OPEN_EXISTING,
                FILE_FLAG_OVERLAPPED,
                0);
            if (hComm == INVALID_HANDLE_VALUE)
                OutputDebugStringW(L"Error!");
            else
                OutputDebugStringW(L"Success!");
            break;
        case ID_SETCOM_COM10:
            OutputDebugStringW(L"Previous COM port = " + portString + "\n");
            comPort = 10;
            OutputDebugStringW(L"SETCOM - COM10\n");
            hComm = CreateFile(L"COM9", GENERIC_READ | GENERIC_WRITE,
                0,
                0,
                OPEN_EXISTING,
                FILE_FLAG_OVERLAPPED,
                0);
            if (hComm == INVALID_HANDLE_VALUE)
                OutputDebugStringW(L"Error!");
            else
                OutputDebugStringW(L"Success!");
            break;
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }

    DWORD dwRead;
    BOOL fWaitingOnRead = FALSE;
    OVERLAPPED osReader = { 0 };

    // Create the overlapped event. Must be closed before exiting
    // to avoid a handle leak.
    osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    if (osReader.hEvent == NULL) {}
    // Error creating overlapped event; abort.
    char lpBuf[32];
    if (com4) {
        if (!fWaitingOnRead) 
        {
            // Issue read operation.
            OVERLAPPED osWrite = { 0 };
            DWORD dwWritten;
            BOOL result = GetLastError();
            result = WriteFile(hComm, "EO1\nJAX0\nDI\n", 12, &dwWritten, NULL);
            CStringA WFError;
            WFError.Format("\nSent %d result %d lasterror %d \n", dwWritten, result, GetLastError());
            OutputDebugStringA(WFError);
            Sleep(100);//min was 61, 100 to be safe
            bool Wait = true;
            DWORD start = GetTickCount() + 15000;

            while (Wait && start > GetTickCount())
            {
                Sleep(200);
                //              GetLastError();
                result = ReadFile(hComm, lpBuf, 32, &dwRead, NULL);
                WFError.Format("Read %d, result %d, lasterror %d \n", dwRead, result, GetLastError());
                OutputDebugStringA(WFError);
                //          WFError = "Read file error = " + WFError;
                if (result != 0)
                {
                    CString temp = lpBuf;
                    temp = temp.Left(dwRead);
                    if (temp.GetLength() > 0)
                    {
                        OutputDebugString(temp + "\n");
                        MessageBox(NULL, temp, L"Title", MB_OK);
//                      memset(&lpBuf[0], 0, sizeof(lpBuf));
                    }
                    //strcpy(lpBuf,"");
//                  goto start;
                }


            }
        }
    }

1 个答案:

答案 0 :(得分:2)

我的有根据的猜测是,你的SetCommState电话失败了。你正在传递一个充满随机垃圾的DCB结构。它在Putty之后工作的原因是Putty为你配置端口,你的程序可以使用该配置(因为它无法建立自己的配置)。

DCB comSettings;行更改为

DCB comSettings = {sizeof(DCB)};

这会正确初始化DCBlength成员,并将所有其他成员设置为0.然后根据您的设备的需要设置其他成员。

并检查SetCommState的错误返回值(以及所有其他API调用的返回值)。