繁体   English   中英

串行COM端口通信不起作用

[英]Serial COM port communications not working

我正在为团队正在处理的一些串行通信编写测试应用程序。 它是用Visual C ++(非托管)在VS2010上编写的。 我们正在Windows 7x64上对其进行测试。 如果我们先运行Putty(并连接),我们的代码将起作用。 如果我们不先运行Putty(并连接),那么将无法进行任何操作。

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

不带腻子

写入文件= 1读取文件= 1

腻子

写入文件= 1读取文件= 1

SetCommState例程返回1(通过): https ://msdn.microsoft.com/zh-cn/library/windows/desktop/aa363436%28v=vs.85%29.aspx只是仔细检查一下:SetCommState之后立即调用GetLastError返回0;

我们在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;
                }


            }
        }
    }

我的猜测是,您的SetCommState调用失败。 您正在向其传递填充有随机垃圾的DCB结构。 在Putty之后它起作用的原因是Putty为您配置了端口,并且您的程序开始使用该配置(因为它无法建立自己的端口)。

更改DCB comSettings; 线到

DCB comSettings = {sizeof(DCB)};

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

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

暂无
暂无

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

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