简体   繁体   English

串行COM端口通信不起作用

[英]Serial COM port communications not working

I'm writing a test app for some serial communications that my team is working on. 我正在为团队正在处理的一些串行通信编写测试应用程序。 Its written in Visual C++ (unmanaged) on VS2010. 它是用Visual C ++(非托管)在VS2010上编写的。 We're testing it on Windows 7x64. 我们正在Windows 7x64上对其进行测试。 If we run Putty first (and connect), our code works. 如果我们先运行Putty(并连接),我们的代码将起作用。 If we don't run Putty first (and connect), nothing works. 如果我们不先运行Putty(并连接),那么将无法进行任何操作。

The return codes from Read/Write file are as follows: 读/写文件的返回码如下:

w/o putty 不带腻子

write file = 1 read file = 1 写入文件= 1读取文件= 1

w/ putty 腻子

write file = 1 read file = 1 写入文件= 1读取文件= 1

The SetCommState routine returns 1 (a pass): https://msdn.microsoft.com/en-us/library/windows/desktop/aa363436%28v=vs.85%29.aspx Just double checking: Calling GetLastError immediately after SetCommState returns 0; SetCommState例程返回1(通过): https ://msdn.microsoft.com/zh-cn/library/windows/desktop/aa363436%28v=vs.85%29.aspx只是仔细检查一下:SetCommState之后立即调用GetLastError返回0;

We're running on COM7, but COM4 is selected in the GUI (dirty hack). 我们在COM7上运行,但是在GUI中选择了COM4(脏污)。 What happens is that the readfile routine doesn't return back a string (via pointer). 发生的情况是readfile例程不返回字符串(通过指针)。 This indicates that writefile isn't working properly, but I'm not 100% sure about this. 这表明writefile不能正常工作,但是我对此不是100%肯定。

Does anyone out there know why this might happen? 有谁知道为什么会这样吗?

Here is the code: 这是代码:

Note: I tried to show everything, but the code formatter screwed up. 注意:我试图显示所有内容,但是代码格式化程序搞砸了。 Everything that is important is here. 重要的一切都在这里。

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;
                }


            }
        }
    }

My educated guess would be, your SetCommState call fails. 我的猜测是,您的SetCommState调用失败。 You are passing it a DCB structure filled with random garbage. 您正在向其传递填充有随机垃圾的DCB结构。 The reason it works after Putty is that Putty configures the port for you, and your program gets to use that configuration (since it fails to establish its own). 在Putty之后它起作用的原因是Putty为您配置了端口,并且您的程序开始使用该配置(因为它无法建立自己的端口)。

Change DCB comSettings; 更改DCB comSettings; line to 线到

DCB comSettings = {sizeof(DCB)};

This initializes DCBlength member correctly, and sets all other members to 0. Then set up other members as necessary for your device. 这将正确初始化DCBlength成员,并将所有其他成员设置为0。然后根据需要为设备设置其他成员。

And check the return value of SetCommState for errors (as well as that of all other API calls). 并检查SetCommState的返回值SetCommState有错误(以及所有其他API调用的返回值)。

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

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